Version Description
Download this release
Release Info
Developer | bordoni |
Plugin | Event Tickets |
Version | 5.1.9 |
Comparing to | |
See all releases |
Code changes from version 5.1.8 to 5.1.9
- common/lang/tribe-common.pot +25 -25
- common/src/Tribe/Main.php +9 -7
- common/src/Tribe/Service_Providers/Dialog.php +1 -1
- common/src/resources/css/common-full.min.css +1 -1
- common/src/resources/css/common-skeleton.min.css +1 -1
- common/src/resources/css/customizer-controls.min.css +1 -1
- common/src/resources/css/dialog.min.css +1 -1
- common/src/resources/css/tribe-common-admin.min.css +1 -1
- common/src/resources/css/variables-full.min.css +1 -0
- common/src/resources/css/variables-skeleton.min.css +1 -0
- common/vendor/autoload.php +1 -1
- common/vendor/autoload_52.php +1 -1
- common/vendor/composer/autoload_real.php +4 -4
- common/vendor/composer/autoload_real_52.php +3 -3
- common/vendor/composer/autoload_static.php +5 -5
- event-tickets.php +1 -1
- lang/event-tickets-cs_CZ.mo +0 -0
- lang/event-tickets-es_ES.mo +0 -0
- lang/event-tickets-fi.mo +0 -0
- lang/event-tickets-fr_CA.mo +0 -0
- lang/event-tickets-ja.mo +0 -0
- lang/event-tickets-nl_NL.mo +0 -0
- lang/event-tickets.pot +581 -485
- readme.txt +9 -2
- src/Tickets/Commerce.php +30 -0
- src/Tickets/Commerce/Assets.php +39 -2
- src/Tickets/Commerce/Attendee.php +471 -0
- src/Tickets/Commerce/Cart.php +660 -0
- src/Tickets/Commerce/Cart/Cart_Interface.php +120 -0
- src/Tickets/Commerce/Cart/Unmanaged_Cart.php +176 -0
- src/Tickets/Commerce/Checkout.php +162 -0
- src/Tickets/Commerce/Communication/Email.php +69 -0
- src/Tickets/Commerce/Currency.php +14 -0
- src/Tickets/Commerce/Editor/Metabox.php +157 -0
- src/Tickets/Commerce/Flag_Actions/Decrease_Stock.php +36 -0
- src/Tickets/Commerce/Flag_Actions/Flag_Action_Abstract.php +122 -0
- src/Tickets/Commerce/Flag_Actions/Flag_Action_Handler.php +77 -0
- src/Tickets/Commerce/Flag_Actions/Flag_Action_Interface.php +104 -0
- src/Tickets/Commerce/Flag_Actions/Generate_Attendees.php +36 -0
- src/Tickets/Commerce/Flag_Actions/Increase_Stock.php +36 -0
- src/Tickets/Commerce/Gateways/Abstract_Gateway.php +9 -6
- src/Tickets/Commerce/Gateways/Interface_Gateway.php +11 -2
- src/Tickets/Commerce/Gateways/Legacy/Gateway.php +0 -106
- src/Tickets/Commerce/Gateways/Legacy/Provider.php +0 -97
- src/Tickets/Commerce/Gateways/Legacy/Settings.php +0 -201
- src/Tickets/Commerce/Gateways/Manager.php +46 -3
- src/Tickets/Commerce/Gateways/PayPal/AjaxRequestHandler.php +0 -316
- src/Tickets/Commerce/Gateways/PayPal/Ajax_Request_Handler.php +44 -0
- src/Tickets/Commerce/Gateways/PayPal/Assets.php +34 -6
- src/Tickets/Commerce/Gateways/PayPal/Buttons.php +61 -0
- src/Tickets/Commerce/Gateways/PayPal/Client.php +498 -0
- src/Tickets/Commerce/Gateways/PayPal/Connect_Client.php +0 -35
- src/Tickets/Commerce/Gateways/PayPal/Gateway.php +14 -19
- src/Tickets/Commerce/Gateways/PayPal/Hooks.php +105 -29
- src/Tickets/Commerce/Gateways/PayPal/Merchant.php +833 -0
- src/Tickets/Commerce/Gateways/PayPal/{SDK/Models/PayPalOrder.php → Models/PayPal_Order.php} +19 -21
- src/Tickets/Commerce/Gateways/PayPal/{SDK/Models/PayPalPayment.php → Models/PayPal_Payment.php} +14 -13
- src/Tickets/Commerce/Gateways/PayPal/Models/Webhook_Config.php +77 -0
- src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php +215 -0
- src/Tickets/Commerce/Gateways/PayPal/Provider.php +27 -31
- src/Tickets/Commerce/Gateways/PayPal/REST.php +8 -40
- src/Tickets/Commerce/Gateways/PayPal/REST/On_Boarding_Endpoint.php +433 -0
- src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php +278 -0
- src/{Tribe/REST/V1/Endpoints/Commerce/PayPal_Webhook.php → Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php} +34 -7
- src/Tickets/Commerce/Gateways/PayPal/Refresh_Token.php +101 -0
- src/Tickets/Commerce/Gateways/PayPal/Repositories/Authorization.php +88 -0
- src/Tickets/Commerce/Gateways/PayPal/Repositories/Order.php +83 -0
- src/Tickets/Commerce/Gateways/PayPal/{SDK/Repositories → Repositories}/Webhooks.php +89 -94
- src/Tickets/Commerce/Gateways/PayPal/SDK/Models/MerchantDetail.php +0 -216
- src/Tickets/Commerce/Gateways/PayPal/SDK/Models/WebhookConfig.php +0 -70
- src/Tickets/Commerce/Gateways/PayPal/SDK/PayPalClient.php +0 -92
- src/Tickets/Commerce/Gateways/PayPal/SDK/RefreshToken.php +0 -113
- src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/MerchantDetails.php +0 -213
- src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/PayPalAuth.php +0 -246
- src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/PayPalOrder.php +0 -175
- src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/Traits/HasMode.php +0 -36
- src/Tickets/Commerce/Gateways/PayPal/Settings.php +1 -237
- src/Tickets/Commerce/Gateways/PayPal/Signup.php +235 -0
- src/Tickets/Commerce/Gateways/PayPal/Status.php +128 -0
- src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php +221 -0
- src/Tickets/Commerce/Gateways/PayPal/{SDK/DataTransferObjects/PayPalWebhookHeaders.php → Webhooks/Headers.php} +28 -27
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{EventListener.php → Event_Listener.php} +2 -2
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentCaptureCompleted.php → Payment_Capture_Completed.php} +1 -1
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentCaptureDenied.php → Payment_Capture_Denied.php} +1 -1
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentCaptureRefunded.php → Payment_Capture_Refunded.php} +1 -1
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentCaptureReversed.php → Payment_Capture_Reversed.php} +1 -1
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentEventListener.php → Payment_Event_Listener.php} +36 -38
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/WebhookChecker.php +0 -104
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/Webhook_Checker.php +104 -0
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/{WebhookRegister.php → Webhook_Register.php} +27 -27
- src/Tickets/Commerce/Gateways/PayPal/Webhooks/{WebhooksRoute.php → Webhooks_Route.php} +38 -41
- src/Tickets/Commerce/Gateways/PayPal/WhoDat.php +200 -0
- src/Tickets/Commerce/Gateways/PayPal/onBoardingRedirectHandler.php +0 -487
- src/Tickets/Commerce/Hooks.php +315 -8
- src/Tickets/Commerce/Models/Attendee_Model.php +114 -0
- src/Tickets/Commerce/Models/Order_Model.php +103 -0
- src/Tickets/Commerce/Models/Ticket_Model.php +59 -0
- src/Tickets/Commerce/Module.php +615 -0
- src/Tickets/Commerce/Order.php +642 -0
- src/Tickets/Commerce/Provider.php +40 -4
- src/Tickets/Commerce/Reports/Attendance_Totals.php +237 -0
- src/Tickets/Commerce/Reports/Event.php +55 -0
- src/Tickets/Commerce/Reports/Ticket.php +40 -0
- src/Tickets/Commerce/Repositories/Attendees_Repository.php +134 -0
- src/Tickets/Commerce/Repositories/Order_Repository.php +486 -0
- src/Tickets/Commerce/Repositories/Tickets_Repository.php +124 -0
- src/Tickets/Commerce/Settings.php +108 -109
- src/Tickets/Commerce/Shortcodes/Checkout_Shortcode.php +84 -0
- src/Tickets/Commerce/Shortcodes/Shortcode_Abstract.php +151 -0
- src/Tickets/Commerce/Shortcodes/Success_Shortcode.php +75 -0
- src/Tickets/Commerce/Status/Action_Required.php +54 -0
- src/Tickets/Commerce/Status/Approved.php +54 -0
- src/Tickets/Commerce/Status/Completed.php +54 -0
- src/Tickets/Commerce/Status/Created.php +50 -0
- src/Tickets/Commerce/Status/Denied.php +49 -0
- src/Tickets/Commerce/Status/Not_Completed.php +50 -0
- src/Tickets/Commerce/Status/Pending.php +155 -0
- src/Tickets/Commerce/Status/Refunded.php +47 -0
- src/Tickets/Commerce/Status/Reversed.php +47 -0
- src/Tickets/Commerce/Status/Status_Abstract.php +184 -0
- src/Tickets/Commerce/Status/Status_Handler.php +347 -0
- src/Tickets/Commerce/Status/Status_Interface.php +103 -0
- src/Tickets/Commerce/Status/Undefined.php +49 -0
- src/Tickets/Commerce/Status/Voided.php +50 -0
- src/Tickets/Commerce/Success.php +125 -0
- src/Tickets/Commerce/Ticket.php +768 -0
- src/Tickets/Commerce/Tickets_View.php +157 -0
- src/Tickets/Commerce/Traits/Has_Mode.php +75 -0
- src/Tickets/Commerce/Utils/Price.php +69 -0
- src/Tickets/Event.php +39 -0
- src/Tickets/Hooks.php +5 -0
- src/Tribe/Admin/Ticket_Settings.php +3 -1
- src/Tribe/Assets.php +10 -5
- src/Tribe/Attendee_Repository.php +49 -31
- src/Tribe/Commerce/PayPal/Main.php +1 -1
- src/Tribe/Editor/Configuration.php +3 -0
- src/Tribe/Editor/Provider.php +15 -4
- src/Tribe/Event_Repository.php +6 -4
- src/Tribe/Main.php +12 -4
- src/Tribe/REST/V1/Endpoints/Base.php +1 -1
- src/Tribe/Repositories/Order.php +1 -1
- src/Tribe/Shortcodes/Tribe_Tickets_Checkout.php +19 -6
- src/Tribe/Status/Manager.php +5 -4
- src/Tribe/Tickets.php +2 -2
- src/Tribe/Tickets_View.php +0 -14
- src/admin-views/commerce/gateways/paypal/signup-link.php +27 -0
- src/admin-views/commerce/metabox/capacity.php +27 -0
- src/admin-views/commerce/metabox/sku.php +42 -0
- src/admin-views/editor/fieldset/settings-provider.php +3 -3
- src/admin-views/payments/tickets-commerce.php +88 -0
- src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php +47 -28
- src/functions/commerce/attendees.php +128 -0
- src/functions/commerce/orders.php +128 -0
- src/functions/commerce/orm.php +98 -0
- src/functions/commerce/tickets.php +128 -0
- src/modules/blocks/rsvp/move-delete/style.pcss +1 -1
- src/modules/blocks/ticket/container-content/advanced-options/move-delete/style.pcss +1 -1
- src/resources/css/app/rsvp/frontend.css +1 -1
- src/resources/css/app/rsvp/frontend.min.css +1 -1
- src/resources/css/attendees.css +1 -1
- src/resources/css/common-responsive.css +359 -9
- src/resources/css/common-responsive.min.css +1 -1
- src/resources/css/details.css +2 -2
- src/resources/css/details.min.css +1 -1
- src/resources/css/freemius.css +4 -4
- src/resources/css/rsvp-v1.css +77 -82
- src/resources/css/rsvp-v1.min.css +1 -1
common/lang/tribe-common.pot
CHANGED
@@ -2,13 +2,13 @@
|
|
2 |
# This file is distributed under the same license as the Tribe Common package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: Tribe Common 4.14.
|
6 |
"Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
|
7 |
-
"POT-Creation-Date: 2021-08-
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
-
"PO-Revision-Date: 2021-08-
|
12 |
"Last-Translator: \n"
|
13 |
"Language-Team: \n"
|
14 |
|
@@ -41,7 +41,7 @@ msgstr ""
|
|
41 |
msgid "Press \"Cmd + C\" to copy"
|
42 |
msgstr ""
|
43 |
|
44 |
-
#. #-#-#-#-# tribe-common.pot (Tribe Common 4.14.
|
45 |
#. Author of the plugin/theme
|
46 |
#: src/Tribe/Admin/Help_Page.php:79 src/Tribe/Customizer.php:664
|
47 |
#: src/Tribe/Plugins_API.php:25 src/admin-views/help-calendar.php:97
|
@@ -2198,87 +2198,87 @@ msgstr ""
|
|
2198 |
msgid "Full debug (all events)"
|
2199 |
msgstr ""
|
2200 |
|
2201 |
-
#: src/Tribe/Main.php:
|
2202 |
msgid ": activate to sort column ascending"
|
2203 |
msgstr ""
|
2204 |
|
2205 |
-
#: src/Tribe/Main.php:
|
2206 |
msgid ": activate to sort column descending"
|
2207 |
msgstr ""
|
2208 |
|
2209 |
-
#: src/Tribe/Main.php:
|
2210 |
msgid "Show _MENU_ entries"
|
2211 |
msgstr ""
|
2212 |
|
2213 |
-
#: src/Tribe/Main.php:
|
2214 |
msgid "No data available in table"
|
2215 |
msgstr ""
|
2216 |
|
2217 |
-
#: src/Tribe/Main.php:
|
2218 |
msgid "Showing _START_ to _END_ of _TOTAL_ entries"
|
2219 |
msgstr ""
|
2220 |
|
2221 |
-
#: src/Tribe/Main.php:
|
2222 |
msgid "Showing 0 to 0 of 0 entries"
|
2223 |
msgstr ""
|
2224 |
|
2225 |
-
#: src/Tribe/Main.php:
|
2226 |
msgid "(filtered from _MAX_ total entries)"
|
2227 |
msgstr ""
|
2228 |
|
2229 |
-
#: src/Tribe/Main.php:
|
2230 |
msgid "No matching records found"
|
2231 |
msgstr ""
|
2232 |
|
2233 |
-
#: src/Tribe/Main.php:
|
2234 |
msgid "Search:"
|
2235 |
msgstr ""
|
2236 |
|
2237 |
-
#: src/Tribe/Main.php:
|
2238 |
msgid "All items on this page were selected. "
|
2239 |
msgstr ""
|
2240 |
|
2241 |
-
#: src/Tribe/Main.php:
|
2242 |
msgid "Select all pages"
|
2243 |
msgstr ""
|
2244 |
|
2245 |
-
#: src/Tribe/Main.php:
|
2246 |
msgid "Clear Selection."
|
2247 |
msgstr ""
|
2248 |
|
2249 |
-
#: src/Tribe/Main.php:
|
2250 |
msgid "All"
|
2251 |
msgstr ""
|
2252 |
|
2253 |
-
#: src/Tribe/Main.php:
|
2254 |
msgid "Next"
|
2255 |
msgstr ""
|
2256 |
|
2257 |
-
#: src/Tribe/Main.php:
|
2258 |
msgid "Previous"
|
2259 |
msgstr ""
|
2260 |
|
2261 |
-
#: src/Tribe/Main.php:
|
2262 |
msgid ": Selected %d rows"
|
2263 |
msgstr ""
|
2264 |
|
2265 |
-
#: src/Tribe/Main.php:
|
2266 |
msgid ": Selected 1 row"
|
2267 |
msgstr ""
|
2268 |
|
2269 |
-
#: src/Tribe/Main.php:
|
2270 |
msgid "Prev"
|
2271 |
msgstr ""
|
2272 |
|
2273 |
-
#: src/Tribe/Main.php:
|
2274 |
msgid "Today"
|
2275 |
msgstr ""
|
2276 |
|
2277 |
-
#: src/Tribe/Main.php:
|
2278 |
msgid "Done"
|
2279 |
msgstr ""
|
2280 |
|
2281 |
-
#: src/Tribe/Main.php:
|
2282 |
msgid "Clear"
|
2283 |
msgstr ""
|
2284 |
|
2 |
# This file is distributed under the same license as the Tribe Common package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: Tribe Common 4.14.4\n"
|
6 |
"Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
|
7 |
+
"POT-Creation-Date: 2021-08-31 16:17:54+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2021-08-31 16:17\n"
|
12 |
"Last-Translator: \n"
|
13 |
"Language-Team: \n"
|
14 |
|
41 |
msgid "Press \"Cmd + C\" to copy"
|
42 |
msgstr ""
|
43 |
|
44 |
+
#. #-#-#-#-# tribe-common.pot (Tribe Common 4.14.4) #-#-#-#-#
|
45 |
#. Author of the plugin/theme
|
46 |
#: src/Tribe/Admin/Help_Page.php:79 src/Tribe/Customizer.php:664
|
47 |
#: src/Tribe/Plugins_API.php:25 src/admin-views/help-calendar.php:97
|
2198 |
msgid "Full debug (all events)"
|
2199 |
msgstr ""
|
2200 |
|
2201 |
+
#: src/Tribe/Main.php:322
|
2202 |
msgid ": activate to sort column ascending"
|
2203 |
msgstr ""
|
2204 |
|
2205 |
+
#: src/Tribe/Main.php:323
|
2206 |
msgid ": activate to sort column descending"
|
2207 |
msgstr ""
|
2208 |
|
2209 |
+
#: src/Tribe/Main.php:325
|
2210 |
msgid "Show _MENU_ entries"
|
2211 |
msgstr ""
|
2212 |
|
2213 |
+
#: src/Tribe/Main.php:326
|
2214 |
msgid "No data available in table"
|
2215 |
msgstr ""
|
2216 |
|
2217 |
+
#: src/Tribe/Main.php:327
|
2218 |
msgid "Showing _START_ to _END_ of _TOTAL_ entries"
|
2219 |
msgstr ""
|
2220 |
|
2221 |
+
#: src/Tribe/Main.php:328
|
2222 |
msgid "Showing 0 to 0 of 0 entries"
|
2223 |
msgstr ""
|
2224 |
|
2225 |
+
#: src/Tribe/Main.php:329
|
2226 |
msgid "(filtered from _MAX_ total entries)"
|
2227 |
msgstr ""
|
2228 |
|
2229 |
+
#: src/Tribe/Main.php:330
|
2230 |
msgid "No matching records found"
|
2231 |
msgstr ""
|
2232 |
|
2233 |
+
#: src/Tribe/Main.php:331
|
2234 |
msgid "Search:"
|
2235 |
msgstr ""
|
2236 |
|
2237 |
+
#: src/Tribe/Main.php:332
|
2238 |
msgid "All items on this page were selected. "
|
2239 |
msgstr ""
|
2240 |
|
2241 |
+
#: src/Tribe/Main.php:333
|
2242 |
msgid "Select all pages"
|
2243 |
msgstr ""
|
2244 |
|
2245 |
+
#: src/Tribe/Main.php:334
|
2246 |
msgid "Clear Selection."
|
2247 |
msgstr ""
|
2248 |
|
2249 |
+
#: src/Tribe/Main.php:336
|
2250 |
msgid "All"
|
2251 |
msgstr ""
|
2252 |
|
2253 |
+
#: src/Tribe/Main.php:337 src/Tribe/Main.php:354
|
2254 |
msgid "Next"
|
2255 |
msgstr ""
|
2256 |
|
2257 |
+
#: src/Tribe/Main.php:338
|
2258 |
msgid "Previous"
|
2259 |
msgstr ""
|
2260 |
|
2261 |
+
#: src/Tribe/Main.php:343
|
2262 |
msgid ": Selected %d rows"
|
2263 |
msgstr ""
|
2264 |
|
2265 |
+
#: src/Tribe/Main.php:344
|
2266 |
msgid ": Selected 1 row"
|
2267 |
msgstr ""
|
2268 |
|
2269 |
+
#: src/Tribe/Main.php:355
|
2270 |
msgid "Prev"
|
2271 |
msgstr ""
|
2272 |
|
2273 |
+
#: src/Tribe/Main.php:356 src/Tribe/Main.php:358
|
2274 |
msgid "Today"
|
2275 |
msgstr ""
|
2276 |
|
2277 |
+
#: src/Tribe/Main.php:357
|
2278 |
msgid "Done"
|
2279 |
msgstr ""
|
2280 |
|
2281 |
+
#: src/Tribe/Main.php:359
|
2282 |
msgid "Clear"
|
2283 |
msgstr ""
|
2284 |
|
common/src/Tribe/Main.php
CHANGED
@@ -20,7 +20,7 @@ class Tribe__Main {
|
|
20 |
const OPTIONNAME = 'tribe_events_calendar_options';
|
21 |
const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
|
22 |
|
23 |
-
const VERSION = '4.14.
|
24 |
|
25 |
const FEED_URL = 'https://theeventscalendar.com/feed/';
|
26 |
|
@@ -212,8 +212,10 @@ class Tribe__Main {
|
|
212 |
tribe_assets(
|
213 |
$this,
|
214 |
[
|
215 |
-
[ '
|
216 |
-
[ 'tribe-common-
|
|
|
|
|
217 |
],
|
218 |
null
|
219 |
);
|
@@ -222,11 +224,11 @@ class Tribe__Main {
|
|
222 |
tribe_assets(
|
223 |
$this,
|
224 |
[
|
225 |
-
[ 'tribe-ui', 'tribe-ui.css' ],
|
226 |
[ 'tribe-buttonset', 'buttonset.js', [ 'jquery', 'underscore' ] ],
|
227 |
-
[ 'tribe-common-admin', 'tribe-common-admin.css', [ 'tribe-dependency-style', 'tribe-bumpdown-css', 'tribe-buttonset-style', 'tribe-select2-css' ] ],
|
228 |
[ 'tribe-validation', 'validation.js', [ 'jquery', 'underscore', 'tribe-common', 'tribe-utils-camelcase', 'tribe-tooltipster' ] ],
|
229 |
-
[ 'tribe-validation-style', 'validation.css', [ 'tribe-tooltipster-css' ] ],
|
230 |
[ 'tribe-dependency', 'dependency.js', [ 'jquery', 'underscore', 'tribe-common' ] ],
|
231 |
[ 'tribe-dependency-style', 'dependency.css', [ 'tribe-select2-css' ] ],
|
232 |
[ 'tribe-pue-notices', 'pue-notices.js', [ 'jquery' ] ],
|
@@ -267,7 +269,7 @@ class Tribe__Main {
|
|
267 |
$this,
|
268 |
'tribe-customizer-controls',
|
269 |
'customizer-controls.css',
|
270 |
-
[],
|
271 |
'customize_controls_print_styles'
|
272 |
);
|
273 |
|
20 |
const OPTIONNAME = 'tribe_events_calendar_options';
|
21 |
const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
|
22 |
|
23 |
+
const VERSION = '4.14.4';
|
24 |
|
25 |
const FEED_URL = 'https://theeventscalendar.com/feed/';
|
26 |
|
212 |
tribe_assets(
|
213 |
$this,
|
214 |
[
|
215 |
+
[ 'tec-variables-skeleton', 'variables-skeleton.css', ],
|
216 |
+
[ 'tribe-common-skeleton-style', 'common-skeleton.css', [ 'tec-variables-skeleton' ] ],
|
217 |
+
[ 'tec-variables-full', 'variables-full.css', ],
|
218 |
+
[ 'tribe-common-full-style', 'common-full.css', [ 'tec-variables-full', 'tribe-common-skeleton-style' ] ],
|
219 |
],
|
220 |
null
|
221 |
);
|
224 |
tribe_assets(
|
225 |
$this,
|
226 |
[
|
227 |
+
[ 'tribe-ui', 'tribe-ui.css', [ 'tec-variables-full' ] ],
|
228 |
[ 'tribe-buttonset', 'buttonset.js', [ 'jquery', 'underscore' ] ],
|
229 |
+
[ 'tribe-common-admin', 'tribe-common-admin.css', [ 'tec-variables-full', 'tribe-dependency-style', 'tribe-bumpdown-css', 'tribe-buttonset-style', 'tribe-select2-css' ] ],
|
230 |
[ 'tribe-validation', 'validation.js', [ 'jquery', 'underscore', 'tribe-common', 'tribe-utils-camelcase', 'tribe-tooltipster' ] ],
|
231 |
+
[ 'tribe-validation-style', 'validation.css', [ 'tec-variables-full', 'tribe-tooltipster-css' ] ],
|
232 |
[ 'tribe-dependency', 'dependency.js', [ 'jquery', 'underscore', 'tribe-common' ] ],
|
233 |
[ 'tribe-dependency-style', 'dependency.css', [ 'tribe-select2-css' ] ],
|
234 |
[ 'tribe-pue-notices', 'pue-notices.js', [ 'jquery' ] ],
|
269 |
$this,
|
270 |
'tribe-customizer-controls',
|
271 |
'customizer-controls.css',
|
272 |
+
[ 'tec-variables-full' ],
|
273 |
'customize_controls_print_styles'
|
274 |
);
|
275 |
|
common/src/Tribe/Service_Providers/Dialog.php
CHANGED
@@ -75,7 +75,7 @@ class Dialog extends \tad_DI52_ServiceProvider {
|
|
75 |
$main,
|
76 |
'tribe-dialog',
|
77 |
'dialog.css',
|
78 |
-
[],
|
79 |
[],
|
80 |
[ 'groups' => 'tribe-dialog' ]
|
81 |
);
|
75 |
$main,
|
76 |
'tribe-dialog',
|
77 |
'dialog.css',
|
78 |
+
[ 'tec-variables-full' ],
|
79 |
[],
|
80 |
[ 'groups' => 'tribe-dialog' ]
|
81 |
);
|
common/src/resources/css/common-full.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.tribe-common figure{line-height:0}.tribe-common figcaption{line-height:normal}.tribe-common a{background-color:transparent;-webkit-text-decoration-skip:objects}.tribe-common abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.tribe-common code,.tribe-common kbd,.tribe-common pre,.tribe-common samp{font-family:monospace;font-size:1em}.tribe-common b,.tribe-common strong{font-weight:inherit;font-weight:bolder}.tribe-common dfn{font-style:italic}.tribe-common mark{background-color:#ff0;color:#000}.tribe-common small{font-size:80%}.tribe-common sub,.tribe-common sup{font-size:75%;line-height:0}.tribe-common hr{border:0;height:0}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=email],.tribe-common input[type=password],.tribe-common input[type=reset],.tribe-common input[type=search],.tribe-common input[type=submit],.tribe-common input[type=text],.tribe-common input[type=url],.tribe-common textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none}.tribe-common button,.tribe-common input,.tribe-common optgroup,.tribe-common select,.tribe-common textarea{color:inherit;font:inherit;-webkit-font-smoothing:antialiased;line-height:normal}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{border-radius:0;outline:0}.tribe-common select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.tribe-common optgroup{font-weight:700}.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common p{font-weight:400;text-rendering:optimizeLegibility}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{opacity:1}.tribe-theme-twentynineteen .tribe-common h1:before,.tribe-theme-twentynineteen .tribe-common h2:before{content:none}.tribe-theme-twentynineteen .tribe-common button,.tribe-theme-twentynineteen .tribe-common input[type=button],.tribe-theme-twentynineteen .tribe-common input[type=reset],.tribe-theme-twentynineteen .tribe-common input[type=submit]{outline:none}.tribe-theme-twentynineteen .tribe-common td,.tribe-theme-twentynineteen .tribe-common th{word-break:normal}.tribe-theme-twentyseventeen .tribe-common h5{letter-spacing:normal;text-transform:none}.tribe-theme-twentyseventeen .tribe-common input[type=text]{border-radius:0}.tribe-theme-twentytwenty .tribe-common{background-color:var(--tec-color-background-events);letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common input,.tribe-theme-twentytwenty .tribe-common textarea{letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common *{word-break:normal}.tribe-theme-twentytwentyone.tribe-common .tribe-common .button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-button .wp-block-button__link:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-file a.wp-block-file__button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-search .wp-block-search__button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common input[type=reset]:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common input[type=submit]:not(:hover):not(:active):not(.has-background){background-color:transparent;background-color:initial}:root{--tec-border-radius-default:4px;--tec-border-width-week-event:2px;--border-radius-default:var(--tec-border-radius-default);--border-width-week-event:var(--tec-border-width-week-event);--tec-box-shadow-default:0 2px 5px 0 var(--tec-color-box-shadow);--tec-box-shadow-tooltip:0 2px 12px 0 var(--tec-color-box-shadow);--tec-box-shadow-card:0 1px 6px 2px var(--tec-color-box-shadow);--tec-box-shadow-multiday:16px 6px 6px -2px var(--tec-color-box-shadow-secondary);--box-shadow-default:var(--tec-box-shadow-default);--box-shadow-tooltip:var(--tec-box-shadow-tooltip);--box-shadow-card:var(--tec-box-shadow-card);--box-shadow-multiday:var(--tec-box-shadow-multiday);--tec-form-color-background:var(--tec-color-background);--tec-form-color-border-default:var(--tec-color-text-primary);--tec-form-color-border-active:var(--tec-color-accent-secondary);--tec-form-color-border-secondary:var(--tec-color-border-tertiary);--tec-form-color-accent-primary:var(--tec-color-accent-primary);--tec-form-box-shadow-default:var(--tec-box-shadow-default);--form-color-background:var(--tec-form-color-background);--form-color-border-default:var(--tec-form-color-border-default);--form-color-border-active:var(--tec-form-color-border-active);--form-color-border-secondary:var(--tec-form-color-border-secondary);--form-color-accent-primary:var(--tec-form-color-accent-primary);--form-box-shadow-default:var(--tec-form-box-shadow-default);--tec-opacity-background:0.07;--tec-opacity-select-highlighted:0.3;--tec-opacity-icon-hover:0.8;--tec-opacity-icon-active:0.9;--tec-opacity-default:1;--opacity-background:var(--tec-opacity-background);--opacity-select-highlighted:var(--tec-opacity-select-highlighted);--opacity-icon-hover:var(--tec-opacity-icon-hover);--opacity-icon-active:var(--tec-opacity-icon-active);--opacity-default:var(--tec-opacity-default);--tec-transition:all 0.2s ease;--tec-transition-background-color:background-color 0.2s ease;--tec-transition-color-border-color:color 0.2s ease,border-color 0.2s ease;--tec-transition-transform:transform 0.2s ease;--tec-transition-border-color:border-color 0.2s ease;--tec-transition-color:color 0.2s ease;--tec-transition-opacity:opacity 0.2s ease;--transition:var(--tec-transition);--transition-background-color:var(--tec-transition-background-color);--transition-color-border-color:var(--tec-transition-color-border-color);--transition-transform:var(--tec-transition-transform);--transition-border-color:var(--tec-transition-border-color);--transition-color:var(--tec-transition-color);--transition-opacity:var(--tec-transition-opacity);--tec-font-family-sans-serif:"Helvetica Neue",Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;--tec-font-weight-regular:400;--tec-font-weight-bold:700;--tec-font-size-0:11px;--tec-font-size-1:12px;--tec-font-size-2:14px;--tec-font-size-3:16px;--tec-font-size-4:18px;--tec-font-size-5:20px;--tec-font-size-6:22px;--tec-font-size-7:24px;--tec-font-size-8:28px;--tec-font-size-9:32px;--tec-font-size-10:42px;--tec-line-height-0:1.38;--tec-line-height-1:1.42;--tec-line-height-2:1.5;--tec-line-height-3:1.62;--font-family-sans-serif:var(--tec-font-family-sans-serif);--font-family-base:var(--tec-font-family-sans-serif);--font-weight-regular:var(--tec-font-weight-regular);--font-weight-bold:var(--tec-font-weight-bold);--font-size-0:var(--tec-font-size-0);--font-size-1:var(--tec-font-size-1);--font-size-2:var(--tec-font-size-2);--font-size-3:var(--tec-font-size-3);--font-size-4:var(--tec-font-size-4);--font-size-5:var(--tec-font-size-5);--font-size-6:var(--tec-font-size-6);--font-size-7:var(--tec-font-size-7);--font-size-8:var(--tec-font-size-8);--font-size-9:var(--tec-font-size-9);--font-size-10:var(--tec-font-size-10);--line-height-0:var(--tec-line-height-0);--line-height-1:var(--tec-line-height-1);--line-height-2:var(--tec-line-height-2);--line-height-3:var(--tec-line-height-3)}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{line-height:0}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3);font-weight:400;font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-form-control-checkbox__label:hover,.tribe-common .tribe-common-form-control-radio__label:hover{opacity:.8;opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--tec-color-background);background-color:var(--tec-form-color-background);border:1px solid var(--tec-color-text-primary);border:1px solid var(--tec-form-color-border-default);height:20px;position:relative;width:20px}.tribe-common .tribe-common-form-control-checkbox__input:active,.tribe-common .tribe-common-form-control-checkbox__input:focus,.tribe-common .tribe-common-form-control-checkbox__input:hover,.tribe-common .tribe-common-form-control-radio__input:active,.tribe-common .tribe-common-form-control-radio__input:focus,.tribe-common .tribe-common-form-control-radio__input:hover{border-color:var(--tec-color-accent-secondary);border-color:var(--tec-form-color-border-active);opacity:.8;opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-checkbox__input:checked,.tribe-common .tribe-common-form-control-radio__input:checked{background-color:var(--tec-color-accent-secondary);background-color:var(--tec-form-color-border-active)}.tribe-common .tribe-common-form-control-checkbox__input{border-radius:4px}.tribe-common .tribe-common-form-control-checkbox__input:checked:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='var(--tec-color-background)'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;content:"";display:block;height:9px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}.tribe-common .tribe-common-form-control-checkbox__input:focus+.tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-checkbox__input:hover+.tribe-common-form-control-checkbox__label{opacity:.8;opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-radio__input{border-radius:50%}.tribe-common .tribe-common-form-control-radio__input:checked:before{background-color:var(--tec-color-background);background-color:var(--tec-form-color-background);border-radius:50%;content:"";display:block;height:8px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:8px}.tribe-common .tribe-common-form-control-radio__input:focus+.tribe-common-form-control-radio__label,.tribe-common .tribe-common-form-control-radio__input:hover+.tribe-common-form-control-radio__label{opacity:.8;opacity:var(--tec-opacity-icon-hover)}#top .main_color .tribe-common .tribe-common-form-control-checkbox__label,#top .main_color .tribe-common .tribe-common-form-control-radio__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label{font-size:14px;font-size:var(--tec-font-size-2);font-weight:400;font-weight:var(--tec-font-weight-regular)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-checkbox__input:checked:before{margin:0}.tribe-common .tribe-common-form-control-slider{line-height:0}.tribe-common .tribe-common-form-control-slider__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;transition:var(--tec-transition-background-color);background-color:var(--tec-color-accent-primary);background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-slider__input::-moz-range-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;transition:var(--tec-transition-background-color);background-color:var(--tec-color-accent-primary);background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-slider__input::-ms-track{background-color:transparent;border-color:transparent;border-width:5px 0;color:transparent;height:10px}.tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,.tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper{background-color:var(--tec-color-accent-primary);background-color:var(--tec-form-color-accent-primary);border-radius:10px}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb{background-color:var(--tec-color-background);background-color:var(--tec-form-color-background);border:1px solid var(--tec-color-border-tertiary);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:0 2px 5px 0 var(--tec-color-box-shadow);box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px;-webkit-appearance:none;appearance:none}.tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb{background-color:var(--tec-color-background);background-color:var(--tec-form-color-background);border:1px solid var(--tec-color-border-tertiary);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:0 2px 5px 0 var(--tec-color-box-shadow);box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px}.tribe-common .tribe-common-form-control-slider__input::-ms-thumb{background-color:var(--tec-color-background);background-color:var(--tec-form-color-background);border:1px solid var(--tec-color-border-tertiary);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:0 2px 5px 0 var(--tec-color-box-shadow);box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px;box-shadow:none;margin-top:-1px}.tribe-common .tribe-common-form-control-slider__label{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);line-height:1.38;line-height:var(--tec-line-height-0);color:var(--tec-color-text-secondary)}#top .main_color .tribe-common .tribe-common-form-control-slider__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label,.tribe-common .tribe-common-form-control-slider__label{font-size:12px;font-size:var(--tec-font-size-1);font-weight:400;font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-form-control-text__input{font-size:16px;font-size:var(--tec-font-size-3);border:0;border-bottom:1px solid var(--tec-color-border-default)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input,.tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);line-height:1.62;line-height:var(--tec-line-height-3);font-weight:400;font-weight:var(--tec-font-weight-regular)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{font-size:14px;font-size:var(--tec-font-size-2);border:0}.tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder{color:var(--tec-color-text-secondary);font-style:normal;opacity:1;opacity:var(--tec-opacity-default)}.tribe-common .tribe-common-form-control-text__input::placeholder{color:var(--tec-color-text-secondary);font-style:normal;opacity:1;opacity:var(--tec-opacity-default)}.tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:var(--tec-color-border-active);outline:0}.tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-text__input{line-height:inherit}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-size:16px;font-size:var(--tec-font-size-3);line-height:1.62;line-height:var(--tec-line-height-3);font-weight:400;font-weight:var(--tec-font-weight-regular);background:var(--tec-color-background);border:0;border-bottom:1px solid var(--tec-color-border-default)}#top .main_color .tribe-common .tribe-common-form-control-text__input:focus,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:var(--tec-color-border-active);box-shadow:none}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3);font-weight:400;font-weight:var(--tec-font-weight-regular);border:0}.tribe-common .tribe-common-form-control-toggle{line-height:0;position:relative}.tribe-common .tribe-common-form-control-toggle__input{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;transition:var(--tec-transition-background-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--tec-color-border-tertiary);background-color:var(--tec-form-color-border-secondary);width:40px}.tribe-common .tribe-common-form-control-toggle__input::-ms-check{display:none}.tribe-common .tribe-common-form-control-toggle__input+label:before{background-color:var(--tec-color-background);background-color:var(--tec-form-color-background);border:1px solid var(--tec-color-border-tertiary);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:0 2px 5px 0 var(--tec-color-box-shadow);box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;content:"";left:0;position:absolute;top:0;transition:transform .2s ease;transition:var(--tec-transition-transform)}.tribe-common .tribe-common-form-control-toggle__input:checked{background-color:var(--tec-color-accent-primary);background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-toggle__input:checked+label:before{transform:translateX(20px)}.tribe-common .tribe-common-form-control-toggle__label{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);line-height:1.38;line-height:var(--tec-line-height-0);color:var(--tec-color-text-secondary)}#top .main_color .tribe-common .tribe-common-form-control-toggle__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label,.tribe-common .tribe-common-form-control-toggle__label{font-size:12px;font-size:var(--tec-font-size-1);font-weight:400;font-weight:var(--tec-font-weight-regular)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-toggle__input{top:0}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-toggle__input:checked:before{content:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-form-control-toggle__input:after{display:none}.tribe-common a,.tribe-common a:active,.tribe-common a:focus,.tribe-common a:hover,.tribe-common a:visited{color:var(--tec-color-text-primary);outline:0;text-decoration:none}.site-footer .widget-area .tribe-common a,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a,.tribe-theme-twentyseventeen .tribe-common a{box-shadow:none}.site-footer .widget-area .tribe-common a:focus,.site-footer .widget-area .tribe-common a:hover,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a:focus,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a:hover,.tribe-theme-twentyseventeen .tribe-common a:focus,.tribe-theme-twentyseventeen .tribe-common a:hover{box-shadow:none;color:var(--tec-color-text-primary)}.tribe-theme-twentynineteen .entry .tribe-common a,.tribe-theme-twentynineteen .tribe-common a,.tribe-theme-twentytwentyone .entry .tribe-common a,.tribe-theme-twentytwentyone .tribe-common a{text-decoration:none}.main_color .sidebar .tribe-common a,.main_color .sidebar .tribe-common a:active,.main_color .sidebar .tribe-common a:focus,.main_color .sidebar .tribe-common a:hover,.main_color .sidebar .tribe-common a:visited,.tribe-theme-enfold .tribe-common a,.tribe-theme-enfold .tribe-common a:active,.tribe-theme-enfold .tribe-common a:focus,.tribe-theme-enfold .tribe-common a:hover,.tribe-theme-enfold .tribe-common a:visited{color:var(--tec-color-text-primary)}.tribe-common .tribe-common-anchor{border-bottom:2px solid transparent;transition:border-color .2s ease;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-anchor:active,.tribe-common .tribe-common-anchor:focus,.tribe-common .tribe-common-anchor:hover{border-bottom:2px solid currentColor}.tribe-common .tribe-common-anchor-alt{border-bottom:2px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:color .2s ease;transition:var(--tec-transition-color)}.tribe-common .tribe-common-anchor-alt:active,.tribe-common .tribe-common-anchor-alt:focus,.tribe-common .tribe-common-anchor-alt:hover{border-bottom:2px solid currentColor;color:var(--tec-color-link-accent)}.tribe-common .tribe-common-anchor-thin{border-bottom:1px solid transparent;transition:border-color .2s ease;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-anchor-thin:active,.tribe-common .tribe-common-anchor-thin:focus,.tribe-common .tribe-common-anchor-thin:hover{border-bottom:1px solid var(--tec-color-link-primary)}.tribe-common .tribe-common-anchor-thin-alt{border-bottom:1px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:color .2s ease;transition:var(--tec-transition-color)}.tribe-common .tribe-common-anchor-thin-alt:active,.tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-common .tribe-common-anchor-thin-alt:hover{border-bottom:1px solid currentColor;color:var(--tec-color-link-accent)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:hover{color:var(--tec-color-accent-primary)}.site-footer .widget-area .tribe-common .tribe-common-anchor,.site-footer .widget-area .tribe-common .tribe-common-anchor-thin,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-thin{transition:border-color .2s ease;transition:var(--tec-transition-border-color)}.site-footer .widget-area .tribe-common .tribe-common-anchor-alt,.site-footer .widget-area .tribe-common .tribe-common-anchor-thin-alt,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-alt,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-thin-alt{transition:color .2s ease;transition:var(--tec-transition-color)}.tribe-common .tribe-common-b1{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-size:14px;font-size:var(--tec-font-size-2);font-weight:400;font-weight:var(--tec-font-weight-regular);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1{font-size:16px;font-size:var(--tec-font-size-3);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-b1--bold{font-weight:700;font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-b2{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-size:12px;font-size:var(--tec-font-size-1);font-weight:400;font-weight:var(--tec-font-weight-regular);line-height:1.38;line-height:var(--tec-line-height-0)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2{font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-b2--bold{font-weight:700;font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-b3{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-size:11px;font-size:var(--tec-font-size-0);font-weight:400;font-weight:var(--tec-font-weight-regular);line-height:1.5;line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3{font-size:12px;font-size:var(--tec-font-size-1);line-height:1.38;line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-b3--bold{font-weight:700;font-weight:var(--tec-font-weight-bold)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1--min-medium{font-size:16px;font-size:var(--tec-font-size-3);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2--min-medium{font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3--min-medium,.tribe-common .tribe-common-cta{font-size:12px;font-size:var(--tec-font-size-1);line-height:1.38;line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-cta{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:400;font-weight:var(--tec-font-weight-regular);font-weight:700;font-weight:var(--tec-font-weight-bold);border-bottom:2px solid transparent;transition:border-color .2s ease;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-cta:active,.tribe-common .tribe-common-cta:focus,.tribe-common .tribe-common-cta:hover{border-bottom:2px solid currentColor}.tribe-common .tribe-common-cta--alt{border-bottom:2px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:color .2s ease;transition:var(--tec-transition-color)}.tribe-common .tribe-common-cta--alt:active,.tribe-common .tribe-common-cta--alt:focus,.tribe-common .tribe-common-cta--alt:hover{border-bottom:2px solid currentColor;color:var(--tec-color-link-accent)}.tribe-common .tribe-common-cta--thin{border-bottom:1px solid transparent;transition:border-color .2s ease;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-cta--thin:active,.tribe-common .tribe-common-cta--thin:focus,.tribe-common .tribe-common-cta--thin:hover{border-bottom:1px solid var(--tec-color-link-primary)}.tribe-common .tribe-common-cta--thin-alt{border-bottom:1px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:color .2s ease;transition:var(--tec-transition-color)}.tribe-common .tribe-common-cta--thin-alt:active,.tribe-common .tribe-common-cta--thin-alt:focus,.tribe-common .tribe-common-cta--thin-alt:hover{border-bottom:1px solid currentColor;color:var(--tec-color-link-accent)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:hover{color:var(--tec-color-accent-primary)}.tribe-common .tribe-common-h1{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);font-size:28px;font-size:var(--tec-font-size-8);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h1{font-size:42px;font-size:var(--tec-font-size-10);line-height:1.38;line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-h2{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);font-size:24px;font-size:var(--tec-font-size-7);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h2{font-size:32px;font-size:var(--tec-font-size-9);line-height:1.38;line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-h3{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);font-size:22px;font-size:var(--tec-font-size-6);line-height:1.5;line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3{font-size:28px;font-size:var(--tec-font-size-8);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-common .tribe-common-h4{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);font-size:20px;font-size:var(--tec-font-size-5);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4{font-size:24px;font-size:var(--tec-font-size-7);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-common .tribe-common-h5{font-size:18px;font-size:var(--tec-font-size-4)}.tribe-common .tribe-common-h5,.tribe-common .tribe-common-h6{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);line-height:1.5;line-height:var(--tec-line-height-2)}.tribe-common .tribe-common-h6{font-size:16px;font-size:var(--tec-font-size-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6{font-size:16px;font-size:var(--tec-font-size-3);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h7{font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h7,.tribe-common .tribe-common-h8{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-h8{font-size:12px;font-size:var(--tec-font-size-1);line-height:1.38;line-height:var(--tec-line-height-0)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3--min-medium{font-size:28px;font-size:var(--tec-font-size-8);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4--min-medium{font-size:24px;font-size:var(--tec-font-size-7);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h5--min-medium{font-size:18px;font-size:var(--tec-font-size-4);line-height:1.5;line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6--min-medium{font-size:16px;font-size:var(--tec-font-size-3);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h7--min-medium{font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h--alt{font-weight:400;font-weight:var(--tec-font-weight-regular)}.tribe-theme-avada #main .tribe-common .tribe-common-h1{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);font-size:28px;font-size:var(--tec-font-size-8);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h1{font-size:42px;font-size:var(--tec-font-size-10);line-height:1.38;line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common .tribe-common-h2{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);font-size:24px;font-size:var(--tec-font-size-7);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h2{font-size:32px;font-size:var(--tec-font-size-9);line-height:1.38;line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common .tribe-common-h3{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);font-size:22px;font-size:var(--tec-font-size-6);line-height:1.5;line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3{font-size:28px;font-size:var(--tec-font-size-8);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common .tribe-common-h4{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);font-size:20px;font-size:var(--tec-font-size-5);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4{font-size:24px;font-size:var(--tec-font-size-7);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common .tribe-common-h5{font-size:18px;font-size:var(--tec-font-size-4)}.tribe-theme-avada #main .tribe-common .tribe-common-h5,.tribe-theme-avada #main .tribe-common .tribe-common-h6{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold);line-height:1.5;line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common .tribe-common-h6{font-size:16px;font-size:var(--tec-font-size-3)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6{font-size:16px;font-size:var(--tec-font-size-3);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h7{font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h7,.tribe-theme-avada #main .tribe-common .tribe-common-h8{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-weight:700;font-weight:var(--tec-font-weight-bold)}.tribe-theme-avada #main .tribe-common .tribe-common-h8{font-size:12px;font-size:var(--tec-font-size-1);line-height:1.38;line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3--min-medium{font-size:28px;font-size:var(--tec-font-size-8);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4--min-medium{font-size:24px;font-size:var(--tec-font-size-7);line-height:1.42;line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h5--min-medium{font-size:18px;font-size:var(--tec-font-size-4);line-height:1.5;line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6--min-medium{font-size:16px;font-size:var(--tec-font-size-3);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h7--min-medium{font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h--alt{font-weight:400;font-weight:var(--tec-font-weight-regular)}.tribe-common button{border:none}.tribe-common button,.tribe-common button:focus,.tribe-common button:hover,.tribe-theme-twentyseventeen .tribe-common button:focus,.tribe-theme-twentyseventeen .tribe-common button:hover{background-color:transparent}.tribe-theme-twentytwenty .tribe-common button{background-color:transparent;text-transform:inherit}.tribe-theme-twentytwenty .tribe-common button:focus,.tribe-theme-twentytwenty .tribe-common button:hover{text-decoration:none}.tribe-theme-twentytwentyone .tribe-common button:not(:hover):not(:active){background-color:inherit;color:inherit}.tribe-theme-enfold .tribe-common th{letter-spacing:0;text-transform:none}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3);font-weight:400;font-weight:var(--tec-font-weight-regular);font-weight:700;font-weight:var(--tec-font-weight-bold);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:var(--tec-color-background);border:1px solid var(--tec-color-accent-primary);border-radius:4px;border-radius:var(--tec-border-radius-default);text-align:center;transition:all .2s ease;transition:var(--tec-transition);color:var(--tec-color-button-primary);padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{width:auto}.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{background-color:var(--tec-color-accent-primary);color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:active{opacity:.9}.tribe-common .tribe-common-c-btn-border--secondary,.tribe-common a.tribe-common-c-btn-border--secondary{border-color:var(--tec-color-button-secondary);color:var(--tec-color-button-secondary)}.tribe-common .tribe-common-c-btn-border--secondary:focus,.tribe-common .tribe-common-c-btn-border--secondary:hover,.tribe-common a.tribe-common-c-btn-border--secondary:focus,.tribe-common a.tribe-common-c-btn-border--secondary:hover{background-color:var(--tec-color-button-secondary)}.tribe-common .tribe-common-c-btn-border--secondary:active,.tribe-common a.tribe-common-c-btn-border--secondary:active{opacity:.9}.tribe-common .tribe-common-c-btn-border--alt,.tribe-common a.tribe-common-c-btn-border--alt{border-color:var(--tec-color-border-secondary);color:var(--tec-color-text-primary);font-weight:400;font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-c-btn-border--alt:focus,.tribe-common .tribe-common-c-btn-border--alt:hover,.tribe-common a.tribe-common-c-btn-border--alt:focus,.tribe-common a.tribe-common-c-btn-border--alt:hover{background-color:var(--tec-color-background);border-color:var(--tec-color-border-active);color:var(--tec-color-text-primary)}.tribe-common .tribe-common-c-btn-border--alt:active,.tribe-common a.tribe-common-c-btn-border--alt:active{opacity:.9}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:hover{background-color:var(--tec-color-button-primary)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--secondary:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--secondary:hover{background-color:var(--tec-color-button-secondary)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--alt:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-size:12px;font-size:var(--tec-font-size-1);line-height:1.38;line-height:var(--tec-line-height-0);font-weight:400;font-weight:var(--tec-font-weight-regular);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:var(--tec-color-background);border:1px solid var(--tec-color-border-default);border-radius:4px;border-radius:var(--tec-border-radius-default);text-align:center;transition:color .2s ease,border-color .2s ease;transition:var(--tec-transition-color-border-color)}.tribe-common .tribe-common-c-btn-border-small:focus,.tribe-common .tribe-common-c-btn-border-small:hover,.tribe-common a.tribe-common-c-btn-border-small:focus,.tribe-common a.tribe-common-c-btn-border-small:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border-small:active,.tribe-common a.tribe-common-c-btn-border-small:active{border-color:var(--tec-color-border-active)}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{color:var(--tec-color-text-secondary);padding:14px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border-small,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border-small{padding:6px 15px;width:auto}.tribe-common .tribe-common-c-btn-border-small:active,.tribe-common .tribe-common-c-btn-border-small:focus,.tribe-common .tribe-common-c-btn-border-small:hover,.tribe-common a.tribe-common-c-btn-border-small:active,.tribe-common a.tribe-common-c-btn-border-small:focus,.tribe-common a.tribe-common-c-btn-border-small:hover{color:var(--tec-color-text-primary)}.tribe-common .tribe-common-c-btn-border-small:disabled,.tribe-common a.tribe-common-c-btn-border-small:disabled{color:var(--tec-color-text-disabled)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border-small:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-icon{border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto}.tribe-common .tribe-common-c-btn-icon--caret-left:active .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-left:focus .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-left:hover .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:active .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:focus .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:hover .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-primary)}.tribe-common .tribe-common-c-btn-icon--caret-left:disabled .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:disabled .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-disabled)}.tribe-common .tribe-common-c-btn-icon--caret-left .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-secondary)}.tribe-common .tribe-common-c-btn-icon--border{align-items:center;background-color:var(--tec-color-background);border:1px solid var(--tec-color-border-default);display:inline-flex;height:56px;justify-content:center;transition:none;width:56px}.tribe-common .tribe-common-c-btn-icon--border:focus,.tribe-common .tribe-common-c-btn-icon--border:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-icon--border:active{border-color:var(--tec-color-border-active)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-icon--border:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{color:var(--tec-color-text-primary);font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-family:var(--tec-font-family-sans-serif);font-size:14px;font-size:var(--tec-font-size-2);line-height:1.62;line-height:var(--tec-line-height-3);font-weight:400;font-weight:var(--tec-font-weight-regular);font-weight:700;font-weight:var(--tec-font-weight-bold);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;border-radius:4px;border-radius:var(--tec-border-radius-default);color:var(--tec-color-background);text-align:center;transition:background-color .2s ease;transition:var(--tec-transition-background-color);background-color:var(--tec-color-button-primary);padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-btn:focus,.tribe-common .tribe-common-c-btn:hover,.tribe-common a.tribe-common-c-btn:focus,.tribe-common a.tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover)}.tribe-common .tribe-common-c-btn:active,.tribe-common a.tribe-common-c-btn:active{background-color:var(--tec-color-button-primary-active)}.tribe-common .tribe-common-c-btn:disabled,.tribe-common a.tribe-common-c-btn:disabled{background-color:var(--tec-color-button-primary-background)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover);color:var(--tec-color-background)}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn{background-color:var(--tec-color-button-primary)}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover);color:var(--tec-color-background)}.tribe-theme-twentytwentyone .tribe-common .tribe-common-c-btn{outline:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-c-btn:not(:hover):not(:active){background-color:var(--tec-color-button-primary);color:var(--tec-color-background)}.tribe-common .tribe-common-c-loader__dot circle{animation-direction:normal;animation-duration:2.24s;animation-iteration-count:infinite;animation-name:a;fill:currentColor;opacity:.07;opacity:var(--tec-opacity-background)}.tribe-common .tribe-common-c-loader__dot--first circle{animation-delay:.45s}.tribe-common .tribe-common-c-loader__dot--second circle{animation-delay:1.05s}.tribe-common .tribe-common-c-loader__dot--third circle{animation-delay:1.35s}@keyframes a{50%{opacity:1;opacity:var(--tec-opacity-default)}}.tribe-common .tribe-common-c-svgicon{color:var(--tec-color-accent-primary)}.tribe-common .tribe-common-c-svgicon--featured path{fill:currentColor}.tribe-common .tribe-common-c-svgicon--recurring path{fill:var(--tec-color-icon-active);stroke:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon--close-alt path,.tribe-common .tribe-common-c-svgicon--close path{stroke:var(--tec-color-icon-secondary)}.tribe-common .tribe-common-c-svgicon--messages-not-found path{stroke:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon--messages-not-found .tribe-common-c-svgicon__svg-stroke{stroke:currentColor}.tribe-common .tribe-common-c-svgicon__svg-fill{fill:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon__svg-stroke{stroke:var(--tec-color-icon-active)}
|
1 |
+
.tribe-common figure{line-height:0}.tribe-common figcaption{line-height:normal}.tribe-common a{background-color:transparent;-webkit-text-decoration-skip:objects}.tribe-common abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.tribe-common code,.tribe-common kbd,.tribe-common pre,.tribe-common samp{font-family:monospace;font-size:1em}.tribe-common b,.tribe-common strong{font-weight:inherit;font-weight:bolder}.tribe-common dfn{font-style:italic}.tribe-common mark{background-color:#ff0;color:#000}.tribe-common small{font-size:80%}.tribe-common sub,.tribe-common sup{font-size:75%;line-height:0}.tribe-common hr{border:0;height:0}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=email],.tribe-common input[type=password],.tribe-common input[type=reset],.tribe-common input[type=search],.tribe-common input[type=submit],.tribe-common input[type=text],.tribe-common input[type=url],.tribe-common textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none}.tribe-common button,.tribe-common input,.tribe-common optgroup,.tribe-common select,.tribe-common textarea{color:inherit;font:inherit;-webkit-font-smoothing:antialiased;line-height:normal}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{border-radius:0;outline:0}.tribe-common select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.tribe-common optgroup{font-weight:700}.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common p{font-weight:400;text-rendering:optimizeLegibility}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{opacity:1}.tribe-theme-twentynineteen .tribe-common h1:before,.tribe-theme-twentynineteen .tribe-common h2:before{content:none}.tribe-theme-twentynineteen .tribe-common button,.tribe-theme-twentynineteen .tribe-common input[type=button],.tribe-theme-twentynineteen .tribe-common input[type=reset],.tribe-theme-twentynineteen .tribe-common input[type=submit]{outline:none}.tribe-theme-twentynineteen .tribe-common td,.tribe-theme-twentynineteen .tribe-common th{word-break:normal}.tribe-theme-twentyseventeen .tribe-common h5{letter-spacing:normal;text-transform:none}.tribe-theme-twentyseventeen .tribe-common input[type=text]{border-radius:0}.tribe-theme-twentytwenty .tribe-common{background-color:var(--tec-color-background-events);letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common input,.tribe-theme-twentytwenty .tribe-common textarea{letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common *{word-break:normal}.tribe-theme-twentytwentyone.tribe-common .tribe-common .button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-button .wp-block-button__link:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-file a.wp-block-file__button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-search .wp-block-search__button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common input[type=reset]:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common input[type=submit]:not(:hover):not(:active):not(.has-background){background-color:transparent;background-color:initial}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{line-height:0}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-form-control-checkbox__label:hover,.tribe-common .tribe-common-form-control-radio__label:hover{opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-default);height:20px;position:relative;width:20px}.tribe-common .tribe-common-form-control-checkbox__input:active,.tribe-common .tribe-common-form-control-checkbox__input:focus,.tribe-common .tribe-common-form-control-checkbox__input:hover,.tribe-common .tribe-common-form-control-radio__input:active,.tribe-common .tribe-common-form-control-radio__input:focus,.tribe-common .tribe-common-form-control-radio__input:hover{border-color:var(--tec-form-color-border-active);opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-checkbox__input:checked,.tribe-common .tribe-common-form-control-radio__input:checked{background-color:var(--tec-form-color-border-active)}.tribe-common .tribe-common-form-control-checkbox__input{border-radius:4px}.tribe-common .tribe-common-form-control-checkbox__input:checked:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='%23fff'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;content:"";display:block;height:9px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}.tribe-common .tribe-common-form-control-checkbox__input:focus+.tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-checkbox__input:hover+.tribe-common-form-control-checkbox__label{opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-radio__input{border-radius:50%}.tribe-common .tribe-common-form-control-radio__input:checked:before{background-color:var(--tec-form-color-background);border-radius:50%;content:"";display:block;height:8px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:8px}.tribe-common .tribe-common-form-control-radio__input:focus+.tribe-common-form-control-radio__label,.tribe-common .tribe-common-form-control-radio__input:hover+.tribe-common-form-control-radio__label{opacity:var(--tec-opacity-icon-hover)}#top .main_color .tribe-common .tribe-common-form-control-checkbox__label,#top .main_color .tribe-common .tribe-common-form-control-radio__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label{font-size:var(--tec-font-size-2);font-weight:var(--tec-font-weight-regular)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-checkbox__input:checked:before{margin:0}.tribe-common .tribe-common-form-control-slider{line-height:0}.tribe-common .tribe-common-form-control-slider__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:var(--tec-transition-background-color);background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-slider__input::-moz-range-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:var(--tec-transition-background-color);background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-slider__input::-ms-track{background-color:transparent;border-color:transparent;border-width:5px 0;color:transparent;height:10px}.tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,.tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper{background-color:var(--tec-form-color-accent-primary);border-radius:10px}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px;-webkit-appearance:none;appearance:none}.tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px}.tribe-common .tribe-common-form-control-slider__input::-ms-thumb{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px;box-shadow:none;margin-top:-1px}.tribe-common .tribe-common-form-control-slider__label{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);line-height:var(--tec-line-height-0);color:var(--tec-color-text-secondary)}#top .main_color .tribe-common .tribe-common-form-control-slider__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label,.tribe-common .tribe-common-form-control-slider__label{font-size:var(--tec-font-size-1);font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-form-control-text__input{font-size:var(--tec-font-size-3);border:0;border-bottom:1px solid var(--tec-color-border-default)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input,.tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{font-size:var(--tec-font-size-2);border:0}.tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder{color:var(--tec-color-text-secondary);font-style:normal;opacity:var(--tec-opacity-default)}.tribe-common .tribe-common-form-control-text__input::placeholder{color:var(--tec-color-text-secondary);font-style:normal;opacity:var(--tec-opacity-default)}.tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:var(--tec-color-border-active);outline:0}.tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-text__input{line-height:inherit}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);background:var(--tec-color-background);border:0;border-bottom:1px solid var(--tec-color-border-default)}#top .main_color .tribe-common .tribe-common-form-control-text__input:focus,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:var(--tec-color-border-active);box-shadow:none}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);border:0}.tribe-common .tribe-common-form-control-toggle{line-height:0;position:relative}.tribe-common .tribe-common-form-control-toggle__input{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:var(--tec-transition-background-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--tec-form-color-border-secondary);width:40px}.tribe-common .tribe-common-form-control-toggle__input::-ms-check{display:none}.tribe-common .tribe-common-form-control-toggle__input+label:before{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;content:"";left:0;position:absolute;top:0;transition:var(--tec-transition-transform)}.tribe-common .tribe-common-form-control-toggle__input:checked{background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-toggle__input:checked+label:before{transform:translateX(20px)}.tribe-common .tribe-common-form-control-toggle__label{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);line-height:var(--tec-line-height-0);color:var(--tec-color-text-secondary)}#top .main_color .tribe-common .tribe-common-form-control-toggle__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label,.tribe-common .tribe-common-form-control-toggle__label{font-size:var(--tec-font-size-1);font-weight:var(--tec-font-weight-regular)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-toggle__input{top:0}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-toggle__input:checked:before{content:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-form-control-toggle__input:after{display:none}.tribe-common a,.tribe-common a:active,.tribe-common a:focus,.tribe-common a:hover,.tribe-common a:visited{color:var(--tec-color-text-primary);outline:0;text-decoration:none}.site-footer .widget-area .tribe-common a,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a,.tribe-theme-twentyseventeen .tribe-common a{box-shadow:none}.site-footer .widget-area .tribe-common a:focus,.site-footer .widget-area .tribe-common a:hover,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a:focus,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a:hover,.tribe-theme-twentyseventeen .tribe-common a:focus,.tribe-theme-twentyseventeen .tribe-common a:hover{box-shadow:none;color:var(--tec-color-text-primary)}.tribe-theme-twentynineteen .entry .tribe-common a,.tribe-theme-twentynineteen .tribe-common a,.tribe-theme-twentytwentyone .entry .tribe-common a,.tribe-theme-twentytwentyone .tribe-common a{text-decoration:none}.main_color .sidebar .tribe-common a,.main_color .sidebar .tribe-common a:active,.main_color .sidebar .tribe-common a:focus,.main_color .sidebar .tribe-common a:hover,.main_color .sidebar .tribe-common a:visited,.tribe-theme-enfold .tribe-common a,.tribe-theme-enfold .tribe-common a:active,.tribe-theme-enfold .tribe-common a:focus,.tribe-theme-enfold .tribe-common a:hover,.tribe-theme-enfold .tribe-common a:visited{color:var(--tec-color-text-primary)}.tribe-common .tribe-common-anchor{border-bottom:2px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-anchor:active,.tribe-common .tribe-common-anchor:focus,.tribe-common .tribe-common-anchor:hover{border-bottom:2px solid currentColor}.tribe-common .tribe-common-anchor-alt{border-bottom:2px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-anchor-alt:active,.tribe-common .tribe-common-anchor-alt:focus,.tribe-common .tribe-common-anchor-alt:hover{border-bottom:2px solid currentColor;color:var(--tec-color-link-accent)}.tribe-common .tribe-common-anchor-thin{border-bottom:1px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-anchor-thin:active,.tribe-common .tribe-common-anchor-thin:focus,.tribe-common .tribe-common-anchor-thin:hover{border-bottom:1px solid var(--tec-color-link-primary)}.tribe-common .tribe-common-anchor-thin-alt{border-bottom:1px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-anchor-thin-alt:active,.tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-common .tribe-common-anchor-thin-alt:hover{border-bottom:1px solid currentColor;color:var(--tec-color-link-accent)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:hover{color:var(--tec-color-accent-primary)}.site-footer .widget-area .tribe-common .tribe-common-anchor,.site-footer .widget-area .tribe-common .tribe-common-anchor-thin,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-thin{transition:var(--tec-transition-border-color)}.site-footer .widget-area .tribe-common .tribe-common-anchor-alt,.site-footer .widget-area .tribe-common .tribe-common-anchor-thin-alt,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-alt,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-thin-alt{transition:var(--tec-transition-color)}.tribe-common .tribe-common-b1{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);font-weight:var(--tec-font-weight-regular);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-b1--bold{font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-b2{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-1);font-weight:var(--tec-font-weight-regular);line-height:var(--tec-line-height-0)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-b2--bold{font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-b3{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-0);font-weight:var(--tec-font-weight-regular);line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-b3--bold{font-weight:var(--tec-font-weight-bold)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3--min-medium,.tribe-common .tribe-common-cta{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-cta{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-regular);font-weight:var(--tec-font-weight-bold);border-bottom:2px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-cta:active,.tribe-common .tribe-common-cta:focus,.tribe-common .tribe-common-cta:hover{border-bottom:2px solid currentColor}.tribe-common .tribe-common-cta--alt{border-bottom:2px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-cta--alt:active,.tribe-common .tribe-common-cta--alt:focus,.tribe-common .tribe-common-cta--alt:hover{border-bottom:2px solid currentColor;color:var(--tec-color-link-accent)}.tribe-common .tribe-common-cta--thin{border-bottom:1px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-cta--thin:active,.tribe-common .tribe-common-cta--thin:focus,.tribe-common .tribe-common-cta--thin:hover{border-bottom:1px solid var(--tec-color-link-primary)}.tribe-common .tribe-common-cta--thin-alt{border-bottom:1px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-cta--thin-alt:active,.tribe-common .tribe-common-cta--thin-alt:focus,.tribe-common .tribe-common-cta--thin-alt:hover{border-bottom:1px solid currentColor;color:var(--tec-color-link-accent)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:hover{color:var(--tec-color-accent-primary)}.tribe-common .tribe-common-h1{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h1{font-size:var(--tec-font-size-10);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-h2{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h2{font-size:var(--tec-font-size-9);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-h3{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-6);line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-common .tribe-common-h4{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-5);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-common .tribe-common-h5{font-size:var(--tec-font-size-4)}.tribe-common .tribe-common-h5,.tribe-common .tribe-common-h6{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);line-height:var(--tec-line-height-2)}.tribe-common .tribe-common-h6{font-size:var(--tec-font-size-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h7{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h7,.tribe-common .tribe-common-h8{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-h8{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3--min-medium{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4--min-medium{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h5--min-medium{font-size:var(--tec-font-size-4);line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h7--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h--alt{font-weight:var(--tec-font-weight-regular)}.tribe-theme-avada #main .tribe-common .tribe-common-h1{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h1{font-size:var(--tec-font-size-10);line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common .tribe-common-h2{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h2{font-size:var(--tec-font-size-9);line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common .tribe-common-h3{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-6);line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common .tribe-common-h4{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-5);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common .tribe-common-h5{font-size:var(--tec-font-size-4)}.tribe-theme-avada #main .tribe-common .tribe-common-h5,.tribe-theme-avada #main .tribe-common .tribe-common-h6{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common .tribe-common-h6{font-size:var(--tec-font-size-3)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h7{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h7,.tribe-theme-avada #main .tribe-common .tribe-common-h8{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold)}.tribe-theme-avada #main .tribe-common .tribe-common-h8{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3--min-medium{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4--min-medium{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h5--min-medium{font-size:var(--tec-font-size-4);line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h7--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h--alt{font-weight:var(--tec-font-weight-regular)}.tribe-common button{border:none}.tribe-common button,.tribe-common button:focus,.tribe-common button:hover,.tribe-theme-twentyseventeen .tribe-common button:focus,.tribe-theme-twentyseventeen .tribe-common button:hover{background-color:transparent}.tribe-theme-twentytwenty .tribe-common button{background-color:transparent;text-transform:inherit}.tribe-theme-twentytwenty .tribe-common button:focus,.tribe-theme-twentytwenty .tribe-common button:hover{text-decoration:none}.tribe-theme-twentytwentyone .tribe-common button:not(:hover):not(:active){background-color:inherit;color:inherit}.tribe-theme-enfold .tribe-common th{letter-spacing:0;text-transform:none}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);font-weight:var(--tec-font-weight-bold);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:var(--tec-color-background);border:1px solid var(--tec-color-accent-primary);border-radius:var(--tec-border-radius-default);text-align:center;transition:var(--tec-transition);color:var(--tec-color-button-primary);padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{width:auto}.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{background-color:var(--tec-color-accent-primary);color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:active{opacity:.9}.tribe-common .tribe-common-c-btn-border--secondary,.tribe-common a.tribe-common-c-btn-border--secondary{border-color:var(--tec-color-button-secondary);color:var(--tec-color-button-secondary)}.tribe-common .tribe-common-c-btn-border--secondary:focus,.tribe-common .tribe-common-c-btn-border--secondary:hover,.tribe-common a.tribe-common-c-btn-border--secondary:focus,.tribe-common a.tribe-common-c-btn-border--secondary:hover{background-color:var(--tec-color-button-secondary)}.tribe-common .tribe-common-c-btn-border--secondary:active,.tribe-common a.tribe-common-c-btn-border--secondary:active{opacity:.9}.tribe-common .tribe-common-c-btn-border--alt,.tribe-common a.tribe-common-c-btn-border--alt{border-color:var(--tec-color-border-secondary);color:var(--tec-color-text-primary);font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-c-btn-border--alt:focus,.tribe-common .tribe-common-c-btn-border--alt:hover,.tribe-common a.tribe-common-c-btn-border--alt:focus,.tribe-common a.tribe-common-c-btn-border--alt:hover{background-color:var(--tec-color-background);border-color:var(--tec-color-border-active);color:var(--tec-color-text-primary)}.tribe-common .tribe-common-c-btn-border--alt:active,.tribe-common a.tribe-common-c-btn-border--alt:active{opacity:.9}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:hover{background-color:var(--tec-color-button-primary)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--secondary:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--secondary:hover{background-color:var(--tec-color-button-secondary)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--alt:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0);font-weight:var(--tec-font-weight-regular);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:var(--tec-color-background);border:1px solid var(--tec-color-border-default);border-radius:var(--tec-border-radius-default);text-align:center;transition:var(--tec-transition-color-border-color)}.tribe-common .tribe-common-c-btn-border-small:focus,.tribe-common .tribe-common-c-btn-border-small:hover,.tribe-common a.tribe-common-c-btn-border-small:focus,.tribe-common a.tribe-common-c-btn-border-small:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border-small:active,.tribe-common a.tribe-common-c-btn-border-small:active{border-color:var(--tec-color-border-active)}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{color:var(--tec-color-text-secondary);padding:14px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border-small,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border-small{padding:6px 15px;width:auto}.tribe-common .tribe-common-c-btn-border-small:active,.tribe-common .tribe-common-c-btn-border-small:focus,.tribe-common .tribe-common-c-btn-border-small:hover,.tribe-common a.tribe-common-c-btn-border-small:active,.tribe-common a.tribe-common-c-btn-border-small:focus,.tribe-common a.tribe-common-c-btn-border-small:hover{color:var(--tec-color-text-primary)}.tribe-common .tribe-common-c-btn-border-small:disabled,.tribe-common a.tribe-common-c-btn-border-small:disabled{color:var(--tec-color-text-disabled)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border-small:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-icon{border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto}.tribe-common .tribe-common-c-btn-icon--caret-left:active .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-left:focus .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-left:hover .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:active .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:focus .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:hover .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-primary)}.tribe-common .tribe-common-c-btn-icon--caret-left:disabled .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:disabled .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-disabled)}.tribe-common .tribe-common-c-btn-icon--caret-left .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-secondary)}.tribe-common .tribe-common-c-btn-icon--border{align-items:center;background-color:var(--tec-color-background);border:1px solid var(--tec-color-border-default);display:inline-flex;height:56px;justify-content:center;transition:none;width:56px}.tribe-common .tribe-common-c-btn-icon--border:focus,.tribe-common .tribe-common-c-btn-icon--border:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-icon--border:active{border-color:var(--tec-color-border-active)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-icon--border:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);font-weight:var(--tec-font-weight-bold);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;border-radius:var(--tec-border-radius-default);color:var(--tec-color-background);text-align:center;transition:var(--tec-transition-background-color);background-color:var(--tec-color-button-primary);padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-btn:focus,.tribe-common .tribe-common-c-btn:hover,.tribe-common a.tribe-common-c-btn:focus,.tribe-common a.tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover)}.tribe-common .tribe-common-c-btn:active,.tribe-common a.tribe-common-c-btn:active{background-color:var(--tec-color-button-primary-active)}.tribe-common .tribe-common-c-btn:disabled,.tribe-common a.tribe-common-c-btn:disabled{background-color:var(--tec-color-button-primary-background)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover);color:var(--tec-color-background)}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn{background-color:var(--tec-color-button-primary)}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover);color:var(--tec-color-background)}.tribe-theme-twentytwentyone .tribe-common .tribe-common-c-btn{outline:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-c-btn:not(:hover):not(:active){background-color:var(--tec-color-button-primary);color:var(--tec-color-background)}.tribe-common .tribe-common-c-loader__dot circle{animation-direction:normal;animation-duration:2.24s;animation-iteration-count:infinite;animation-name:a;fill:currentColor;opacity:var(--tec-opacity-background)}.tribe-common .tribe-common-c-loader__dot--first circle{animation-delay:.45s}.tribe-common .tribe-common-c-loader__dot--second circle{animation-delay:1.05s}.tribe-common .tribe-common-c-loader__dot--third circle{animation-delay:1.35s}@keyframes a{50%{opacity:var(--tec-opacity-default)}}.tribe-common .tribe-common-c-svgicon{color:var(--tec-color-accent-primary)}.tribe-common .tribe-common-c-svgicon--featured path{fill:currentColor}.tribe-common .tribe-common-c-svgicon--recurring path{fill:var(--tec-color-icon-active);stroke:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon--close-alt path,.tribe-common .tribe-common-c-svgicon--close path{stroke:var(--tec-color-icon-secondary)}.tribe-common .tribe-common-c-svgicon--messages-not-found path{stroke:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon--messages-not-found .tribe-common-c-svgicon__svg-stroke{stroke:currentColor}.tribe-common .tribe-common-c-svgicon__svg-fill{fill:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon__svg-stroke{stroke:var(--tec-color-icon-active)}
|
common/src/resources/css/common-skeleton.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.tribe-common{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smoothing:antialiased}.tribe-common *{box-sizing:border-box}.tribe-common article,.tribe-common aside,.tribe-common details,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common header,.tribe-common main,.tribe-common menu,.tribe-common nav,.tribe-common section,.tribe-common summary{display:block}.tribe-common svg:not(:root){overflow:hidden}.tribe-common audio,.tribe-common canvas,.tribe-common progress,.tribe-common video{display:inline-block}.tribe-common audio:not([controls]){display:none;height:0}.tribe-common progress{vertical-align:baseline}.tribe-common [hidden],.tribe-common template{display:none}.tribe-common pre{overflow:auto}.tribe-common sub,.tribe-common sup{position:relative;vertical-align:baseline}.tribe-common sup{top:-.5em}.tribe-common sub{bottom:-.25em}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{box-sizing:border-box;margin:0}.tribe-common input[type=number]::-webkit-inner-spin-button,.tribe-common input[type=number]::-webkit-outer-spin-button{height:auto}.tribe-common legend{color:inherit;display:table;max-width:100%;white-space:normal}.tribe-common textarea{overflow:auto;resize:none}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=reset],.tribe-common input[type=submit]{cursor:pointer;overflow:visible}.tribe-common button[disabled],.tribe-common input[disabled]{cursor:default}.tribe-common button::-moz-focus-inner,.tribe-common input::-moz-focus-inner{border:0;padding:0}.tribe-common a,.tribe-common abbr,.tribe-common acronym,.tribe-common address,.tribe-common applet,.tribe-common article,.tribe-common aside,.tribe-common audio,.tribe-common b,.tribe-common big,.tribe-common blockquote,.tribe-common canvas,.tribe-common caption,.tribe-common center,.tribe-common cite,.tribe-common code,.tribe-common dd,.tribe-common del,.tribe-common details,.tribe-common dfn,.tribe-common div,.tribe-common dl,.tribe-common dt,.tribe-common em,.tribe-common embed,.tribe-common fieldset,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common form,.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common header,.tribe-common i,.tribe-common iframe,.tribe-common img,.tribe-common ins,.tribe-common kbd,.tribe-common label,.tribe-common legend,.tribe-common li,.tribe-common main,.tribe-common mark,.tribe-common menu,.tribe-common nav,.tribe-common object,.tribe-common ol,.tribe-common output,.tribe-common p,.tribe-common pre,.tribe-common q,.tribe-common ruby,.tribe-common s,.tribe-common samp,.tribe-common section,.tribe-common small,.tribe-common span,.tribe-common strike,.tribe-common strong,.tribe-common sub,.tribe-common summary,.tribe-common sup,.tribe-common table,.tribe-common tbody,.tribe-common td,.tribe-common tfoot,.tribe-common th,.tribe-common thead,.tribe-common time,.tribe-common tr,.tribe-common tt,.tribe-common u,.tribe-common ul,.tribe-common var,.tribe-common video{border:0;margin:0;padding:0}.tribe-common ol,.tribe-common ul{list-style:none}.tribe-common img{border-style:none;height:auto;-ms-interpolation-mode:bicubic;max-width:100%}.tribe-common embed,.tribe-common iframe,.tribe-common video{max-height:100%;max-width:100%}.tribe-theme-avada input[type=text]{margin:0}.tribe-theme-divi .entry-content .tribe-common table,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common table{border:0;margin:0}.tribe-theme-divi .entry-content .tribe-common td,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common td{border:0}.tribe-theme-divi #content-area .tribe-common td,.tribe-theme-divi #content-area .tribe-common th,.tribe-theme-divi #content-area .tribe-common tr,.tribe-theme-divi #left-area .tribe-common ul{padding:0}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{cursor:default}#top .main_color .tribe-common form,#top .main_color .tribe-common input,#top.tribe-theme-enfold .tribe-common form,#top.tribe-theme-enfold .tribe-common input{margin:0}.entry-content-wrapper .tribe-common li,.entry-content .tribe-common ol,.entry-content .tribe-common ul,.tribe-theme-genesis .tribe-common ol,.tribe-theme-genesis .tribe-common ul{margin:0;padding:0}.tribe-theme-twentynineteen .tribe-common svg{fill:none}.tribe-theme-twentyseventeen .tribe-common div.tribe-dialog{z-index:5!important}:root{--tec-grid-gutter:48px;--tec-grid-gutter-negative:calc(var(--tec-grid-gutter)*-1);--tec-grid-gutter-half:calc(var(--tec-grid-gutter)/2);--tec-grid-gutter-half-negative:calc(var(--tec-grid-gutter-half)*-1);--tec-grid-gutter-small:42px;--tec-grid-gutter-small-negative:calc(var(--tec-grid-gutter-small)*-1);--tec-grid-gutter-small-half:calc(var(--tec-grid-gutter-small)/2);--tec-grid-gutter-small-half-negative:calc(var(--tec-grid-gutter-small-half)*-1);--tec-grid-gutter-page:42px;--tec-grid-gutter-page-small:19.5px;--tec-grid-width-default:1176px;--tec-grid-width-min:320px;--tec-grid-width:calc(var(--tec-grid-width-default) + var(--tec-grid-gutter-page)*2);--tec-grid-width-1-of-2:50%;--tec-grid-width-1-of-3:33.333%;--tec-grid-width-1-of-4:25%;--tec-grid-width-1-of-5:20%;--tec-grid-width-1-of-7:14.285%;--tec-grid-width-1-of-8:12.5%;--tec-grid-width-1-of-9:11.111%;--grid-gutter:var(--tec-grid-gutter);--grid-gutter-negative:var(--tec-grid-gutter-negative);--grid-gutter-half:var(--tec-grid-gutter-half);--grid-gutter-half-negative:var(--tec-grid-gutter-half-negative);--grid-gutter-small:var(--tec-grid-gutter-small);--grid-gutter-small-negative:var(--tec-grid-gutter-small-negative);--grid-gutter-small-half:var(--tec-grid-gutter-small-half);--grid-gutter-small-half-negative:var(--tec-grid-gutter-small-half-negative);--grid-gutter-page:var(--tec-grid-gutter-page);--grid-gutter-page-small:var(--tec-grid-gutter-page-small);--grid-width-default:var(--tec-grid-width-default);--grid-width-min:var(--tec-grid-width-min);--grid-width:var(--tec-grid-width);--grid-width-1-of-2:var(--tec-grid-width-1-of-2);--grid-width-1-of-3:var(--tec-grid-width-1-of-3);--grid-width-1-of-4:var(--tec-grid-width-1-of-4);--grid-width-1-of-5:var(--tec-grid-width-1-of-5);--grid-width-1-of-7:var(--tec-grid-width-1-of-7);--grid-width-1-of-8:var(--tec-grid-width-1-of-8);--grid-width-1-of-9:var(--tec-grid-width-1-of-9);--tec-spacer-0:4px;--tec-spacer-1:8px;--tec-spacer-2:12px;--tec-spacer-3:16px;--tec-spacer-4:20px;--tec-spacer-5:24px;--tec-spacer-6:28px;--tec-spacer-7:32px;--tec-spacer-8:40px;--tec-spacer-9:48px;--tec-spacer-10:56px;--tec-spacer-11:64px;--tec-spacer-12:80px;--tec-spacer-13:96px;--tec-spacer-14:160px;--spacer-0:var(--tec-spacer-0);--spacer-1:var(--tec-spacer-1);--spacer-2:var(--tec-spacer-2);--spacer-3:var(--tec-spacer-3);--spacer-4:var(--tec-spacer-4);--spacer-5:var(--tec-spacer-5);--spacer-6:var(--tec-spacer-6);--spacer-7:var(--tec-spacer-7);--spacer-8:var(--tec-spacer-8);--spacer-9:var(--tec-spacer-9);--spacer-10:var(--tec-spacer-10);--spacer-11:var(--tec-spacer-11);--spacer-12:var(--tec-spacer-12);--spacer-13:var(--tec-spacer-13);--spacer-14:var(--tec-spacer-14);--tec-z-index-spinner-container:100;--tec-z-index-views-selector:30;--tec-z-index-dropdown:30;--tec-z-index-events-bar-button:20;--tec-z-index-search:10;--tec-z-index-filters:9;--tec-z-index-scroller:7;--tec-z-index-week-event-hover:5;--tec-z-index-map-event-hover:5;--tec-z-index-map-event-hover-actions:6;--tec-z-index-multiday-event:5;--tec-z-index-multiday-event-bar:2;--z-index-spinner-container:var(--tec-z-index-spinner-container);--z-index-views-selector:var(--tec-z-index-views-selector);--z-index-dropdown:var(--tec-z-index-dropdown);--z-index-events-bar-button:var(--tec-z-index-events-bar-button);--z-index-search:var(--tec-z-index-search);--z-index-filters:var(--tec-z-index-filters);--z-index-scroller:var(--tec-z-index-scroller);--z-index-week-event-hover:var(--tec-z-index-week-event-hover);--z-index-map-event-hover:var(--tec-z-index-map-event-hover);--z-index-map-event-hover-actions:var(--tec-z-index-map-event-hover-actions);--z-index-multiday-event:var(--tec-z-index-multiday-event);--z-index-multiday-event-bar:var(--tec-z-index-multiday-event-bar);--tec-color-text-primary:#141827;--tec-color-text-primary-light:rgba(20,24,39,.62);--tec-color-text-secondary:#5d5d5d;--tec-color-text-disabled:#d5d5d5;--tec-color-text-events-title:var(--tec-color-text-primary);--tec-color-text-event-title:var(--tec-color-text-events-title);--tec-color-text-event-date:var(--tec-color-text-primary);--tec-color-text-secondary-event-date:var(--tec-color-text-secondary);--tec-color-icon-primary:#5d5d5d;--tec-color-icon-primary-alt:#757575;--tec-color-icon-secondary:#bababa;--tec-color-icon-active:#141827;--tec-color-icon-disabled:#d5d5d5;--tec-color-icon-focus:#334aff;--tec-color-icon-error:#da394d;--tec-color-event-icon:#141827;--tec-color-event-icon-hover:#334aff;--tec-color-accent-primary:#334aff;--tec-color-accent-primary-hover:rgba(51,74,255,.8);--tec-color-accent-primary-active:rgba(51,74,255,.9);--tec-color-accent-primary-background:rgba(51,74,255,.07);--tec-color-accent-secondary:#141827;--tec-color-accent-secondary-hover:rgba(20,24,39,.8);--tec-color-accent-secondary-active:rgba(20,24,39,.9);--tec-color-accent-secondary-background:rgba(20,24,39,.07);--tec-color-button-primary:var(--tec-color-accent-primary);--tec-color-button-primary-hover:var(--tec-color-accent-primary-hover);--tec-color-button-primary-active:var(--tec-color-accent-primary-active);--tec-color-button-primary-background:var(--tec-color-accent-primary-background);--tec-color-button-secondary:var(--tec-color-accent-secondary);--tec-color-button-secondary-hover:var(--tec-color-accent-secondary-hover);--tec-color-button-secondary-active:var(--tec-color-accent-secondary-active);--tec-color-button-secondary-background:var(--tec-color-accent-secondary-background);--tec-color-link-primary:var(--tec-color-text-primary);--tec-color-link-accent-hover:rgba(51,74,255,.8);--tec-color-border-default:#d5d5d5;--tec-color-border-secondary:#e4e4e4;--tec-color-border-tertiary:#7d7d7d;--tec-color-border-hover:#5d5d5d;--tec-color-border-active:#141827;--tec-color-background:#fff;--tec-color-background-events:transparent;--tec-color-background-transparent:hsla(0,0%,100%,.6);--tec-color-background-secondary:#f7f6f6;--tec-color-background-messages:rgba(20,24,39,.07);--tec-color-background-secondary-hover:#f0eeee;--tec-color-background-error:rgba(218,57,77,.08);--tec-color-box-shadow:rgba(0,0,0,.14);--tec-color-box-shadow-secondary:rgba(0,0,0,.1);--tec-color-scroll-track:rgba(0,0,0,.25);--tec-color-scroll-bar:rgba(0,0,0,.5);--tec-color-background-primary-multiday:rgba(51,74,255,.24);--tec-color-background-primary-multiday-hover:rgba(51,74,255,.34);--tec-color-background-secondary-multiday:rgba(20,24,39,.24);--tec-color-background-secondary-multiday-hover:rgba(20,24,39,.34);--tec-color-accent-primary-week-event:rgba(51,74,255,.1);--tec-color-accent-primary-week-event-hover:rgba(51,74,255,.2);--tec-color-accent-primary-week-event-featured:rgba(51,74,255,.04);--tec-color-accent-primary-week-event-featured-hover:rgba(51,74,255,.14);--tec-color-background-secondary-datepicker:var(--tec-color-background-secondary);--tec-color-accent-primary-background-datepicker:var(--tec-color-accent-primary-background);--color-text-primary:var(--tec-color-text-primary);--color-text-primary-light:var(--tec-color-text-primary-light);--color-text-secondary:var(--tec-color-text-secondary);--color-text-disabled:var(--tec-color-text-disabled);--color-icon-primary:var(--tec-color-icon-primary);--color-icon-primary-alt:var(--tec-color-icon-primary);--color-icon-secondary:var(--tec-color-icon-secondary);--color-icon-active:var(--tec-color-icon-active);--color-icon-disabled:var(--tec-color-icon-disabled);--color-icon-focus:var(--tec-color-icon-focus);--color-icon-error:var(--tec-color-icon-error);--color-accent-primary:var(--tec-color-accent-primary);--color-accent-primary-hover:var(--tec-color-accent-primary-hover);--color-accent-primary-active:var(--tec-color-accent-primary-active);--color-accent-primary-background:var(--tec-color-accent-primary-background);--color-accent-primary-multiday:var(--tec-color-accent-primary-multiday);--color-accent-primary-multiday-hover:var(--tec-color-accent-primary-multiday-hover);--color-accent-primary-week-event:var(--tec-color-accent-primary-week-event);--color-accent-primary-week-event-hover:var(--tec-color-accent-primary-week-event-hover);--color-accent-primary-week-event-featured:var(--tec-color-accent-primary-week-event-featured);--color-accent-primary-week-event-featured-hover:var(--tec-color-accent-primary-week-event-featured-hover);--color-accent-secondary:var(--tec-color-accent-secondary);--color-accent-secondary-hover:var(--tec-color-accent-secondary-hover);--color-accent-secondary-active:var(--tec-color-accent-secondary-active);--color-accent-secondary-background:var(--tec-color-accent-secondary-background);--color-border-default:var(--tec-color-border-default);--color-border-secondary:var(--tec-color-border-secondary);--color-border-tertiary:var(--tec-color-border-tertiary);--color-border-hover:var(--tec-color-border-hover);--color-border-active:var(--tec-color-border-active);--color-background:var(--tec-color-background);--color-background-transparent:var(--tec-color-background-transparent);--color-background-secondary:var(--tec-color-background-secondary);--color-background-messages:var(--tec-color-background-messages);--color-background-secondary-hover:var(--tec-color-background-secondary-hover);--color-background-error:var(--tec-color-icon-error);--color-box-shadow:var(--tec-color-box-shadow);--color-box-shadow-secondary:var(--tec-color-box-shadow-secondary);--color-scroll-track:var(--tec-color-scroll-track);--color-scroll-bar:var(--tec-color-scroll-bar)}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{align-items:flex-start;display:flex}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{cursor:pointer;margin-left:15px}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{cursor:pointer;flex:none;margin:1px 0 0}#top .main_color .tribe-common .tribe-common-form-control-checkbox__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__input{margin:1px 0 0}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-checkbox__input{top:0}.tribe-theme-twentytwentyone .tribe-common .tribe-common-form-control-checkbox__input:checked:after{border:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-form-control-radio__input:checked:after{background-color:transparent}.tribe-common .tribe-common-form-control-checkbox-radio-group>*{margin-bottom:15px}.tribe-common .tribe-common-form-control-checkbox-radio-group>:last-child{margin-bottom:0}.tribe-common .tribe-common-form-control-slider__input{cursor:pointer;display:inline-block;margin:0;padding:0;vertical-align:middle;width:120px}.tribe-common .tribe-common-form-control-slider__label{cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider--vertical .tribe-common-form-control-slider__label{display:block;margin:0 0 6px}.tribe-common .tribe-common-form-control-text__label{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-form-control-text__input{height:auto;padding:12px 28px 12px 0;padding:var(--tec-spacer-2) var(--tec-spacer-6) var(--tec-spacer-2) 0;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{padding:20px 20px 20px 40px;padding:var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-8)}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{padding:12px 28px 12px 0;padding:var(--tec-spacer-2) var(--tec-spacer-6) var(--tec-spacer-2) 0;width:100%}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{padding:20px 20px 20px 40px;padding:var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-8)}.tribe-common .tribe-common-form-control-toggle__input,.tribe-common .tribe-common-form-control-toggle__label{cursor:pointer;display:inline-block;vertical-align:middle}.tribe-common .tribe-common-form-control-toggle__label{margin-left:11px}.tribe-common .tribe-common-form-control-toggle--vertical .tribe-common-form-control-toggle__label{display:block;margin:0 0 6px}#top .main_color .tribe-common .tribe-common-form-control-toggle__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__input{display:inline-block;margin:5px 0}.tribe-common .tribe-common-g-col{min-width:0;width:100%}.tribe-common .tribe-common-g-row{display:flex;flex-wrap:wrap}.tribe-common .tribe-common-g-row--gutters{margin-left:-21px;margin-left:var(--tec-grid-gutter-small-half-negative);margin-right:-21px;margin-right:var(--tec-grid-gutter-small-half-negative)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-g-row--gutters{margin-left:-24px;margin-left:var(--tec-grid-gutter-half-negative);margin-right:-24px;margin-right:var(--tec-grid-gutter-half-negative)}.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:21px;padding-left:var(--tec-grid-gutter-small-half);padding-right:21px;padding-right:var(--tec-grid-gutter-small-half)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:24px;padding-left:var(--tec-grid-gutter-half);padding-right:24px;padding-right:var(--tec-grid-gutter-half)}.tribe-theme-twentynineteen .tribe-common .entry.tribe-common-g-row--gutters{margin-left:-21px;margin-left:var(--tec-grid-gutter-small-half-negative);margin-right:-21px;margin-right:var(--tec-grid-gutter-small-half-negative);padding:0}.tribe-theme-twentynineteen .tribe-common.tribe-common--breakpoint-medium .entry.tribe-common-g-row--gutters{margin-left:-24px;margin-left:var(--tec-grid-gutter-half-negative);margin-right:-24px;margin-right:var(--tec-grid-gutter-half-negative)}.tribe-theme-twentynineteen .tribe-common .tribe-common-g-row--gutters>.entry.tribe-common-g-col{margin:0;padding-left:21px;padding-left:var(--tec-grid-gutter-small-half);padding-right:21px;padding-right:var(--tec-grid-gutter-small-half)}.tribe-theme-twentynineteen .tribe-common.tribe-common--breakpoint-medium .tribe-common-g-row--gutters>.entry.tribe-common-g-col{padding-left:24px;padding-left:var(--tec-grid-gutter-half);padding-right:24px;padding-right:var(--tec-grid-gutter-half)}.tribe-common a{cursor:pointer}.tribe-theme-divi #left-area .tribe-common ul,.tribe-theme-divi .entry-content .tribe-common ul,body.et-pb-preview.tribe-theme-divi #main-content .container .tribe-common ul{list-style-type:none;padding:0}.entry-content .tribe-common ol>li,.entry-content .tribe-common ul>li{list-style-type:none}.tribe-common button{padding:0}.tribe-common .tribe-common-l-container{margin-left:auto;margin-right:auto;max-width:1260px;max-width:var(--tec-grid-width);padding-left:19.5px;padding-left:var(--tec-grid-gutter-page-small);padding-right:19.5px;padding-right:var(--tec-grid-gutter-page-small);width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-l-container{padding-left:42px;padding-left:var(--tec-grid-gutter-page);padding-right:42px;padding-right:var(--tec-grid-gutter-page)}.tribe-common .tribe-common-a11y-hidden{display:none!important;visibility:hidden}.tribe-common .tribe-common-a11y-visual-hide{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-a11y-visual-show{clip:auto;height:auto;margin:0;position:static;width:auto}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{width:auto}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{padding:14px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border-small,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border-small{padding:6px 15px;width:auto}.tribe-common .tribe-common-c-btn-icon:before{background-repeat:no-repeat;background-size:contain;content:"";display:block}.tribe-common .tribe-common-c-btn-icon--caret-left .tribe-common-c-btn-icon__icon-svg,.tribe-common .tribe-common-c-btn-icon--caret-right .tribe-common-c-btn-icon__icon-svg{width:11px}.tribe-common .tribe-common-c-btn-icon--caret-left .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right .tribe-common-c-btn-icon__icon-svg path{fill:currentColor}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-image{display:block;height:auto;margin-left:auto;margin-right:auto;width:100%}.tribe-common .tribe-common-c-image--bg{position:relative}.tribe-common .tribe-common-c-image__bg{background:50% no-repeat;background-size:cover;bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.tribe-common .tribe-common-c-loader{display:flex;padding-top:192px;padding-top:calc(var(--tec-spacer-11)*3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-loader{padding-top:288px;padding-top:calc(var(--tec-spacer-13)*3)}.tribe-common .tribe-common-c-loader__dot{width:15px}.tribe-common .tribe-common-c-loader__dot:not(:first-of-type){margin-left:8px}.tribe-common .tribe-common-c-loader__dot circle{fill:currentColor}.tribe-common .tribe-common-c-svgicon--featured{width:8px}.tribe-common .tribe-common-c-svgicon--recurring{width:12px}.tribe-common .tribe-common-c-svgicon--search{width:16px}.tribe-common .tribe-common-c-svgicon--location{width:10px}.tribe-common .tribe-common-c-svgicon--day,.tribe-common .tribe-common-c-svgicon--map,.tribe-common .tribe-common-c-svgicon--month,.tribe-common .tribe-common-c-svgicon--photo,.tribe-common .tribe-common-c-svgicon--week{height:100%;width:100%}.tribe-common .tribe-common-c-svgicon--close-alt path,.tribe-common .tribe-common-c-svgicon--close path{stroke:currentColor}.tribe-common .tribe-common-c-svgicon--hybrid circle,.tribe-common .tribe-common-c-svgicon--mail,.tribe-common .tribe-common-c-svgicon--map-pin,.tribe-common .tribe-common-c-svgicon--messages-not-found g,.tribe-common .tribe-common-c-svgicon--no-map,.tribe-common .tribe-common-c-svgicon--phone,.tribe-common .tribe-common-c-svgicon--virtual g,.tribe-common .tribe-common-c-svgicon--website{fill:none}.tribe-common .tribe-common-c-svgicon--messages-not-found{width:22px}.tribe-common .tribe-common-c-svgicon--messages-not-found path{stroke:currentColor}.tribe-common .tribe-common-c-svgicon--error{width:18px}.tribe-common .tribe-common-c-svgicon--error g,.tribe-common .tribe-common-c-svgicon--reset path{fill:none}.tribe-common .tribe-common-c-svgicon__svg-fill{fill:currentColor}.tribe-common .tribe-common-c-svgicon__svg-stroke{stroke:currentColor}
|
1 |
+
.tribe-common{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smoothing:antialiased}.tribe-common *{box-sizing:border-box}.tribe-common article,.tribe-common aside,.tribe-common details,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common header,.tribe-common main,.tribe-common menu,.tribe-common nav,.tribe-common section,.tribe-common summary{display:block}.tribe-common svg:not(:root){overflow:hidden}.tribe-common audio,.tribe-common canvas,.tribe-common progress,.tribe-common video{display:inline-block}.tribe-common audio:not([controls]){display:none;height:0}.tribe-common progress{vertical-align:baseline}.tribe-common [hidden],.tribe-common template{display:none}.tribe-common pre{overflow:auto}.tribe-common sub,.tribe-common sup{position:relative;vertical-align:baseline}.tribe-common sup{top:-.5em}.tribe-common sub{bottom:-.25em}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{box-sizing:border-box;margin:0}.tribe-common input[type=number]::-webkit-inner-spin-button,.tribe-common input[type=number]::-webkit-outer-spin-button{height:auto}.tribe-common legend{color:inherit;display:table;max-width:100%;white-space:normal}.tribe-common textarea{overflow:auto;resize:none}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=reset],.tribe-common input[type=submit]{cursor:pointer;overflow:visible}.tribe-common button[disabled],.tribe-common input[disabled]{cursor:default}.tribe-common button::-moz-focus-inner,.tribe-common input::-moz-focus-inner{border:0;padding:0}.tribe-common a,.tribe-common abbr,.tribe-common acronym,.tribe-common address,.tribe-common applet,.tribe-common article,.tribe-common aside,.tribe-common audio,.tribe-common b,.tribe-common big,.tribe-common blockquote,.tribe-common canvas,.tribe-common caption,.tribe-common center,.tribe-common cite,.tribe-common code,.tribe-common dd,.tribe-common del,.tribe-common details,.tribe-common dfn,.tribe-common div,.tribe-common dl,.tribe-common dt,.tribe-common em,.tribe-common embed,.tribe-common fieldset,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common form,.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common header,.tribe-common i,.tribe-common iframe,.tribe-common img,.tribe-common ins,.tribe-common kbd,.tribe-common label,.tribe-common legend,.tribe-common li,.tribe-common main,.tribe-common mark,.tribe-common menu,.tribe-common nav,.tribe-common object,.tribe-common ol,.tribe-common output,.tribe-common p,.tribe-common pre,.tribe-common q,.tribe-common ruby,.tribe-common s,.tribe-common samp,.tribe-common section,.tribe-common small,.tribe-common span,.tribe-common strike,.tribe-common strong,.tribe-common sub,.tribe-common summary,.tribe-common sup,.tribe-common table,.tribe-common tbody,.tribe-common td,.tribe-common tfoot,.tribe-common th,.tribe-common thead,.tribe-common time,.tribe-common tr,.tribe-common tt,.tribe-common u,.tribe-common ul,.tribe-common var,.tribe-common video{border:0;margin:0;padding:0}.tribe-common ol,.tribe-common ul{list-style:none}.tribe-common img{border-style:none;height:auto;-ms-interpolation-mode:bicubic;max-width:100%}.tribe-common embed,.tribe-common iframe,.tribe-common video{max-height:100%;max-width:100%}.tribe-theme-avada input[type=text]{margin:0}.tribe-theme-divi .entry-content .tribe-common table,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common table{border:0;margin:0}.tribe-theme-divi .entry-content .tribe-common td,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common td{border:0}.tribe-theme-divi #content-area .tribe-common td,.tribe-theme-divi #content-area .tribe-common th,.tribe-theme-divi #content-area .tribe-common tr,.tribe-theme-divi #left-area .tribe-common ul{padding:0}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{cursor:default}#top .main_color .tribe-common form,#top .main_color .tribe-common input,#top.tribe-theme-enfold .tribe-common form,#top.tribe-theme-enfold .tribe-common input{margin:0}.entry-content-wrapper .tribe-common li,.entry-content .tribe-common ol,.entry-content .tribe-common ul,.tribe-theme-genesis .tribe-common ol,.tribe-theme-genesis .tribe-common ul{margin:0;padding:0}.tribe-theme-twentynineteen .tribe-common svg{fill:none}.tribe-theme-twentyseventeen .tribe-common div.tribe-dialog{z-index:5!important}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{align-items:flex-start;display:flex}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{cursor:pointer;margin-left:15px}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{cursor:pointer;flex:none;margin:1px 0 0}#top .main_color .tribe-common .tribe-common-form-control-checkbox__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__input{margin:1px 0 0}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-checkbox__input{top:0}.tribe-theme-twentytwentyone .tribe-common .tribe-common-form-control-checkbox__input:checked:after{border:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-form-control-radio__input:checked:after{background-color:transparent}.tribe-common .tribe-common-form-control-checkbox-radio-group>*{margin-bottom:15px}.tribe-common .tribe-common-form-control-checkbox-radio-group>:last-child{margin-bottom:0}.tribe-common .tribe-common-form-control-slider__input{cursor:pointer;display:inline-block;margin:0;padding:0;vertical-align:middle;width:120px}.tribe-common .tribe-common-form-control-slider__label{cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider--vertical .tribe-common-form-control-slider__label{display:block;margin:0 0 6px}.tribe-common .tribe-common-form-control-text__label{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-form-control-text__input{height:auto;padding:var(--tec-spacer-2) var(--tec-spacer-6) var(--tec-spacer-2) 0;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{padding:var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-8)}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{padding:var(--tec-spacer-2) var(--tec-spacer-6) var(--tec-spacer-2) 0;width:100%}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{padding:var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-8)}.tribe-common .tribe-common-form-control-toggle__input,.tribe-common .tribe-common-form-control-toggle__label{cursor:pointer;display:inline-block;vertical-align:middle}.tribe-common .tribe-common-form-control-toggle__label{margin-left:11px}.tribe-common .tribe-common-form-control-toggle--vertical .tribe-common-form-control-toggle__label{display:block;margin:0 0 6px}#top .main_color .tribe-common .tribe-common-form-control-toggle__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__input{display:inline-block;margin:5px 0}.tribe-common .tribe-common-g-col{min-width:0;width:100%}.tribe-common .tribe-common-g-row{display:flex;flex-wrap:wrap}.tribe-common .tribe-common-g-row--gutters{margin-left:var(--tec-grid-gutter-small-half-negative);margin-right:var(--tec-grid-gutter-small-half-negative)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-g-row--gutters{margin-left:var(--tec-grid-gutter-half-negative);margin-right:var(--tec-grid-gutter-half-negative)}.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:var(--tec-grid-gutter-small-half);padding-right:var(--tec-grid-gutter-small-half)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:var(--tec-grid-gutter-half);padding-right:var(--tec-grid-gutter-half)}.tribe-theme-twentynineteen .tribe-common .entry.tribe-common-g-row--gutters{margin-left:var(--tec-grid-gutter-small-half-negative);margin-right:var(--tec-grid-gutter-small-half-negative);padding:0}.tribe-theme-twentynineteen .tribe-common.tribe-common--breakpoint-medium .entry.tribe-common-g-row--gutters{margin-left:var(--tec-grid-gutter-half-negative);margin-right:var(--tec-grid-gutter-half-negative)}.tribe-theme-twentynineteen .tribe-common .tribe-common-g-row--gutters>.entry.tribe-common-g-col{margin:0;padding-left:var(--tec-grid-gutter-small-half);padding-right:var(--tec-grid-gutter-small-half)}.tribe-theme-twentynineteen .tribe-common.tribe-common--breakpoint-medium .tribe-common-g-row--gutters>.entry.tribe-common-g-col{padding-left:var(--tec-grid-gutter-half);padding-right:var(--tec-grid-gutter-half)}.tribe-common a{cursor:pointer}.tribe-theme-divi #left-area .tribe-common ul,.tribe-theme-divi .entry-content .tribe-common ul,body.et-pb-preview.tribe-theme-divi #main-content .container .tribe-common ul{list-style-type:none;padding:0}.entry-content .tribe-common ol>li,.entry-content .tribe-common ul>li{list-style-type:none}.tribe-common button{padding:0}.tribe-common .tribe-common-l-container{margin-left:auto;margin-right:auto;max-width:var(--tec-grid-width);padding-left:var(--tec-grid-gutter-page-small);padding-right:var(--tec-grid-gutter-page-small);width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-l-container{padding-left:var(--tec-grid-gutter-page);padding-right:var(--tec-grid-gutter-page)}.tribe-common .tribe-common-a11y-hidden{display:none!important;visibility:hidden}.tribe-common .tribe-common-a11y-visual-hide{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-a11y-visual-show{clip:auto;height:auto;margin:0;position:static;width:auto}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{width:auto}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{padding:14px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border-small,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border-small{padding:6px 15px;width:auto}.tribe-common .tribe-common-c-btn-icon:before{background-repeat:no-repeat;background-size:contain;content:"";display:block}.tribe-common .tribe-common-c-btn-icon--caret-left .tribe-common-c-btn-icon__icon-svg,.tribe-common .tribe-common-c-btn-icon--caret-right .tribe-common-c-btn-icon__icon-svg{width:11px}.tribe-common .tribe-common-c-btn-icon--caret-left .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right .tribe-common-c-btn-icon__icon-svg path{fill:currentColor}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-image{display:block;height:auto;margin-left:auto;margin-right:auto;width:100%}.tribe-common .tribe-common-c-image--bg{position:relative}.tribe-common .tribe-common-c-image__bg{background:50% no-repeat;background-size:cover;bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.tribe-common .tribe-common-c-loader{display:flex;padding-top:calc(var(--tec-spacer-11)*3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-loader{padding-top:calc(var(--tec-spacer-13)*3)}.tribe-common .tribe-common-c-loader__dot{width:15px}.tribe-common .tribe-common-c-loader__dot:not(:first-of-type){margin-left:8px}.tribe-common .tribe-common-c-loader__dot circle{fill:currentColor}.tribe-common .tribe-common-c-svgicon--featured{width:8px}.tribe-common .tribe-common-c-svgicon--recurring{width:12px}.tribe-common .tribe-common-c-svgicon--search{width:16px}.tribe-common .tribe-common-c-svgicon--location{width:10px}.tribe-common .tribe-common-c-svgicon--day,.tribe-common .tribe-common-c-svgicon--map,.tribe-common .tribe-common-c-svgicon--month,.tribe-common .tribe-common-c-svgicon--photo,.tribe-common .tribe-common-c-svgicon--week{height:100%;width:100%}.tribe-common .tribe-common-c-svgicon--close-alt path,.tribe-common .tribe-common-c-svgicon--close path{stroke:currentColor}.tribe-common .tribe-common-c-svgicon--hybrid circle,.tribe-common .tribe-common-c-svgicon--mail,.tribe-common .tribe-common-c-svgicon--map-pin,.tribe-common .tribe-common-c-svgicon--messages-not-found g,.tribe-common .tribe-common-c-svgicon--no-map,.tribe-common .tribe-common-c-svgicon--phone,.tribe-common .tribe-common-c-svgicon--virtual g,.tribe-common .tribe-common-c-svgicon--website{fill:none}.tribe-common .tribe-common-c-svgicon--messages-not-found{width:22px}.tribe-common .tribe-common-c-svgicon--messages-not-found path{stroke:currentColor}.tribe-common .tribe-common-c-svgicon--error{width:18px}.tribe-common .tribe-common-c-svgicon--error g,.tribe-common .tribe-common-c-svgicon--reset path{fill:none}.tribe-common .tribe-common-c-svgicon__svg-fill{fill:currentColor}.tribe-common .tribe-common-c-svgicon__svg-stroke{stroke:currentColor}
|
common/src/resources/css/customizer-controls.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
:root{--tec-grid-gutter:48px;--tec-grid-gutter-negative:calc(var(--tec-grid-gutter)*-1);--tec-grid-gutter-half:calc(var(--tec-grid-gutter)/2);--tec-grid-gutter-half-negative:calc(var(--tec-grid-gutter-half)*-1);--tec-grid-gutter-small:42px;--tec-grid-gutter-small-negative:calc(var(--tec-grid-gutter-small)*-1);--tec-grid-gutter-small-half:calc(var(--tec-grid-gutter-small)/2);--tec-grid-gutter-small-half-negative:calc(var(--tec-grid-gutter-small-half)*-1);--tec-grid-gutter-page:42px;--tec-grid-gutter-page-small:19.5px;--tec-grid-width-default:1176px;--tec-grid-width-min:320px;--tec-grid-width:calc(var(--tec-grid-width-default) + var(--tec-grid-gutter-page)*2);--tec-grid-width-1-of-2:50%;--tec-grid-width-1-of-3:33.333%;--tec-grid-width-1-of-4:25%;--tec-grid-width-1-of-5:20%;--tec-grid-width-1-of-7:14.285%;--tec-grid-width-1-of-8:12.5%;--tec-grid-width-1-of-9:11.111%;--grid-gutter:var(--tec-grid-gutter);--grid-gutter-negative:var(--tec-grid-gutter-negative);--grid-gutter-half:var(--tec-grid-gutter-half);--grid-gutter-half-negative:var(--tec-grid-gutter-half-negative);--grid-gutter-small:var(--tec-grid-gutter-small);--grid-gutter-small-negative:var(--tec-grid-gutter-small-negative);--grid-gutter-small-half:var(--tec-grid-gutter-small-half);--grid-gutter-small-half-negative:var(--tec-grid-gutter-small-half-negative);--grid-gutter-page:var(--tec-grid-gutter-page);--grid-gutter-page-small:var(--tec-grid-gutter-page-small);--grid-width-default:var(--tec-grid-width-default);--grid-width-min:var(--tec-grid-width-min);--grid-width:var(--tec-grid-width);--grid-width-1-of-2:var(--tec-grid-width-1-of-2);--grid-width-1-of-3:var(--tec-grid-width-1-of-3);--grid-width-1-of-4:var(--tec-grid-width-1-of-4);--grid-width-1-of-5:var(--tec-grid-width-1-of-5);--grid-width-1-of-7:var(--tec-grid-width-1-of-7);--grid-width-1-of-8:var(--tec-grid-width-1-of-8);--grid-width-1-of-9:var(--tec-grid-width-1-of-9);--tec-spacer-0:4px;--tec-spacer-1:8px;--tec-spacer-2:12px;--tec-spacer-3:16px;--tec-spacer-4:20px;--tec-spacer-5:24px;--tec-spacer-6:28px;--tec-spacer-7:32px;--tec-spacer-8:40px;--tec-spacer-9:48px;--tec-spacer-10:56px;--tec-spacer-11:64px;--tec-spacer-12:80px;--tec-spacer-13:96px;--tec-spacer-14:160px;--spacer-0:var(--tec-spacer-0);--spacer-1:var(--tec-spacer-1);--spacer-2:var(--tec-spacer-2);--spacer-3:var(--tec-spacer-3);--spacer-4:var(--tec-spacer-4);--spacer-5:var(--tec-spacer-5);--spacer-6:var(--tec-spacer-6);--spacer-7:var(--tec-spacer-7);--spacer-8:var(--tec-spacer-8);--spacer-9:var(--tec-spacer-9);--spacer-10:var(--tec-spacer-10);--spacer-11:var(--tec-spacer-11);--spacer-12:var(--tec-spacer-12);--spacer-13:var(--tec-spacer-13);--spacer-14:var(--tec-spacer-14);--tec-z-index-spinner-container:100;--tec-z-index-views-selector:30;--tec-z-index-dropdown:30;--tec-z-index-events-bar-button:20;--tec-z-index-search:10;--tec-z-index-filters:9;--tec-z-index-scroller:7;--tec-z-index-week-event-hover:5;--tec-z-index-map-event-hover:5;--tec-z-index-map-event-hover-actions:6;--tec-z-index-multiday-event:5;--tec-z-index-multiday-event-bar:2;--z-index-spinner-container:var(--tec-z-index-spinner-container);--z-index-views-selector:var(--tec-z-index-views-selector);--z-index-dropdown:var(--tec-z-index-dropdown);--z-index-events-bar-button:var(--tec-z-index-events-bar-button);--z-index-search:var(--tec-z-index-search);--z-index-filters:var(--tec-z-index-filters);--z-index-scroller:var(--tec-z-index-scroller);--z-index-week-event-hover:var(--tec-z-index-week-event-hover);--z-index-map-event-hover:var(--tec-z-index-map-event-hover);--z-index-map-event-hover-actions:var(--tec-z-index-map-event-hover-actions);--z-index-multiday-event:var(--tec-z-index-multiday-event);--z-index-multiday-event-bar:var(--tec-z-index-multiday-event-bar);--tec-color-text-primary:#141827;--tec-color-text-primary-light:rgba(20,24,39,.62);--tec-color-text-secondary:#5d5d5d;--tec-color-text-disabled:#d5d5d5;--tec-color-text-events-title:var(--tec-color-text-primary);--tec-color-text-event-title:var(--tec-color-text-events-title);--tec-color-text-event-date:var(--tec-color-text-primary);--tec-color-text-secondary-event-date:var(--tec-color-text-secondary);--tec-color-icon-primary:#5d5d5d;--tec-color-icon-primary-alt:#757575;--tec-color-icon-secondary:#bababa;--tec-color-icon-active:#141827;--tec-color-icon-disabled:#d5d5d5;--tec-color-icon-focus:#334aff;--tec-color-icon-error:#da394d;--tec-color-event-icon:#141827;--tec-color-event-icon-hover:#334aff;--tec-color-accent-primary:#334aff;--tec-color-accent-primary-hover:rgba(51,74,255,.8);--tec-color-accent-primary-active:rgba(51,74,255,.9);--tec-color-accent-primary-background:rgba(51,74,255,.07);--tec-color-accent-secondary:#141827;--tec-color-accent-secondary-hover:rgba(20,24,39,.8);--tec-color-accent-secondary-active:rgba(20,24,39,.9);--tec-color-accent-secondary-background:rgba(20,24,39,.07);--tec-color-button-primary:var(--tec-color-accent-primary);--tec-color-button-primary-hover:var(--tec-color-accent-primary-hover);--tec-color-button-primary-active:var(--tec-color-accent-primary-active);--tec-color-button-primary-background:var(--tec-color-accent-primary-background);--tec-color-button-secondary:var(--tec-color-accent-secondary);--tec-color-button-secondary-hover:var(--tec-color-accent-secondary-hover);--tec-color-button-secondary-active:var(--tec-color-accent-secondary-active);--tec-color-button-secondary-background:var(--tec-color-accent-secondary-background);--tec-color-link-primary:var(--tec-color-text-primary);--tec-color-link-accent-hover:rgba(51,74,255,.8);--tec-color-border-default:#d5d5d5;--tec-color-border-secondary:#e4e4e4;--tec-color-border-tertiary:#7d7d7d;--tec-color-border-hover:#5d5d5d;--tec-color-border-active:#141827;--tec-color-background:#fff;--tec-color-background-events:transparent;--tec-color-background-transparent:hsla(0,0%,100%,.6);--tec-color-background-secondary:#f7f6f6;--tec-color-background-messages:rgba(20,24,39,.07);--tec-color-background-secondary-hover:#f0eeee;--tec-color-background-error:rgba(218,57,77,.08);--tec-color-box-shadow:rgba(0,0,0,.14);--tec-color-box-shadow-secondary:rgba(0,0,0,.1);--tec-color-scroll-track:rgba(0,0,0,.25);--tec-color-scroll-bar:rgba(0,0,0,.5);--tec-color-background-primary-multiday:rgba(51,74,255,.24);--tec-color-background-primary-multiday-hover:rgba(51,74,255,.34);--tec-color-background-secondary-multiday:rgba(20,24,39,.24);--tec-color-background-secondary-multiday-hover:rgba(20,24,39,.34);--tec-color-accent-primary-week-event:rgba(51,74,255,.1);--tec-color-accent-primary-week-event-hover:rgba(51,74,255,.2);--tec-color-accent-primary-week-event-featured:rgba(51,74,255,.04);--tec-color-accent-primary-week-event-featured-hover:rgba(51,74,255,.14);--tec-color-background-secondary-datepicker:var(--tec-color-background-secondary);--tec-color-accent-primary-background-datepicker:var(--tec-color-accent-primary-background);--color-text-primary:var(--tec-color-text-primary);--color-text-primary-light:var(--tec-color-text-primary-light);--color-text-secondary:var(--tec-color-text-secondary);--color-text-disabled:var(--tec-color-text-disabled);--color-icon-primary:var(--tec-color-icon-primary);--color-icon-primary-alt:var(--tec-color-icon-primary);--color-icon-secondary:var(--tec-color-icon-secondary);--color-icon-active:var(--tec-color-icon-active);--color-icon-disabled:var(--tec-color-icon-disabled);--color-icon-focus:var(--tec-color-icon-focus);--color-icon-error:var(--tec-color-icon-error);--color-accent-primary:var(--tec-color-accent-primary);--color-accent-primary-hover:var(--tec-color-accent-primary-hover);--color-accent-primary-active:var(--tec-color-accent-primary-active);--color-accent-primary-background:var(--tec-color-accent-primary-background);--color-accent-primary-multiday:var(--tec-color-accent-primary-multiday);--color-accent-primary-multiday-hover:var(--tec-color-accent-primary-multiday-hover);--color-accent-primary-week-event:var(--tec-color-accent-primary-week-event);--color-accent-primary-week-event-hover:var(--tec-color-accent-primary-week-event-hover);--color-accent-primary-week-event-featured:var(--tec-color-accent-primary-week-event-featured);--color-accent-primary-week-event-featured-hover:var(--tec-color-accent-primary-week-event-featured-hover);--color-accent-secondary:var(--tec-color-accent-secondary);--color-accent-secondary-hover:var(--tec-color-accent-secondary-hover);--color-accent-secondary-active:var(--tec-color-accent-secondary-active);--color-accent-secondary-background:var(--tec-color-accent-secondary-background);--color-border-default:var(--tec-color-border-default);--color-border-secondary:var(--tec-color-border-secondary);--color-border-tertiary:var(--tec-color-border-tertiary);--color-border-hover:var(--tec-color-border-hover);--color-border-active:var(--tec-color-border-active);--color-background:var(--tec-color-background);--color-background-transparent:var(--tec-color-background-transparent);--color-background-secondary:var(--tec-color-background-secondary);--color-background-messages:var(--tec-color-background-messages);--color-background-secondary-hover:var(--tec-color-background-secondary-hover);--color-background-error:var(--tec-color-icon-error);--color-box-shadow:var(--tec-color-box-shadow);--color-box-shadow-secondary:var(--tec-color-box-shadow-secondary);--color-scroll-track:var(--tec-color-scroll-track);--color-scroll-bar:var(--tec-color-scroll-bar);--tec-border-radius-default:4px;--tec-border-width-week-event:2px;--border-radius-default:var(--tec-border-radius-default);--border-width-week-event:var(--tec-border-width-week-event);--tec-box-shadow-default:0 2px 5px 0 var(--tec-color-box-shadow);--tec-box-shadow-tooltip:0 2px 12px 0 var(--tec-color-box-shadow);--tec-box-shadow-card:0 1px 6px 2px var(--tec-color-box-shadow);--tec-box-shadow-multiday:16px 6px 6px -2px var(--tec-color-box-shadow-secondary);--box-shadow-default:var(--tec-box-shadow-default);--box-shadow-tooltip:var(--tec-box-shadow-tooltip);--box-shadow-card:var(--tec-box-shadow-card);--box-shadow-multiday:var(--tec-box-shadow-multiday);--tec-form-color-background:var(--tec-color-background);--tec-form-color-border-default:var(--tec-color-text-primary);--tec-form-color-border-active:var(--tec-color-accent-secondary);--tec-form-color-border-secondary:var(--tec-color-border-tertiary);--tec-form-color-accent-primary:var(--tec-color-accent-primary);--tec-form-box-shadow-default:var(--tec-box-shadow-default);--form-color-background:var(--tec-form-color-background);--form-color-border-default:var(--tec-form-color-border-default);--form-color-border-active:var(--tec-form-color-border-active);--form-color-border-secondary:var(--tec-form-color-border-secondary);--form-color-accent-primary:var(--tec-form-color-accent-primary);--form-box-shadow-default:var(--tec-form-box-shadow-default);--tec-opacity-background:0.07;--tec-opacity-select-highlighted:0.3;--tec-opacity-icon-hover:0.8;--tec-opacity-icon-active:0.9;--tec-opacity-default:1;--opacity-background:var(--tec-opacity-background);--opacity-select-highlighted:var(--tec-opacity-select-highlighted);--opacity-icon-hover:var(--tec-opacity-icon-hover);--opacity-icon-active:var(--tec-opacity-icon-active);--opacity-default:var(--tec-opacity-default);--tec-transition:all 0.2s ease;--tec-transition-background-color:background-color 0.2s ease;--tec-transition-color-border-color:color 0.2s ease,border-color 0.2s ease;--tec-transition-transform:transform 0.2s ease;--tec-transition-border-color:border-color 0.2s ease;--tec-transition-color:color 0.2s ease;--tec-transition-opacity:opacity 0.2s ease;--transition:var(--tec-transition);--transition-background-color:var(--tec-transition-background-color);--transition-color-border-color:var(--tec-transition-color-border-color);--transition-transform:var(--tec-transition-transform);--transition-border-color:var(--tec-transition-border-color);--transition-color:var(--tec-transition-color);--transition-opacity:var(--tec-transition-opacity);--tec-font-family-sans-serif:"Helvetica Neue",Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;--tec-font-weight-regular:400;--tec-font-weight-bold:700;--tec-font-size-0:11px;--tec-font-size-1:12px;--tec-font-size-2:14px;--tec-font-size-3:16px;--tec-font-size-4:18px;--tec-font-size-5:20px;--tec-font-size-6:22px;--tec-font-size-7:24px;--tec-font-size-8:28px;--tec-font-size-9:32px;--tec-font-size-10:42px;--tec-line-height-0:1.38;--tec-line-height-1:1.42;--tec-line-height-2:1.5;--tec-line-height-3:1.62;--font-family-sans-serif:var(--tec-font-family-sans-serif);--font-family-base:var(--tec-font-family-sans-serif);--font-weight-regular:var(--tec-font-weight-regular);--font-weight-bold:var(--tec-font-weight-bold);--font-size-0:var(--tec-font-size-0);--font-size-1:var(--tec-font-size-1);--font-size-2:var(--tec-font-size-2);--font-size-3:var(--tec-font-size-3);--font-size-4:var(--tec-font-size-4);--font-size-5:var(--tec-font-size-5);--font-size-6:var(--tec-font-size-6);--font-size-7:var(--tec-font-size-7);--font-size-8:var(--tec-font-size-8);--font-size-9:var(--tec-font-size-9);--font-size-10:var(--tec-font-size-10);--line-height-0:var(--tec-line-height-0);--line-height-1:var(--tec-line-height-1);--line-height-2:var(--tec-line-height-2);--line-height-3:var(--tec-line-height-3)}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-heading{font-size:20px;font-size:var(--tec-font-size-5);font-weight:400;line-height:1.62;line-height:var(--tec-line-height-3);margin-bottom:0;margin-top:0}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-heading-description{margin-bottom:0}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-description{font-style:normal;margin-bottom:12px;margin-bottom:var(--tec-spacer-2)}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-title{margin-bottom:0}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-title~.customize-control-content{margin-top:8px;margin-top:var(--tec-spacer-1)}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-title~.customize-control-description{margin-bottom:3px;margin-top:4px;margin-top:var(--tec-spacer-0)}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control .customize-inside-control-row{padding:3px 0}.wp-customizer [id^=customize-control-tribe_customizer] .button.wp-color-result{border-color:#141827;border-color:var(--tec-color-text-primary)}.wp-customizer [id^=customize-control-tribe_customizer] .button.wp-color-result:active,.wp-customizer [id^=customize-control-tribe_customizer] .button.wp-color-result:focus,.wp-customizer [id^=customize-control-tribe_customizer] .button.wp-color-result:hover{border-color:#141827;border-color:var(--tec-color-text-primary);box-shadow:0 0 0 .75px rgba(20,24,39,.5)}.wp-customizer [id^=customize-control-tribe_customizer][id$=_choice].customize-control-radio+[id^=customize-control-tribe_customizer][id$=_color]{margin-top:-18px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:1px solid #d5d5d5;border:1px solid var(--tec-color-border-default);border-radius:9px;width:calc(100% - 24px)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider.focus-visible,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider:active,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider:focus,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider:focus-visible{box-shadow:0 0 0 2px #334aff;box-shadow:0 0 0 2px var(--tec-color-accent-primary);outline:none}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-track{background-color:#fff;background-color:var(--tec-color-background);border:0;border-radius:3px;cursor:pointer;height:3px;width:100%}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-slider-runnable-track{background-color:#fff;border:0;border-radius:3px;cursor:pointer;height:3px;width:100%}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-track{background-color:#fff;background-color:var(--tec-color-background);border:0;border-radius:3px;cursor:pointer;height:3px;width:100%}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-progress{background-color:#334aff;background-color:var(--tec-color-accent-primary);border-radius:3px;height:3px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-progress-value{background-color:#334aff;background-color:var(--tec-color-accent-primary)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-fill-lower{background-color:#334aff;background-color:var(--tec-color-accent-primary)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-thumb{background-color:#fff;background-color:var(--tec-color-background);border:5px solid #334aff;border:5px solid var(--tec-color-accent-primary);border-radius:50%;cursor:pointer;height:5px;width:5px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-thumb:active,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-thumb:focus{border-color:rgba(51,74,255,.8);border-color:var(--tec-color-link-accent-hover)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:#fff;background-color:var(--tec-color-background);border:5px solid #334aff;border:5px solid var(--tec-color-accent-primary);border-radius:50%;cursor:pointer;height:16px;margin-top:-7px;width:16px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-slider-thumb:active,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-slider-thumb:focus{border-color:rgba(51,74,255,.8);border-color:var(--tec-color-link-accent-hover)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-thumb{background-color:#fff;background-color:var(--tec-color-background);border:5px solid #334aff;border:5px solid var(--tec-color-accent-primary);border-radius:50%;cursor:pointer;height:5px;width:5px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-thumb:active,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-thumb:focus{border-color:rgba(51,74,255,.8);border-color:var(--tec-color-link-accent-hover)}.wp-customizer [id^=customize-control-tribe_customizer] .tec-range-slider-datalist{display:flex;justify-content:space-between;width:calc(100% - 24px)}.wp-customizer [id^=customize-control-tribe_customizer] .tec-range-slider-option{text-align:center}.wp-customizer [id^=customize-control-tribe_customizer] .tec-range-slider-option:first-child{text-align:left}.wp-customizer [id^=customize-control-tribe_customizer] .tec-range-slider-option:last-child{text-align:right}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .customize-inside-control-row{display:flex;justify-content:space-between;margin-left:0;padding-left:0}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label{align-items:center;display:inline-flex;margin:5px 0}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label.focus-visible,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:active,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:focus,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:focus-visible{outline:none}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label.focus-visible .tec-switch-toggle,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:active .tec-switch-toggle,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:focus-visible .tec-switch-toggle,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:focus .tec-switch-toggle{box-shadow:0 0 0 2px #334aff;box-shadow:0 0 0 2px var(--tec-color-accent-primary)}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle{border-radius:12px;cursor:pointer;font-size:16px;padding:2px;position:relative}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle:after,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle:before{content:"";display:block;margin:0;transition:all .1s cubic-bezier(.4,0,.2,1)}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle:before{background-color:#f7f6f6;background-color:var(--tec-color-background-secondary);border:1px solid #bababa;border:1px solid var(--tec-color-icon-secondary);border-radius:.55em;height:1.125em;opacity:.6;width:2.75em}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle:after{background-color:#d5d5d5;background-color:var(--tec-color-icon-disabled);border-radius:50%;height:16px;left:3px;position:absolute;top:50%;transform:translateY(-50%);width:16px}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-input:checked+.tec-switch-toggle:before{background-color:#334aff;background-color:var(--tec-color-accent-primary);border-color:rgba(51,74,255,.6);opacity:1}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-input:checked+.tec-switch-toggle:after{background-color:#fff;background-color:var(--tec-color-background);transform:translate(calc(41px - 100%),-50%)}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-input:disabled+.tec-switch-toggle{cursor:not-allowed;filter:grayscale(100%);opacity:.6}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-input:focus+.tec-switch-toggle:before{border-color:#334aff;border-color:var(--tec-color-accent-primary)}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .toggle-label-off{margin-right:4px}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .toggle-label-on{margin-left:4px}.wp-customizer [id^=customize-control-tribe_customizer][id$=_choice].customize-control-toggle+[id^=customize-control-tribe_customizer][id$=_color]{margin-top:-8px}
|
1 |
+
.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-heading{font-size:var(--tec-font-size-5);font-weight:400;line-height:var(--tec-line-height-3);margin-bottom:0;margin-top:0}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-heading-description{margin-bottom:0}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-description{font-style:normal;margin-bottom:var(--tec-spacer-2)}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-title{margin-bottom:0}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-title~.customize-control-content{margin-top:var(--tec-spacer-1)}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control-title~.customize-control-description{margin-bottom:3px;margin-top:var(--tec-spacer-0)}.wp-customizer [id^=customize-control-tribe_customizer] .customize-control .customize-inside-control-row{padding:3px 0}.wp-customizer [id^=customize-control-tribe_customizer] .button.wp-color-result{border-color:var(--tec-color-text-primary)}.wp-customizer [id^=customize-control-tribe_customizer] .button.wp-color-result:active,.wp-customizer [id^=customize-control-tribe_customizer] .button.wp-color-result:focus,.wp-customizer [id^=customize-control-tribe_customizer] .button.wp-color-result:hover{border-color:var(--tec-color-text-primary);box-shadow:0 0 0 .75px rgba(20,24,39,.5)}.wp-customizer [id^=customize-control-tribe_customizer][id$=_choice].customize-control-radio+[id^=customize-control-tribe_customizer][id$=_color]{margin-top:-18px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:1px solid var(--tec-color-border-default);border-radius:9px;width:calc(100% - 24px)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider.focus-visible,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider:active,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider:focus,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider:focus-visible{box-shadow:0 0 0 2px var(--tec-color-accent-primary);outline:none}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-track{background-color:var(--tec-color-background);border:0;border-radius:3px;cursor:pointer;height:3px;width:100%}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-slider-runnable-track{background-color:#fff;border:0;border-radius:3px;cursor:pointer;height:3px;width:100%}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-track{background-color:var(--tec-color-background);border:0;border-radius:3px;cursor:pointer;height:3px;width:100%}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-progress{background-color:var(--tec-color-accent-primary);border-radius:3px;height:3px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-progress-value{background-color:var(--tec-color-accent-primary)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-fill-lower{background-color:var(--tec-color-accent-primary)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-thumb{background-color:var(--tec-color-background);border:5px solid var(--tec-color-accent-primary);border-radius:50%;cursor:pointer;height:5px;width:5px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-thumb:active,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-moz-range-thumb:focus{border-color:var(--tec-color-link-accent-hover)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:var(--tec-color-background);border:5px solid var(--tec-color-accent-primary);border-radius:50%;cursor:pointer;height:16px;margin-top:-7px;width:16px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-slider-thumb:active,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-webkit-slider-thumb:focus{border-color:var(--tec-color-link-accent-hover)}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-thumb{background-color:var(--tec-color-background);border:5px solid var(--tec-color-accent-primary);border-radius:50%;cursor:pointer;height:5px;width:5px}.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-thumb:active,.wp-customizer [id^=customize-control-tribe_customizer] input[type=range].tec-range-slider::-ms-thumb:focus{border-color:var(--tec-color-link-accent-hover)}.wp-customizer [id^=customize-control-tribe_customizer] .tec-range-slider-datalist{display:flex;justify-content:space-between;width:calc(100% - 24px)}.wp-customizer [id^=customize-control-tribe_customizer] .tec-range-slider-option{text-align:center}.wp-customizer [id^=customize-control-tribe_customizer] .tec-range-slider-option:first-child{text-align:left}.wp-customizer [id^=customize-control-tribe_customizer] .tec-range-slider-option:last-child{text-align:right}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .customize-inside-control-row{display:flex;justify-content:space-between;margin-left:0;padding-left:0}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label{align-items:center;display:inline-flex;margin:5px 0}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label.focus-visible,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:active,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:focus,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:focus-visible{outline:none}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label.focus-visible .tec-switch-toggle,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:active .tec-switch-toggle,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:focus-visible .tec-switch-toggle,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-label:focus .tec-switch-toggle{box-shadow:0 0 0 2px var(--tec-color-accent-primary)}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle{border-radius:12px;cursor:pointer;font-size:16px;padding:2px;position:relative}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle:after,.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle:before{content:"";display:block;margin:0;transition:all .1s cubic-bezier(.4,0,.2,1)}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle:before{background-color:var(--tec-color-background-secondary);border:1px solid var(--tec-color-icon-secondary);border-radius:.55em;height:1.125em;opacity:.6;width:2.75em}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-toggle:after{background-color:var(--tec-color-icon-disabled);border-radius:50%;height:16px;left:3px;position:absolute;top:50%;transform:translateY(-50%);width:16px}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-input:checked+.tec-switch-toggle:before{background-color:var(--tec-color-accent-primary);border-color:rgba(51,74,255,.6);opacity:1}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-input:checked+.tec-switch-toggle:after{background-color:var(--tec-color-background);transform:translate(calc(41px - 100%),-50%)}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-input:disabled+.tec-switch-toggle{cursor:not-allowed;filter:grayscale(100%);opacity:.6}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .tec-switch-input:focus+.tec-switch-toggle:before{border-color:var(--tec-color-accent-primary)}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .toggle-label-off{margin-right:4px}.wp-customizer [id^=customize-control-tribe_customizer].customize-control-toggle .toggle-label-on{margin-left:4px}.wp-customizer [id^=customize-control-tribe_customizer][id$=_choice].customize-control-toggle+[id^=customize-control-tribe_customizer][id$=_color]{margin-top:-8px}
|
common/src/resources/css/dialog.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
:root{--tec-grid-gutter:48px;--tec-grid-gutter-negative:calc(var(--tec-grid-gutter)*-1);--tec-grid-gutter-half:calc(var(--tec-grid-gutter)/2);--tec-grid-gutter-half-negative:calc(var(--tec-grid-gutter-half)*-1);--tec-grid-gutter-small:42px;--tec-grid-gutter-small-negative:calc(var(--tec-grid-gutter-small)*-1);--tec-grid-gutter-small-half:calc(var(--tec-grid-gutter-small)/2);--tec-grid-gutter-small-half-negative:calc(var(--tec-grid-gutter-small-half)*-1);--tec-grid-gutter-page:42px;--tec-grid-gutter-page-small:19.5px;--tec-grid-width-default:1176px;--tec-grid-width-min:320px;--tec-grid-width:calc(var(--tec-grid-width-default) + var(--tec-grid-gutter-page)*2);--tec-grid-width-1-of-2:50%;--tec-grid-width-1-of-3:33.333%;--tec-grid-width-1-of-4:25%;--tec-grid-width-1-of-5:20%;--tec-grid-width-1-of-7:14.285%;--tec-grid-width-1-of-8:12.5%;--tec-grid-width-1-of-9:11.111%;--grid-gutter:var(--tec-grid-gutter);--grid-gutter-negative:var(--tec-grid-gutter-negative);--grid-gutter-half:var(--tec-grid-gutter-half);--grid-gutter-half-negative:var(--tec-grid-gutter-half-negative);--grid-gutter-small:var(--tec-grid-gutter-small);--grid-gutter-small-negative:var(--tec-grid-gutter-small-negative);--grid-gutter-small-half:var(--tec-grid-gutter-small-half);--grid-gutter-small-half-negative:var(--tec-grid-gutter-small-half-negative);--grid-gutter-page:var(--tec-grid-gutter-page);--grid-gutter-page-small:var(--tec-grid-gutter-page-small);--grid-width-default:var(--tec-grid-width-default);--grid-width-min:var(--tec-grid-width-min);--grid-width:var(--tec-grid-width);--grid-width-1-of-2:var(--tec-grid-width-1-of-2);--grid-width-1-of-3:var(--tec-grid-width-1-of-3);--grid-width-1-of-4:var(--tec-grid-width-1-of-4);--grid-width-1-of-5:var(--tec-grid-width-1-of-5);--grid-width-1-of-7:var(--tec-grid-width-1-of-7);--grid-width-1-of-8:var(--tec-grid-width-1-of-8);--grid-width-1-of-9:var(--tec-grid-width-1-of-9);--tec-spacer-0:4px;--tec-spacer-1:8px;--tec-spacer-2:12px;--tec-spacer-3:16px;--tec-spacer-4:20px;--tec-spacer-5:24px;--tec-spacer-6:28px;--tec-spacer-7:32px;--tec-spacer-8:40px;--tec-spacer-9:48px;--tec-spacer-10:56px;--tec-spacer-11:64px;--tec-spacer-12:80px;--tec-spacer-13:96px;--tec-spacer-14:160px;--spacer-0:var(--tec-spacer-0);--spacer-1:var(--tec-spacer-1);--spacer-2:var(--tec-spacer-2);--spacer-3:var(--tec-spacer-3);--spacer-4:var(--tec-spacer-4);--spacer-5:var(--tec-spacer-5);--spacer-6:var(--tec-spacer-6);--spacer-7:var(--tec-spacer-7);--spacer-8:var(--tec-spacer-8);--spacer-9:var(--tec-spacer-9);--spacer-10:var(--tec-spacer-10);--spacer-11:var(--tec-spacer-11);--spacer-12:var(--tec-spacer-12);--spacer-13:var(--tec-spacer-13);--spacer-14:var(--tec-spacer-14);--tec-z-index-spinner-container:100;--tec-z-index-views-selector:30;--tec-z-index-dropdown:30;--tec-z-index-events-bar-button:20;--tec-z-index-search:10;--tec-z-index-filters:9;--tec-z-index-scroller:7;--tec-z-index-week-event-hover:5;--tec-z-index-map-event-hover:5;--tec-z-index-map-event-hover-actions:6;--tec-z-index-multiday-event:5;--tec-z-index-multiday-event-bar:2;--z-index-spinner-container:var(--tec-z-index-spinner-container);--z-index-views-selector:var(--tec-z-index-views-selector);--z-index-dropdown:var(--tec-z-index-dropdown);--z-index-events-bar-button:var(--tec-z-index-events-bar-button);--z-index-search:var(--tec-z-index-search);--z-index-filters:var(--tec-z-index-filters);--z-index-scroller:var(--tec-z-index-scroller);--z-index-week-event-hover:var(--tec-z-index-week-event-hover);--z-index-map-event-hover:var(--tec-z-index-map-event-hover);--z-index-map-event-hover-actions:var(--tec-z-index-map-event-hover-actions);--z-index-multiday-event:var(--tec-z-index-multiday-event);--z-index-multiday-event-bar:var(--tec-z-index-multiday-event-bar);--tec-color-text-primary:#141827;--tec-color-text-primary-light:rgba(20,24,39,.62);--tec-color-text-secondary:#5d5d5d;--tec-color-text-disabled:#d5d5d5;--tec-color-text-events-title:var(--tec-color-text-primary);--tec-color-text-event-title:var(--tec-color-text-events-title);--tec-color-text-event-date:var(--tec-color-text-primary);--tec-color-text-secondary-event-date:var(--tec-color-text-secondary);--tec-color-icon-primary:#5d5d5d;--tec-color-icon-primary-alt:#757575;--tec-color-icon-secondary:#bababa;--tec-color-icon-active:#141827;--tec-color-icon-disabled:#d5d5d5;--tec-color-icon-focus:#334aff;--tec-color-icon-error:#da394d;--tec-color-event-icon:#141827;--tec-color-event-icon-hover:#334aff;--tec-color-accent-primary:#334aff;--tec-color-accent-primary-hover:rgba(51,74,255,.8);--tec-color-accent-primary-active:rgba(51,74,255,.9);--tec-color-accent-primary-background:rgba(51,74,255,.07);--tec-color-accent-secondary:#141827;--tec-color-accent-secondary-hover:rgba(20,24,39,.8);--tec-color-accent-secondary-active:rgba(20,24,39,.9);--tec-color-accent-secondary-background:rgba(20,24,39,.07);--tec-color-button-primary:var(--tec-color-accent-primary);--tec-color-button-primary-hover:var(--tec-color-accent-primary-hover);--tec-color-button-primary-active:var(--tec-color-accent-primary-active);--tec-color-button-primary-background:var(--tec-color-accent-primary-background);--tec-color-button-secondary:var(--tec-color-accent-secondary);--tec-color-button-secondary-hover:var(--tec-color-accent-secondary-hover);--tec-color-button-secondary-active:var(--tec-color-accent-secondary-active);--tec-color-button-secondary-background:var(--tec-color-accent-secondary-background);--tec-color-link-primary:var(--tec-color-text-primary);--tec-color-link-accent-hover:rgba(51,74,255,.8);--tec-color-border-default:#d5d5d5;--tec-color-border-secondary:#e4e4e4;--tec-color-border-tertiary:#7d7d7d;--tec-color-border-hover:#5d5d5d;--tec-color-border-active:#141827;--tec-color-background:#fff;--tec-color-background-events:transparent;--tec-color-background-transparent:hsla(0,0%,100%,.6);--tec-color-background-secondary:#f7f6f6;--tec-color-background-messages:rgba(20,24,39,.07);--tec-color-background-secondary-hover:#f0eeee;--tec-color-background-error:rgba(218,57,77,.08);--tec-color-box-shadow:rgba(0,0,0,.14);--tec-color-box-shadow-secondary:rgba(0,0,0,.1);--tec-color-scroll-track:rgba(0,0,0,.25);--tec-color-scroll-bar:rgba(0,0,0,.5);--tec-color-background-primary-multiday:rgba(51,74,255,.24);--tec-color-background-primary-multiday-hover:rgba(51,74,255,.34);--tec-color-background-secondary-multiday:rgba(20,24,39,.24);--tec-color-background-secondary-multiday-hover:rgba(20,24,39,.34);--tec-color-accent-primary-week-event:rgba(51,74,255,.1);--tec-color-accent-primary-week-event-hover:rgba(51,74,255,.2);--tec-color-accent-primary-week-event-featured:rgba(51,74,255,.04);--tec-color-accent-primary-week-event-featured-hover:rgba(51,74,255,.14);--tec-color-background-secondary-datepicker:var(--tec-color-background-secondary);--tec-color-accent-primary-background-datepicker:var(--tec-color-accent-primary-background);--color-text-primary:var(--tec-color-text-primary);--color-text-primary-light:var(--tec-color-text-primary-light);--color-text-secondary:var(--tec-color-text-secondary);--color-text-disabled:var(--tec-color-text-disabled);--color-icon-primary:var(--tec-color-icon-primary);--color-icon-primary-alt:var(--tec-color-icon-primary);--color-icon-secondary:var(--tec-color-icon-secondary);--color-icon-active:var(--tec-color-icon-active);--color-icon-disabled:var(--tec-color-icon-disabled);--color-icon-focus:var(--tec-color-icon-focus);--color-icon-error:var(--tec-color-icon-error);--color-accent-primary:var(--tec-color-accent-primary);--color-accent-primary-hover:var(--tec-color-accent-primary-hover);--color-accent-primary-active:var(--tec-color-accent-primary-active);--color-accent-primary-background:var(--tec-color-accent-primary-background);--color-accent-primary-multiday:var(--tec-color-accent-primary-multiday);--color-accent-primary-multiday-hover:var(--tec-color-accent-primary-multiday-hover);--color-accent-primary-week-event:var(--tec-color-accent-primary-week-event);--color-accent-primary-week-event-hover:var(--tec-color-accent-primary-week-event-hover);--color-accent-primary-week-event-featured:var(--tec-color-accent-primary-week-event-featured);--color-accent-primary-week-event-featured-hover:var(--tec-color-accent-primary-week-event-featured-hover);--color-accent-secondary:var(--tec-color-accent-secondary);--color-accent-secondary-hover:var(--tec-color-accent-secondary-hover);--color-accent-secondary-active:var(--tec-color-accent-secondary-active);--color-accent-secondary-background:var(--tec-color-accent-secondary-background);--color-border-default:var(--tec-color-border-default);--color-border-secondary:var(--tec-color-border-secondary);--color-border-tertiary:var(--tec-color-border-tertiary);--color-border-hover:var(--tec-color-border-hover);--color-border-active:var(--tec-color-border-active);--color-background:var(--tec-color-background);--color-background-transparent:var(--tec-color-background-transparent);--color-background-secondary:var(--tec-color-background-secondary);--color-background-messages:var(--tec-color-background-messages);--color-background-secondary-hover:var(--tec-color-background-secondary-hover);--color-background-error:var(--tec-color-icon-error);--color-box-shadow:var(--tec-color-box-shadow);--color-box-shadow-secondary:var(--tec-color-box-shadow-secondary);--color-scroll-track:var(--tec-color-scroll-track);--color-scroll-bar:var(--tec-color-scroll-bar);--tec-border-radius-default:4px;--tec-border-width-week-event:2px;--border-radius-default:var(--tec-border-radius-default);--border-width-week-event:var(--tec-border-width-week-event);--tec-box-shadow-default:0 2px 5px 0 var(--tec-color-box-shadow);--tec-box-shadow-tooltip:0 2px 12px 0 var(--tec-color-box-shadow);--tec-box-shadow-card:0 1px 6px 2px var(--tec-color-box-shadow);--tec-box-shadow-multiday:16px 6px 6px -2px var(--tec-color-box-shadow-secondary);--box-shadow-default:var(--tec-box-shadow-default);--box-shadow-tooltip:var(--tec-box-shadow-tooltip);--box-shadow-card:var(--tec-box-shadow-card);--box-shadow-multiday:var(--tec-box-shadow-multiday);--tec-form-color-background:var(--tec-color-background);--tec-form-color-border-default:var(--tec-color-text-primary);--tec-form-color-border-active:var(--tec-color-accent-secondary);--tec-form-color-border-secondary:var(--tec-color-border-tertiary);--tec-form-color-accent-primary:var(--tec-color-accent-primary);--tec-form-box-shadow-default:var(--tec-box-shadow-default);--form-color-background:var(--tec-form-color-background);--form-color-border-default:var(--tec-form-color-border-default);--form-color-border-active:var(--tec-form-color-border-active);--form-color-border-secondary:var(--tec-form-color-border-secondary);--form-color-accent-primary:var(--tec-form-color-accent-primary);--form-box-shadow-default:var(--tec-form-box-shadow-default);--tec-opacity-background:0.07;--tec-opacity-select-highlighted:0.3;--tec-opacity-icon-hover:0.8;--tec-opacity-icon-active:0.9;--tec-opacity-default:1;--opacity-background:var(--tec-opacity-background);--opacity-select-highlighted:var(--tec-opacity-select-highlighted);--opacity-icon-hover:var(--tec-opacity-icon-hover);--opacity-icon-active:var(--tec-opacity-icon-active);--opacity-default:var(--tec-opacity-default);--tec-transition:all 0.2s ease;--tec-transition-background-color:background-color 0.2s ease;--tec-transition-color-border-color:color 0.2s ease,border-color 0.2s ease;--tec-transition-transform:transform 0.2s ease;--tec-transition-border-color:border-color 0.2s ease;--tec-transition-color:color 0.2s ease;--tec-transition-opacity:opacity 0.2s ease;--transition:var(--tec-transition);--transition-background-color:var(--tec-transition-background-color);--transition-color-border-color:var(--tec-transition-color-border-color);--transition-transform:var(--tec-transition-transform);--transition-border-color:var(--tec-transition-border-color);--transition-color:var(--tec-transition-color);--transition-opacity:var(--tec-transition-opacity);--tec-font-family-sans-serif:"Helvetica Neue",Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;--tec-font-weight-regular:400;--tec-font-weight-bold:700;--tec-font-size-0:11px;--tec-font-size-1:12px;--tec-font-size-2:14px;--tec-font-size-3:16px;--tec-font-size-4:18px;--tec-font-size-5:20px;--tec-font-size-6:22px;--tec-font-size-7:24px;--tec-font-size-8:28px;--tec-font-size-9:32px;--tec-font-size-10:42px;--tec-line-height-0:1.38;--tec-line-height-1:1.42;--tec-line-height-2:1.5;--tec-line-height-3:1.62;--font-family-sans-serif:var(--tec-font-family-sans-serif);--font-family-base:var(--tec-font-family-sans-serif);--font-weight-regular:var(--tec-font-weight-regular);--font-weight-bold:var(--tec-font-weight-bold);--font-size-0:var(--tec-font-size-0);--font-size-1:var(--tec-font-size-1);--font-size-2:var(--tec-font-size-2);--font-size-3:var(--tec-font-size-3);--font-size-4:var(--tec-font-size-4);--font-size-5:var(--tec-font-size-5);--font-size-6:var(--tec-font-size-6);--font-size-7:var(--tec-font-size-7);--font-size-8:var(--tec-font-size-8);--font-size-9:var(--tec-font-size-9);--font-size-10:var(--tec-font-size-10);--line-height-0:var(--tec-line-height-0);--line-height-1:var(--tec-line-height-1);--line-height-2:var(--tec-line-height-2);--line-height-3:var(--tec-line-height-3)}.tribe-common .tribe-dialog{--tribe-dialog-background-color:#fff;--tribe-dialog-close-background:#fff;--tribe-dialog-close-border-color:#bababa;--tribe-dialog-close-border-width:1px;--tribe-dialog-close-color:#bababa;--tribe-dialog-close-height:12px;--tribe-dialog-close-height-desktop:16px;--tribe-dialog-overlay-color:transparent;--tribe-modal-overlay-color:rgba(20,24,39,.9);--tribe-dialog-border-radius:4px;--tribe-dialog-padding:16px;--tribe-dialog-padding-top:24px;--tribe-dialog-padding-side:28px}.tribe-common div.tribe-dialog{align-items:center;display:flex;height:100vh;justify-content:center;left:0;position:fixed;top:0;width:100vw;z-index:100}.tribe-common div.tribe-dialog[aria-hidden=true]{display:none}.tribe-common .tribe-dialog__overlay{background-color:var(--tribe-dialog-overlay-color);height:100vh;left:0;opacity:.9;position:fixed;top:0;width:100vw;z-index:100}.tribe-common .tribe-dialog__wrapper{background-color:var(--tribe-dialog-background-color);border-radius:var(--tribe-dialog-border-radius);box-shadow:0 2px 54px 0 var(--tribe-modal-overlay-color);max-height:100vh;max-width:100vw;overflow-y:auto;padding:var(--tribe-dialog-padding);-webkit-perspective:1000;-webkit-transform:translateZ(0);width:800px;z-index:200}.tribe-common .tribe-dialog__wrapper div[role=document]{align-items:flex-end;display:flex;flex-flow:column;justify-content:space-between;position:relative}.tribe-common .tribe-dialog__close-button{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='var(--tec-color-icon-secondary)' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;cursor:pointer;display:inline-block;font-size:14px;height:var(--tribe-dialog-close-height);line-height:var(--tribe-dialog-close-height);padding:0;position:absolute;width:var(--tribe-dialog-close-height);z-index:1}.tribe-common .tribe-dialog__close-button:focus,.tribe-common .tribe-dialog__close-button:hover{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='var(--tec-color-icon-primary)' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-size:contain;outline:none}.tribe-common .tribe-dialog__close-button--hidden{display:none}.tribe-common .tribe-dialog__close-button--round{border-radius:50%}.tribe-common .tribe-dialog__close-button--border{border:var(--tribe-dialog-close-border-width) solid var(--tribe-dialog-close-border-color)}.tribe-common h2.tribe-dialog__title{align-self:flex-start;margin:0 0 22px;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:0}.tribe-common .tribe-dialog__content{color:#141827;font-size:14px;line-height:1.64em;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:calc(var(--tribe-dialog-close-height) + .5em);width:100%}.tribe-common .tribe-dialog__title+.tribe-dialog__content{padding:0}.tribe-common .tribe-dialog__content p{font-size:14px;font-size:var(--font-size-2)}.tribe-common .tribe-modal__overlay{background-color:var(--tribe-modal-overlay-color)}.tribe-common .tribe-confirm__content{padding-right:0}.tribe-common .tribe-dialog__button_wrap{display:flex;flex-flow:row wrap;justify-content:flex-end;margin-top:1rem}.tribe-common .tribe-dialog__button-cancel,.tribe-common .tribe-dialog__button-continue{margin-left:8px;margin-left:var(--spacer-1);width:auto}#top .main_color .tribe-common div.tribe-dialog,#top.tribe-theme-enfold .tribe-common div.tribe-dialog,.tribe-theme-avada .tribe-common div.tribe-dialog,.tribe-theme-divi .tribe-common div.tribe-dialog{z-index:99999}@media screen and (min-width:768px){.tribe-common .tribe-dialog__wrapper{max-height:calc(100vh - 160px);padding:var(--tribe-dialog-padding-top) var(--tribe-dialog-padding-side)}.tribe-common .tribe-dialog__close-button{height:var(--tribe-dialog-close-height-desktop);line-height:var(--tribe-dialog-close-height-desktop);width:var(--tribe-dialog-close-height-desktop)}}@media screen and (max-width:768px){.tribe-common .tribe-dialog__content:last-of-type{padding-bottom:36px}}
|
1 |
+
.tribe-common .tribe-dialog{--tribe-dialog-background-color:#fff;--tribe-dialog-close-background:#fff;--tribe-dialog-close-border-color:#bababa;--tribe-dialog-close-border-width:1px;--tribe-dialog-close-color:#bababa;--tribe-dialog-close-height:12px;--tribe-dialog-close-height-desktop:16px;--tribe-dialog-overlay-color:transparent;--tribe-modal-overlay-color:rgba(20,24,39,.9);--tribe-dialog-border-radius:4px;--tribe-dialog-padding:16px;--tribe-dialog-padding-top:24px;--tribe-dialog-padding-side:28px}.tribe-common div.tribe-dialog{align-items:center;display:flex;height:100vh;justify-content:center;left:0;position:fixed;top:0;width:100vw;z-index:100}.tribe-common div.tribe-dialog[aria-hidden=true]{display:none}.tribe-common .tribe-dialog__overlay{background-color:var(--tribe-dialog-overlay-color);height:100vh;left:0;opacity:.9;position:fixed;top:0;width:100vw;z-index:100}.tribe-common .tribe-dialog__wrapper{background-color:var(--tribe-dialog-background-color);border-radius:var(--tribe-dialog-border-radius);box-shadow:0 2px 54px 0 var(--tribe-modal-overlay-color);max-height:100vh;max-width:100vw;overflow-y:auto;padding:var(--tribe-dialog-padding);-webkit-perspective:1000;-webkit-transform:translateZ(0);width:800px;z-index:200}.tribe-common .tribe-dialog__wrapper div[role=document]{align-items:flex-end;display:flex;flex-flow:column;justify-content:space-between;position:relative}.tribe-common .tribe-dialog__close-button{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%23bababa' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;cursor:pointer;display:inline-block;font-size:14px;height:var(--tribe-dialog-close-height);line-height:var(--tribe-dialog-close-height);padding:0;position:absolute;width:var(--tribe-dialog-close-height);z-index:1}.tribe-common .tribe-dialog__close-button:focus,.tribe-common .tribe-dialog__close-button:hover{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%235d5d5d' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-size:contain;outline:none}.tribe-common .tribe-dialog__close-button--hidden{display:none}.tribe-common .tribe-dialog__close-button--round{border-radius:50%}.tribe-common .tribe-dialog__close-button--border{border:var(--tribe-dialog-close-border-width) solid var(--tribe-dialog-close-border-color)}.tribe-common h2.tribe-dialog__title{align-self:flex-start;margin:0 0 22px;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:0}.tribe-common .tribe-dialog__content{color:#141827;font-size:14px;line-height:1.64em;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:calc(var(--tribe-dialog-close-height) + .5em);width:100%}.tribe-common .tribe-dialog__title+.tribe-dialog__content{padding:0}.tribe-common .tribe-dialog__content p{font-size:var(--font-size-2)}.tribe-common .tribe-modal__overlay{background-color:var(--tribe-modal-overlay-color)}.tribe-common .tribe-confirm__content{padding-right:0}.tribe-common .tribe-dialog__button_wrap{display:flex;flex-flow:row wrap;justify-content:flex-end;margin-top:1rem}.tribe-common .tribe-dialog__button-cancel,.tribe-common .tribe-dialog__button-continue{margin-left:var(--spacer-1);width:auto}#top .main_color .tribe-common div.tribe-dialog,#top.tribe-theme-enfold .tribe-common div.tribe-dialog,.tribe-theme-avada .tribe-common div.tribe-dialog,.tribe-theme-divi .tribe-common div.tribe-dialog{z-index:99999}@media screen and (min-width:768px){.tribe-common .tribe-dialog__wrapper{max-height:calc(100vh - 160px);padding:var(--tribe-dialog-padding-top) var(--tribe-dialog-padding-side)}.tribe-common .tribe-dialog__close-button{height:var(--tribe-dialog-close-height-desktop);line-height:var(--tribe-dialog-close-height-desktop);width:var(--tribe-dialog-close-height-desktop)}}@media screen and (max-width:768px){.tribe-common .tribe-dialog__content:last-of-type{padding-bottom:36px}}
|
common/src/resources/css/tribe-common-admin.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.invalid input,input:out-of-range{border:2px solid red!important}.valid input{border:1px solid green}.clearfix{zoom:1}.placeholder{color:#999;cursor:text;padding:4px}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::placeholder,textarea::placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.bubble{background-color:#f9f9f9;border:1px solid #dfdfdf;border-radius:3px;border-spacing:0;padding:10px}.tribe-sticky-tooltip{color:#bbb}td.tribe_message{padding-bottom:10px!important}#tribe_thanks{float:left;margin:5px 0 0;width:200px}.tribe_brand{font-family:Georgia,serif!important;font-size:17px!important;font-weight:400;margin:8px 0}.tribe-rating{color:#3d54ff}.tribe-rating:hover{color:#1c39bb}#tribe-upgrade{background:#f6f6f6;border:1px solid #ccc;border-radius:5px;margin:20px 0 30px;padding:0 20px 20px}#tribe-upgrade .message{background-color:#ffffe0;border:1px solid #e6db55;border-radius:3px;padding:6px 12px}table.plugins .tribe-plugin-update-message{background:#d54e21;color:#fff;display:inline-table;margin:6px 0;padding:10px 12px}table.plugins .tribe-plugin-update-message h4{display:inline;font-weight:700;margin-right:8px}table.plugins .tribe-plugin-update-message h4:after{content:" \00BB "}table.plugins .tribe-plugin-update-message a{color:#fff;text-decoration:underline}.tribe-settings-form{max-width:1000px}.tribe-settings-form fieldset{clear:both;display:inline-block;padding:10px 0}.tribe-settings-form fieldset.tribe-field-license_key legend{width:auto}.tribe-settings-form legend{float:left;font-weight:700;margin-right:20px;width:220px}.tribe-settings-form .tribe-field-wrap{float:left;max-width:500px}.tribe-settings-form .tribe-field-wrap :first-child{margin-top:0}.tribe-settings-form .tribe-field-checkbox_list label,.tribe-settings-form .tribe-field-radio label{display:block;margin:5px 0 5px 20px;text-indent:-20px}.tribe-settings-form .tribe-field-checkbox_list label>p,.tribe-settings-form .tribe-field-radio label>p{margin-left:1px;text-indent:0}.tribe-settings-form .tribe-field-checkbox_list label input,.tribe-settings-form .tribe-field-radio label input{margin-right:5px}.tribe-settings-form .tribe-settings-form-wrap .description,.tribe-settings-form .tribe-settings-form-wrap fieldset,.tribe-settings-form fieldset[id^=tribe-field-geoloc_]{padding-left:12px}.tribe-settings-form .tribe-settings-form-wrap fieldset .description{margin-left:0;max-width:450px;padding-left:0}.tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection{margin-bottom:18px}.tribe-settings-form .tribe-settings-form-wrap #tribe-field-stylesheetOption .description{color:#999;margin-left:1px}.tribe-settings-form .tribe-settings-form-wrap h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}.tribe-settings-form .tribe-settings-form-wrap .contained,.tribe-settings-form .tribe-settings-form-wrap .system-info,.tribe-settings-form .tribe-settings-form-wrap .tribe-sysinfo-optin-msg,.tribe-settings-form .tribe-settings-form-wrap h3+p{margin:0 0 10px;padding-left:12px}.tribe_settings .tribe-field-indent{margin-left:245px}.tribe_settings #pu_dashboard_message{display:none}.tribe_settings .tribe-errors-list{margin-left:15px}.tribe_settings .expiring-license{color:red}.tribe_settings .tribe-error{border:1px solid red}.tribe_settings .tribe-field-description{margin-bottom:0;position:relative;top:-12px}.tribe_settings #ical-link{top:-14px}#modern-tribe-info{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:8px 20px 12px}#modern-tribe-info img{margin:10px 0}#modern-tribe-info ul{list-style:disc;margin-left:20px}#modern-tribe-info ul ul{list-style:circle}.tribe-field-inline-dropdown{margin-left:0;margin-right:0}.tribe-field-inline-text{line-height:28px;margin:0 2px}.tribe-field-textarea.tribe-size-small textarea{height:60px;width:180px}.tribe-field-textarea.tribe-size-medium textarea{height:80px;width:300px}.tribe-field-textarea.tribe-size-large textarea{height:120px;width:450px}.tribe-field-email.tribe-size-small input,.tribe-field-license_key.tribe-size-small input,.tribe-field-text.tribe-size-small input{width:50px}.tribe-field-email.tribe-size-medium input,.tribe-field-license_key.tribe-size-medium input,.tribe-field-text.tribe-size-medium input{width:225px}.tribe-field-email.tribe-size-large input,.tribe-field-license_key.tribe-size-large input,.tribe-field-text.tribe-size-large input{width:450px}.tribe-field-dropdown.tribe-size-small select{width:100px}.tribe-field-dropdown.tribe-size-medium select{width:300px}.tribe-field-dropdown.tribe-size-large select{width:450px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap{max-width:600px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap .description{max-width:100%}.tribe-field-dropdown_chosen.tribe-size-small select{width:100px}.tribe-field-dropdown_chosen.tribe-size-medium select{width:200px}.tribe-field-dropdown_chosen.tribe-size-large select{width:300px}.tribe-field-wrap .tooltip:first-child{font-style:normal}.tribe-field.indent{margin-left:252px;width:75%}.tribe-field.indent legend{font-weight:400;width:auto}.tribe-field.indent .tribe-field-wrap{padding-right:12px}.tribe-field.indent.tribe-field-radio .tribe-field-wrap{clear:left;margin-top:12px}.tribe-field.light-bordered{background-color:#fff;border:1px solid #d3d3d3}.ajax-loading-license,.invalid-key,.valid-key{display:none;margin:0 5px}.ajax-loading-license{position:relative;top:5px}.key-validity{display:inline-block}.invalid-key,.optin-fail{color:red}.optin-success,.valid-key{color:green}.valid-key.service-msg{color:#b72}#additional-field-table{margin-bottom:20px}.tribe-admin-box-left{float:left;width:20%}.tribe-admin-box-left,.tribe-admin-box-right{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:0 20px 15px}.tribe-admin-box-right{float:right;width:68%}.ajax-loader{float:right;margin:10px}.tribe-arrangeable-item{border:1px solid #d3d3d3;border-radius:3px}.tribe-arrangeable-item .ui-state-default{border:none}.tribe-arrangeable-item-top{padding:6px}.tribe-arrangeable-item-top:hover{cursor:move}.tribe-arrangeable-action{float:right}.tribe-arrangeable-child{background-color:#f9f9f9;border-top:1px solid #d3d3d3;display:none;padding:25px}.tribe-arrangeable-child label{display:block;margin:0 0 7px}.tribe_events_active_filter_type_options{margin:10px 0}.tribe_events_active_filter_type_options label{margin:7px 0}#event_organizer td small,.OrganizerInfo td small{display:block;margin:0;max-width:250px}#event_organizer .organizer-email,.OrganizerInfo .organizer-email{vertical-align:top}.tribe-table-field-label{max-width:100%;width:200px}#tribe-help-general,#tribe-help-sidebar{float:left;margin-top:20px}#tribe-help-general p{margin-left:15px}#tribe-help-general ul{list-style-type:square}#tribe-help-general ol,#tribe-help-general ul{margin-bottom:20px;margin-left:35px}#tribe-help-general h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}#tribe-help-general h3~h3{margin-top:2.25em}#tribe-help-general h3+p{margin:0 0 20px;padding-left:12px}#tribe-help-general{width:65%}.tribe-help-section{padding-bottom:10px}.tribe-section-type-box{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;padding:8px 20px 12px}.tribe-section-type-box img{height:auto;margin:10px 0;max-width:300px}.tribe-section-type-box ul{list-style:disc;margin-left:20px}.tribe-section-type-box ul ul{list-style:circle}#tribe-log-controls{padding-bottom:1rem;padding-left:12px}#tribe-log-controls>div{display:inline-block;padding-right:1rem}#tribe-log-controls .working{opacity:1;transition:opacity .2s}#tribe-log-controls .working.hidden{opacity:0;transition:opacity .2s}#tribe-log-viewer,#tribe-system-info dl.support-stats,.template-updates-wrapper{background:#000;border-radius:2px;color:#888;max-height:400px;overflow:scroll;padding:10px}#tribe-system-info dl.support-stats dt,.template-updates-wrapper dt{clear:both;float:left;font-weight:700;text-transform:uppercase;width:25%}#tribe-system-info dl.support-stats dd,.template-updates-wrapper dd{margin-left:25%;padding-left:10px}.system-info-copy .system-info-copy-btn{padding:6px}.system-info-copy .system-info-copy-btn .dashicons{padding-right:10px}.template-updates-wrapper p{margin-top:0}#tribe-help-sidebar{margin:20px 0 0 3%;max-width:225px;width:32%}.tribe-help-plugin-info{border:1px solid #ccc;padding:0 12px 12px}.tribe-help-plugin-info dd,.tribe-help-plugin-info dt{display:inline;margin:0}.tribe-help-plugin-info dt{font-weight:700}.tribe-help-plugin-info dd:after{content:"";display:block;height:.4em}.tribe-help-plugin-info dd:last-child:after{height:0}.tribe-help-plugin-info+.tribe-help-plugin-info{margin-top:20px}.tribe-help-plugin-info>div{line-height:2em}.tribe-help-plugin-info .star-rating{display:inline-block;margin-left:3px;position:relative;top:-2px}.tribe-help-plugin-info .tribe-list-addons{color:#21a6cb;font-size:24px;list-style:circle inside;margin-bottom:10px;margin-top:10px;padding-left:4px}.tribe-help-plugin-info .tribe-list-addons a{font-size:13px;left:-5px;position:relative;top:-5px}.tribe-help-plugin-info .tribe-list-addons .tribe-active-addon{list-style:disc inside}.ui-widget-overlay{background:#666;filter:alpha(opacity=50);opacity:.5}.ui-widget-shadow{background:#000;border-radius:5px;filter:alpha(opacity=20);margin:-5px 0 0 -5px;opacity:.2;padding:5px}.ui-resizable{position:relative}.ui-resizable-handle{display:block;font-size:.1px;position:absolute;z-index:99999}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;left:0;top:-5px;width:100%}.ui-resizable-s{bottom:-5px;cursor:s-resize;height:7px;left:0;width:100%}.ui-resizable-e{cursor:e-resize;height:100%;right:-5px;top:0;width:7px}.ui-resizable-w{cursor:w-resize;height:100%;left:-5px;top:0;width:7px}.ui-resizable-se{bottom:1px;cursor:se-resize;height:12px;right:1px;width:12px}.ui-resizable-sw{bottom:-5px;cursor:sw-resize;height:9px;left:-5px;width:9px}.ui-resizable-nw{cursor:nw-resize;height:9px;left:-5px;top:-5px;width:9px}.ui-resizable-ne{cursor:ne-resize;height:9px;right:-5px;top:-5px;width:9px}.ui-dialog{padding:.2em;position:relative;width:375px}.ui-dialog .ui-dialog-titlebar{padding:.5em .3em .3em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0 .2em}.ui-dialog .ui-dialog-titlebar-close{height:18px;margin:-10px 0 0;padding:1px;position:absolute;right:.3em;top:50%;width:19px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin-left:-8px;margin-top:-8px}.ui-dialog .ui-dialog-titlebar-close:focus,.ui-dialog .ui-dialog-titlebar-close:hover{padding:0}.ui-dialog .ui-dialog-content{background:none;border:0;overflow:auto;padding:.5em 1em;zoom:1}.ui-dialog .ui-dialog-buttonpane{background-image:none;border-width:1px 0 0;margin:.5em 0 0;padding:.3em 1em .5em!important;text-align:right}.ui-dialog .ui-dialog-buttonpane button{cursor:pointer;line-height:1.4em;margin:.5em .4em!important;overflow:visible;padding:.2em .6em .3em;text-shadow:none;width:auto}.ui-dialog .ui-resizable-se{bottom:3px;height:14px;right:3px;width:14px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:none!important;text-align:center}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button .ui-button-text{display:block;line-height:1.4}#ui-datepicker-div{display:none}#tribe-loading{background:#fff;background:hsla(0,0%,100%,.8);display:none;height:100%;left:0;position:absolute;top:0;transition:all 1s linear;width:100%;z-index:4}#tribe-loading span{background:url(../images/tribe-loading.gif) 0 0 no-repeat;background-size:32px 32px;height:32px;left:50%;margin:-16px 0 0 -16px;position:absolute;top:50%;width:32px}<<<<<<< HEAD =======>>>>>>>b509f7a664980817599b22fafa19c531746d5b03 @media only screen and(min--moz-device-pixel-ratio: 2) <<<<<<< HEAD =======>>>>>>>b509f7a664980817599b22fafa19c531746d5b03 #tribe-loading span,only screen and(-o-min-device-pixel-ratio: 2/1) <<<<<<< HEAD =======>>>>>>>b509f7a664980817599b22fafa19c531746d5b03 #tribe-loading span,only screen and(-webkit-min-device-pixel-ratio: 2) <<<<<<< HEAD =======>>>>>>>b509f7a664980817599b22fafa19c531746d5b03 #tribe-loading span,only screen and(min-device-pixel-ratio: 2) <<<<<<< HEAD =======>>>>>>>b509f7a664980817599b22fafa19c531746d5b03 #tribe-loading span{background-image:url(../images/tribe-loading@2x.gif)}.tribe_update_page{max-width:850px}.tribe-half-column{float:left;margin-bottom:30px;margin-right:5%;width:45%}.tribe-row:after,.tribe-row:before{content:"";display:table}.tribe-row,.tribe-row:after{clear:both}.tribe-row .tribe-half-column:last-child{margin-right:0;width:50%}.tribe_update_page h2{font-size:30px;line-height:1.2;margin-bottom:20px}.tribe_update_page h3{font-size:24px;font-weight:400;line-height:24px;margin-top:0}.tribe_update_page h4{font-size:18px;font-weight:600;line-height:18px;margin:0}.tribe_update_page p{font-size:15px}p.tribe-update-message{font-size:18px;font-weight:400}.tribe_update_page h4:before{content:"\f145";font-family:dashicons;font-size:34px;line-height:1;margin-right:5px;position:relative;top:5px}a.tribe-rating-link{text-decoration:none}.tribe-update-links{margin-top:30px}.tribe_update_page li:before{content:"\2022";padding-right:3px}.tribe_update_page .rss-widget{margin:1em 0}.tribe_update_page a.rsswidget{font-size:14px;font-weight:400;line-height:1}.tribe_update_page .rss-widget li:before{display:none}.tribe-events-widget-admin-form__input-section p{margin:0}.tribe-events-widget-admin-form__input-section h4{margin:.5em 0}.tribe-update-bar{display:inline-block}.tribe-update-bar .progress{border:1px solid #ccc;float:left;margin-right:1rem;padding:1px;width:18rem}.tribe-update-bar .progress .bar{background:#7ad03a;height:1rem;width:1%}#tribe-dialog-wrapper>div{padding:1rem}#tribe-dialog-wrapper>div .stage{display:none}#tribe-dialog-wrapper #heading{background:#fff}#tribe-dialog-wrapper label{display:block}#tribe-dialog-wrapper .select-single-container{border:1px solid #888;height:300px;overflow-y:scroll}#tribe-dialog-wrapper .select-single-container label{opacity:1;padding:3px 5px;transition:opacity .2s}#tribe-dialog-wrapper .select-single-container label:nth-child(odd){background:#fff}#tribe-dialog-wrapper .select-single-container label.selected{background:#0073aa;color:#fff;font-weight:700}#tribe-dialog-wrapper .select-single-container label input{display:none}#tribe-dialog-wrapper .select-single-container.updating label{opacity:.35;transition:opacity .2s}.ui-front{z-index:1000000}.wp-list-table.plugins .column-description .update-message{color:#d54e21}.api-check{min-height:100px;padding:1em}.api-check+.notice-dismiss:hover:before{color:#fff}.api-check:after,.api-check:before{content:"";display:table}.api-check:after{clear:both}.api-check .tribe-mascot{bottom:0;display:none;padding:0 1rem 0 0;position:absolute;right:0;top:0}.api-check .tribe-mascot img{display:inline-block;height:100%;max-height:150px;max-width:150px;vertical-align:middle;width:auto}.api-check p{line-height:1.7;margin-bottom:1em}.api-check a{text-decoration:none}.api-check a:hover{text-decoration:underline}.api-check .plugin-list{display:inline;font-weight:600;margin:0;padding:0}.api-check .plugin-list span.plugin-invalid:after{content:", "}.api-check .plugin-list span.plugin-invalid:last-of-type:after{content:""}.tribe-marketing-notice{padding:1em}.tribe-marketing-notice+.notice-dismiss:hover:before{color:#fff}.tribe-marketing-notice:after,.tribe-marketing-notice:before{content:"";display:table}.tribe-marketing-notice:after{clear:both}.tribe-marketing-notice .tribe-marketing-notice__icon{display:none;flex-shrink:0;padding:0;position:static}.tribe-marketing-notice .tribe-marketing-notice__icon img{display:inline-block;max-height:100%;max-width:none;vertical-align:middle;width:100%}.tribe-marketing-notice h3{margin-bottom:.5em;margin-top:.5em}.tribe-marketing-notice p{line-height:1.7;margin-bottom:.5em}.tribe-marketing-notice a{text-decoration:none}.tribe-marketing-notice a:hover{text-decoration:underline}#wpcontent .notice-tribe-banner{align-items:center;background:#161b7d;border:0;box-shadow:none;display:flex;justify-content:flex-start;margin:0 0 16px;padding-right:0}.notice-tribe-banner .tribe-marketing-notice__icon{width:47px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:0;padding:1em 0}.notice-tribe-banner h3{color:#fff;display:block;font-size:.875rem;line-height:1.25;margin:0 0 .25rem}.notice-tribe-banner a{border-bottom:1px solid #fff;line-height:1.25;margin:0;text-decoration:none}.notice-tribe-banner a:hover{text-decoration:none}.notice-tribe-banner a,.notice-tribe-banner p{color:#fff;display:inline-block;font-size:.875rem;line-height:1.25}.notice-tribe-banner p{display:inline-block;margin:0;padding:0}.notice-tribe-banner .tribe-marketing-notice{align-items:center;display:flex;justify-content:flex-start;margin:0 auto;min-height:65px;padding:0 .75rem;width:100%}.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe-welcome .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:100%}.notice-tribe-banner .notice-dismiss{position:static}.notice-tribe-banner .notice-dismiss:before{color:#eaf1ff}.tribe-dropdown,.tribe-ea-dropdown{max-width:100%;width:auto}.tribe-dropdown.select2-container .selection,.tribe-ea-dropdown.select2-container .selection{margin-top:inherit}.tribe-dropdown .select2-selection--single,.tribe-ea-dropdown .select2-selection--single{height:32px}.tribe-dropdown .select2-selection--single .select2-selection__clear,.tribe-ea-dropdown .select2-selection--single .select2-selection__clear{line-height:28px}.tribe-dropdown .select2-selection--single .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--single .select2-selection__rendered{line-height:32px;padding-right:28px}.tribe-dropdown.select2-container--focus .select2-selection--single,.tribe-ea-dropdown.select2-container--focus .select2-selection--single{border-color:#5897fb;box-shadow:0 0 5px rgba(0,0,0,.1)}.tribe-dropdown.select2-container--open .select2-search__field,.tribe-ea-dropdown.select2-container--open .select2-search__field{padding:0}.tribe-dropdown.select2-container--open .select2-dropdown--below,.tribe-ea-dropdown.select2-container--open .select2-dropdown--below{border-top:1px solid #aaa;margin-top:-1px}.tribe-dropdown.select2-container--open .select2-dropdown--above,.tribe-ea-dropdown.select2-container--open .select2-dropdown--above{border-bottom:1px solid #aaa;margin-bottom:-16px}.tribe-dropdown.select2-container--open .select2-selection--single,.tribe-ea-dropdown.select2-container--open .select2-selection--single{border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:#aaa}.tribe-dropdown.select2-container--open .select2-selection__arrow b,.tribe-ea-dropdown.select2-container--open .select2-selection__arrow b{transform:rotate(180deg)}.tribe-dropdown.select2-selection--single,.tribe-ea-dropdown.select2-selection--single{background-image:none;border:1px solid #ccc;border-radius:3px;overflow:hidden}.tribe-dropdown.select2-selection--single>.select2-selection__rendered,.tribe-ea-dropdown.select2-selection--single>.select2-selection__rendered{white-space:normal}.tribe-dropdown.select2-selection--single .select2-selection__arrow,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow{background:transparent;background-image:none;border-left:0;top:2px;width:26px}.tribe-dropdown.select2-selection--single .select2-selection__arrow b,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow b{background:#fff url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E") no-repeat right 5px top 55%;background-size:auto;background-size:16px 16px;border:0;bottom:0;display:block;height:auto;left:0;margin:0;padding:0;right:0;top:0;width:auto}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered{background-image:none;border:1px solid #ccc;border-radius:3px;min-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline{line-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input{padding-bottom:0;padding-top:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice{line-height:19px;margin-top:2px;padding-bottom:0;padding-top:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div{line-height:inherit}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove{left:4px;top:3px;transition-property:border,color}.select2-results .select2-results__option{color:#939393;font-weight:400;margin-bottom:0}.select2-results .select2-results__option[aria-disabled=true]{background-color:#e0e0e0}.select2-results.select2-results__option--highlighted{background-color:#efefef;color:#a1a1a1;cursor:default;display:block}.wp-core-ui .button-red{background-color:#a00;border-color:#9b2124;box-shadow:inset 0 1px 0 rgba(120,200,230,.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red.hover,.wp-core-ui .button-red:focus,.wp-core-ui .button-red:hover{background-color:#a00;border-color:#7f1c1f;box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.3)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red:focus{border-color:#500f0e;box-shadow:inset 0 1px 0 rgba(120,200,230,.6),1px 1px 2px rgba(0,0,0,.4)}.wp-core-ui .button-red.active,.wp-core-ui .button-red.active:focus,.wp-core-ui .button-red.active:hover,.wp-core-ui .button-red:active{background:#7f1c1f;border-color:#601312 #ae2426 #ae2426;box-shadow:inset 0 1px 0 rgba(0,0,0,.1);color:hsla(0,0%,100%,.95);text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red-disabled,.wp-core-ui .button-red:disabled,.wp-core-ui .button-red[disabled]{background:#ba292b!important;border-color:#7f1c1f!important;box-shadow:none!important;color:#e79496!important;cursor:default;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important}.ticket_form .select2-container .select2-selection--single .select2-selection__arrow{display:none}.clear{zoom:1}.clear:after,.clear:before{content:" ";display:table}.clear:after{clear:both}.checkmark:after{border:solid #0ab152;border-width:0 3px 3px 0;content:"";display:block;height:15px;transform:rotate(45deg);width:8px}.checkmark.checkmark-right:after{float:right;margin-right:2em}.checkmark.checkmark-left:after{float:left;margin-left:2em}.checkmark.no-checkmark:after{display:none}.complete,.ok,.on,.yes,[data-status=complete],[data-status=ok],[data-status=on],[data-status=yes]{color:#0ab152}.incomplete,.ko,.no,.off,[data-status=incomplete],[data-status=ko],[data-status=no],[data-status=off]{color:#ff2500}.plugin-card-event-tickets-plus .column-downloaded,.plugin-card-event-tickets-plus .column-rating,.plugin-card-event-tickets-plus .column-updated,.plugin-card-event-tickets .column-downloaded,.plugin-card-event-tickets .column-rating,.plugin-card-event-tickets .column-updated,.plugin-card-events-calendar-pro .column-downloaded,.plugin-card-events-calendar-pro .column-rating,.plugin-card-events-calendar-pro .column-updated,.plugin-card-events-community-tickets .column-downloaded,.plugin-card-events-community-tickets .column-rating,.plugin-card-events-community-tickets .column-updated,.plugin-card-events-community .column-downloaded,.plugin-card-events-community .column-rating,.plugin-card-events-community .column-updated,.plugin-card-image-widget-plus .column-downloaded,.plugin-card-image-widget-plus .column-rating,.plugin-card-image-widget-plus .column-updated,.plugin-card-image-widget .column-downloaded,.plugin-card-image-widget .column-rating,.plugin-card-image-widget .column-updated,.plugin-card-the-events-calendar .column-downloaded,.plugin-card-the-events-calendar .column-rating,.plugin-card-the-events-calendar .column-updated,.plugin-card-tribe-eventbrite .column-downloaded,.plugin-card-tribe-eventbrite .column-rating,.plugin-card-tribe-eventbrite .column-updated,.plugin-card-tribe-filterbar .column-downloaded,.plugin-card-tribe-filterbar .column-rating,.plugin-card-tribe-filterbar .column-updated{display:none}.tribe-events-admin-content-wrapper{font-style:normal;margin:0 auto;padding:20px;width:calc(100% - 40px)}.tribe-events-admin-card{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;display:block;margin:0 auto 36px;padding:27px;text-align:center}.tribe-events-admin-card--2up .tribe-events-admin-card__title{max-width:260px}.tribe-events-admin-card--3up .tribe-events-admin-card__description{height:71px}.tribe-events-admin-card--3up .tribe-events-admin-card__image{margin-bottom:28px}.tribe-events-admin-card__button{background-color:#fff;border:none;color:#3d54ff;font-size:14px;font-weight:700;letter-spacing:1px;line-height:16px;position:absolute;right:20px;text-transform:uppercase;top:17px}.tribe-events-admin-card__button:hover{color:#161b7d}.tribe-events-admin-card__description{color:#000;font-size:14px;font-style:normal;font-weight:400;line-height:22px;margin-top:16px}.tribe-events-admin-card__image{display:block;height:100px;margin:0 auto}.tribe-events-admin-card__link{color:#3d54ff;display:inline-block;font-size:16px;font-style:normal;font-weight:700;line-height:18px;margin-top:24px;position:relative;text-decoration:none}.tribe-events-admin-card__link:hover{color:#161b7d}.tribe-events-admin-card__link:after{border-style:solid;border-width:0 0 1px;bottom:-4px;content:"";left:0;position:absolute;width:100%}.tribe-events-admin-card__title{color:#0f1031;font-size:20px;font-weight:700;line-height:23px;margin:auto}.tribe-events-admin-card-grid{max-width:1048px}.tribe-events-admin-section-header{color:#000;font-size:24px;font-weight:700;line-height:28px;margin:21px 0 24px}input[type=checkbox].tribe-common-switch__input{display:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label{background:#fff;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;cursor:pointer;display:block;height:18px;outline:0;padding:3px;position:relative;transition:all .2s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:27px}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:after,input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:before{content:"";display:block;height:10px;position:relative;width:10px}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:after{background:#878787;border-radius:2px;content:"";left:0;transition:all .2s ease}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:before{display:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label::-moz-selection{background:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label::selection{background:none}input[type=checkbox].tribe-common-switch__input:checked+.tribe-common-switch__label:after{background:#2e709d;left:50%}body.tribe-welcome,body.tribe_events_page_tribe-help{background-color:#fff;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}body.tribe-welcome .update-nag,body.tribe_events_page_tribe-help .update-nag{display:none}body.tribe-welcome #wpcontent,body.tribe_events_page_tribe-help #wpcontent{padding:0}body.tribe-welcome .tribe_settings,body.tribe_events_page_tribe-help .tribe_settings{margin:0}body.tribe-welcome #wpfooter,body.tribe-welcome .tribe_settings>h1,body.tribe_events_page_tribe-help #wpfooter,body.tribe_events_page_tribe-help .tribe_settings>h1{display:none}body.tribe-welcome #wpbody-content,body.tribe_events_page_tribe-help #wpbody-content{padding-bottom:25px}body.tribe-welcome .tribe-dependency-error,body.tribe_events_page_tribe-help .tribe-dependency-error{display:none}.tribe-events-admin-header__logo-word-mark{display:inline-block;height:auto;margin:0 0 26px;vertical-align:middle;width:312px}.tribe-events-admin-content-wrapper{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding:0 0 30px}.tribe-events-admin-header{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding:45px 0 0}.tribe-events-admin-header__right-image{height:280px;position:absolute;right:0;top:0;width:auto;z-index:-1}.tribe-events-admin-header__title{font-size:48px;line-height:48px;margin:0 0 18px}.tribe-events-admin-header__description{font-size:18px;line-height:28px;margin-bottom:44px;max-width:60%}.tribe-events-admin-tab-nav{display:flex;margin:0}.tribe-events-admin-tab-nav li{cursor:pointer;font-size:16px;font-weight:500;margin-bottom:0;margin-right:30px}.tribe-events-admin-tab-nav li:hover{color:#334aff}.tribe-events-admin-tab-nav .selected{border-bottom:3px solid #334aff;color:#334aff;padding-bottom:17px}.tribe-events-admin-tab-nav li:after{background:#334aff;border-radius:100px;bottom:0;content:"";display:block;height:3px;left:0;position:absolute;right:0}.tribe-events-admin__line{border-top:1px solid #e1e1e4}.tribe-events-admin-products-description{color:#0f1031;font-size:14px;line-height:2}.tribe-events-admin-products-card{align-items:center;border:1px solid #e1e1e4;border-radius:20px;display:flex;padding:10px 15px}.tribe-events-admin-products-card__icon{height:40px;-o-object-fit:contain;object-fit:contain;width:40px}.tribe-events-admin-products-card__group{margin:0 20px;max-width:55%}.tribe-events-admin-products-card__group-title{color:#0f1031;font-size:16px;font-weight:700;line-height:1;margin:0}.tribe-events-admin-products-card__group-description{font-size:12px;margin-top:5px}.tribe-events-admin-products-card__button{background-color:#fff;border:1px solid #e1e1e4;border-radius:20px;color:#0f1031;font-size:12px;font-weight:700;letter-spacing:1px;line-height:16px;margin-left:auto;padding:10px 15px;text-decoration:none;text-transform:uppercase}.tribe-events-admin-products-card__button:hover{background-color:#334aff;color:#fff}.tribe-events-admin-products-card__button:active,.tribe-events-admin-products-card__button:focus{box-shadow:none;outline:none}.tribe-events-admin-products-card__button--active,.tribe-events-admin-products-card__button--active:active,.tribe-events-admin-products-card__button--active:focus,.tribe-events-admin-products-card__button--active:hover{background:rgba(61,84,255,.16);color:#334aff;cursor:not-allowed;text-transform:uppercase}.tribe-events-admin-card--1up{width:100%}.tribe-events-admin-card--no-pad{padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__image{display:block;height:152px;margin:0;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{font-size:28px;line-height:34px;text-align:left}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin:0;padding:0;text-align:left}.tribe-events-admin-card--no-pad .tribe-events-admin-card__link{margin:0;padding:0}.tribe-events-admin-card--faq{display:inline-block;font-size:0;height:147px;margin:0 0 0 30px;padding:24px 16px 22px 20px;width:230px}.tribe-events-admin-card--faq:first-child{margin-left:0}.tribe-events-admin-card--faq img{float:left;height:22px;width:16px}.tribe-events-admin-card--faq .tribe-events-admin-faq__question{color:#334aff;font-size:16px;line-height:19px;margin:0 0 12px 26px;text-align:left}.tribe-events-admin-card--faq .tribe-events-admin-faq__answer{font-size:13px;line-height:16px;margin-left:26px;text-align:left}.tribe-events-admin-video{border-radius:16px;height:200px;margin-bottom:72px;-webkit-mask-image:-webkit-radial-gradient(circle,#fff 100%,#000 0);overflow:hidden;-webkit-transform:rotate(.000001deg)}.tribe-events-admin-video iframe{width:100%}.tribe-events-admin-card--promo-blue{background-color:#3d54ff;background-image:url(../images/welcome/promo.jpg)}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{color:#fff;font-size:16px;margin-bottom:16px;text-align:left}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__title{color:#fff;text-align:left}.tribe-events-admin-graphic{position:absolute;right:0;top:106px;z-index:-1}.tribe-events-admin-graphic--desktop-only{display:none}.tribe-events-admin-graphic--mobile-only{display:block}.tribe-events-admin-card__form{position:relative}input[type=email].tribe-events-admin-card__input{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;font-size:14px;height:54px}input[type=email].tribe-events-admin-card__input:-ms-input-placeholder{color:rgba(15,16,49,.72);letter-spacing:.5px;padding-left:10px}input[type=email].tribe-events-admin-card__input::placeholder{color:rgba(15,16,49,.72);letter-spacing:.5px;padding-left:10px}.tribe-events-admin-container,.tribe-events-admin-content-wrapper.tribe-events-admin-container{margin:0 auto;max-width:1024px;width:90%}.tribe-events-admin-2col-grid{display:grid;grid-gap:15px 30px;gap:15px 30px;grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-3col-grid{display:grid;grid-gap:30px;gap:30px;grid-template-areas:". . .";grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-4col-grid{display:grid;grid-gap:30px;gap:30px;grid-template-areas:". . . .";grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-products{margin:10px 0 0}.tribe-events-admin-quick-nav{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;display:block;margin:40px 0 78px;padding:18px 23px 2px}.tribe-events-admin-quick-nav__link{color:#3d54ff;font-size:16px;font-weight:700;line-height:18px;text-align:center;text-decoration:none}.tribe-events-admin-quick-nav__link:hover{color:#161b7d}.tribe-events-admin-quick-nav__link-item{display:block;padding-bottom:19px}.tribe-events-admin-quick-nav__links{display:inline}.tribe-events-admin-quick-nav__title{color:rgba(15,16,49,.72);display:inline-block;font-size:14px;font-weight:400;line-height:16px;padding-bottom:14px;text-transform:uppercase}.tribe-events-admin-title{padding-top:14px}.tribe-events-admin-title__description{color:#0f1031;font-size:16px;font-weight:400;line-height:24px;max-width:584px;padding-top:15px}.tribe-events-admin-title__heading{color:#0f1031;display:inline-block;font-size:24px;font-weight:700;line-height:28px;margin:5px 0 0}.tribe-events-admin-title__logo{margin-right:8px;vertical-align:top;width:34px}.tribe-events-admin-notice{background-color:#3d54ff;height:65px}.tribe-events-admin-notice .tribe-events-admin-content-wrapper{padding-bottom:0;padding-top:8px}.tribe-events-admin-notice p{color:#fff;display:inline-block;font-family:Helvetica;font-size:16px;line-height:18px;margin-top:0;padding-bottom:12px;padding-left:16px;vertical-align:middle;width:calc(100% - 60px)}.tribe-events-admin-notice__logo{display:inline-block}.tribe-events-admin-tickets .tribe-events-admin-section-header{font-size:28px;line-height:32px}.tribe-events-admin-tickets .tribe-events-admin-graphic--desktop-only{width:365px}.tribe-events-admin-tickets .tribe-events-admin-graphic--mobile-only{top:230px;width:300px}.tribe-events-admin-tickets .tribe-events-admin-title__heading{margin-top:0}.tribe-events-admin-tickets .tribe-events-admin-title__logo{margin-right:4px;width:32px}.tribe-events-admin-kb{margin:10px 0 0}.tribe-events-admin-kb-card{border:1px solid #e1e1e4;border-radius:20px}.tribe-events-admin-kb-card__image{height:auto;width:100%}.tribe-events-admin-kb-card__title{color:#0f1031;flex-grow:0;font-size:20px;font-weight:700;line-height:1.2;margin:0;padding:20px 28px 10px}.tribe-events-admin-kb-card__links{margin:0;padding:0 28px 25px}.tribe-events-admin-kb-card__links li{margin:0 0 10px}.tribe-events-admin-kb-card__links li a{color:#334aff;font-size:14px;line-height:1.2;text-decoration:none}.tribe-events-admin-kb-card__links li a:focus{box-shadow:none;outline:none}.tribe-events-admin-kb-card__links li a:hover{color:#1c39bb}.tribe-events-admin-section-header{align-items:center;display:flex;justify-content:space-between;margin:50px 0 0}.tribe-events-admin-section-header h3{color:#0f1031;font-size:28px;font-weight:700;line-height:1}.tribe-events-admin-section-header a{border-bottom:2px solid #334aff;color:#334aff;font-size:14px;padding-bottom:2px;text-decoration:none}.tribe-events-admin-section-header a:focus{box-shadow:none;outline:none}.tribe-events-admin-section-header a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-faq{margin:10px 0 0}.tribe-events-admin-faq-card{border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;padding:24px 15px 19px 19px}.tribe-events-admin-faq-card a{color:#0f1031}.tribe-events-admin-faq-card a:focus{box-shadow:none;outline:none}.tribe-events-admin-faq-card a:hover{color:#1c39bb}.tribe-events-admin-faq-card__icon img{height:22px;width:16px}.tribe-events-admin-faq-card__content{margin-left:10px}.tribe-events-admin-faq__question,.tribe-events-admin-faq__question a{color:#334aff;font-size:16px;text-decoration:none}.tribe-events-admin-faq__question a:focus{box-shadow:none;outline:none}.tribe-events-admin-faq__question a:hover{color:#1c39bb}.tribe-events-admin-faq__answer{color:#0f1031;font-size:13px;margin-top:18px}.tribe-events-admin-extensions-title{color:#0f1031;font-size:16px;line-height:1.5;margin:0 0 30px;max-width:70%}.tribe-events-admin-extensions{margin:10px 0 0}.tribe-events-admin-extensions-card{border:1px solid #e1e1e4;border-radius:20px;border-top:8px solid #334aff;padding:48px 35px 24px 25px}.tribe-events-admin-extensions-card__title{font-size:20px;margin:0}.tribe-events-admin-extensions-card__title a{color:#0f1031;font-family:Helvetica;font-size:20px;font-weight:700;line-height:1.2;text-decoration:none}.tribe-events-admin-extensions-card__title a:active,.tribe-events-admin-extensions-card__title a:focus,.tribe-events-admin-extensions-card__title a:hover{box-shadow:none;color:#334aff}.tribe-events-admin-extensions-card__description{color:#0f1031;font-family:Helvetica;font-size:14px;line-height:1.43;margin:20px 0}.tribe-events-admin-cta{align-items:center;border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;margin:60px 0}.tribe-events-admin-cta__image{height:152px;-o-object-fit:contain;object-fit:contain;width:auto}.tribe-events-admin-cta__content,.tribe-events-admin__troubleshooting-cta{align-items:center;display:flex;flex-direction:column;justify-content:center;padding:20px 0;width:100%}.tribe-events-admin-cta__content-title{color:#0f1031;font-size:28px;font-weight:700;line-height:normal;margin:0 0 10px;text-align:center}.tribe-events-admin-cta__content-subtitle{color:#0f1031;font-size:16px;line-height:1.5;margin-bottom:10px;text-align:center}.tribe-events-admin-cta__content-description a{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;font-weight:700;padding-bottom:2px;text-decoration:none}.tribe-events-admin-cta__content-description a:focus{box-shadow:none;outline:none}.tribe-events-admin-cta__content-description a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-footer-logo{display:inline-block;vertical-align:middle;width:228px}.tribe-events-admin-step{margin:10px 0 0}.tribe-events-admin-step-card{border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;padding:24px 15px 19px 19px}.tribe-events-admin-step-card a{border-bottom:2px solid #334aff;color:#334aff;padding-bottom:2px;text-decoration:none}.tribe-events-admin-step-card a:focus{box-shadow:none;outline:none}.tribe-events-admin-step-card a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-step-card__icon img{height:43px;margin-right:5px;width:42px}.tribe-events-admin-step-card__content{margin-left:10px}.tribe-events-admin-step__title{color:#0f1031;font-size:20px;font-weight:700;line-height:1.2;margin-bottom:10px}.tribe-events-admin-step__answer{color:#0f1031;font-size:13px;margin-top:18px}.tribe-events-admin__system-information{display:grid;grid-gap:15px 30px;gap:15px 30px;grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:1fr;margin:100px 0;position:relative}.tribe-events-admin__troubleshooting-title{color:#0f1031;font-size:28px;font-weight:700;line-height:1;margin:0}.tribe-events-admin__troubleshooting-description{color:#0f1031;font-size:18px;line-height:1.2;line-height:1.44;margin:20px 0}.tribe-events-admin__system-information-select{display:flex;margin:30px 0 20px}.tribe-events-admin__system-information-select input[type=checkbox]{margin:0 10px 0 0}.tribe-events-admin__system-information-select label{color:#0f1031;font-size:16px;line-height:1.2}.tribe-events-admin__system-information-content small{color:#0f1031;font-size:12px;line-height:1.2}.tribe-events-admin__recent-template-changes .template-updates-wrapper,.tribe-events-admin__system-information-widget{background:#0f1031;border-radius:16px;color:#fff;font-size:14px;line-height:1.14;max-height:280px;overflow:scroll;-ms-overflow-style:none;padding:12px 0 0 27px;scrollbar-width:none}.tribe-events-admin__system-information-widget a{color:#334aff}.tribe-events-admin__system-information-widget a:hover{opacity:.8}.tribe-events-admin__recent-template-changes .template-updates-wrapper{padding:30px 0 30px 27px}.tribe-events-admin__recent-template-changes .template-updates-wrapper::-webkit-scrollbar,.tribe-events-admin__system-information-widget::-webkit-scrollbar{display:none}.tribe-events-admin__system-information-widget-copy{bottom:10px;position:absolute}.tribe-events-admin__system-information-widget-copy button{background-color:#334aff;border:none;border-radius:100px;color:#fff;cursor:pointer;font-size:16px;font-weight:700;outline:none;padding:18px 25px;text-align:center}.tribe-events-admin__system-information-widget-copy button:hover{background-color:#1c39bb}.tribe-events-admin__system-information-widget-copy button .dashicons,.tribe-events-admin__system-information-widget-copy button .dashicons-before:before{display:none}.tribe-events-admin__system-information-widget-copy button .optin-success{color:#fff;font-size:16px;font-weight:700;text-align:center}.tribe-events-admin__recent-template-changes p{color:#0f1031;font-size:18px;line-height:1.2;line-height:1.44;margin:20px 0}.tribe-events-admin__recent-log{margin-top:50px}.tribe-events-admin__troubleshooting-event-log-wrapper label{color:#0f1031;display:block;font-size:16px;line-height:1.63;margin-bottom:10px}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-controls{margin:20px 0 10px}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-viewer{background:#0f1031;border-radius:16px;color:#fff;font-size:14px;line-height:1.14;max-height:280px;min-height:60px;overflow:scroll;-ms-overflow-style:none;padding:12px 0 0 27px;scrollbar-width:none}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-viewer::-webkit-scrollbar{display:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;padding-bottom:2px;text-decoration:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log:focus{box-shadow:none;outline:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__troubleshooting-event-log-wrapper .tribe-events-admin__recent-log-filters-select-wrapper:after{display:none}.tribe-events-admin__recent-log-filters{display:flex;padding:20px 0 40px}.tribe-events-admin__recent-log-filters-field{margin-right:40px}.tribe-events-admin__recent-log-filters-select-wrapper:after{content:url(../images/help/polygon.svg);height:13px;pointer-events:none;position:absolute;right:22px;top:20px;width:14px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default .select2-selection--single{border:1px solid #e1e1e4!important;border-radius:16px;color:#0f1031;font-size:14px;line-height:1.14;padding:0 25px 0 15px!important}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls{margin-bottom:20px;padding:0}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:first-child,.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(2),.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(3){padding-right:75px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-selection__clear{display:none}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default .select2-selection--single .select2-selection__arrow{right:5px}.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple,.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default.select2-container--open.select2-container--below .select2-selection--single{border-bottom-left-radius:16px;border-bottom-right-radius:16px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container .select2-selection--single .select2-selection__rendered{width:100%}.tribe-events-admin__recent-log-filters-select-wrapper select.focus-visible,.tribe-events-admin__recent-log-filters-select-wrapper select:focus-visible{outline:none}.tribe-events-admin__recent-log-filters-select-wrapper select option{color:#0f1031;font-size:14px;line-height:1.14}.tribe-events-admin__ea-status{margin-top:50px}.tribe-events-admin__issues-found-card{background-color:#f3eee8;border-radius:8px;margin-bottom:20px}.tribe-events-admin__issues-found-card:last-of-type{margin-bottom:100px}.tribe-events-admin__issues-found-card-title{align-items:center;cursor:pointer;display:flex;padding:10px 20px 10px 17px;position:relative}.tribe-events-admin__issues-found-card-title img{height:21px;margin-right:14px;-o-object-fit:contain;object-fit:contain;width:21px}.tribe-events-admin__issues-found-card-title h3{margin:0}.tribe-events-admin__issues-found-card-title span{color:#0f1031;display:block}.tribe-events-admin__issues-found-card-title i{background-image:url(../images/help/arrow-down.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:15px;margin:12px 20px;position:absolute;right:0;top:0;transition:all .3s ease;width:15px}.tribe-events-admin__issues-found-card-title.active i{background-image:url(../images/help/arrow-up.svg);background-repeat:no-repeat;top:5px}.tribe-events-admin__issues-found-card-description{display:none;padding:0 20px 20px 55px}.tribe-events-admin__issues-found-card-description p{color:#0f1031;font-size:16px;margin:0}.tribe-events-admin__issues-found-card-description-actions{display:flex;padding:20px 0 10px}.tribe-events-admin__issues-found-card-description-actions a{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;margin-right:20px;padding-bottom:5px;text-decoration:none}.tribe-events-admin__issues-found-card-description-actions a:focus{box-shadow:none;outline:none}.tribe-events-admin__issues-found-card-description-actions a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__ea-status-table-wrapper{overflow-x:auto}.tribe-events-admin__ea-status-table{border:1px solid #e1e1e4;border-radius:16px;margin:30px 0 40px;overflow:hidden}.tribe-events-admin__ea-status-table a{border-bottom:2px solid #334aff;color:#334aff;padding-bottom:2px;text-decoration:none}.tribe-events-admin__ea-status-table a:focus{box-shadow:none;outline:none}.tribe-events-admin__ea-status-table a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__ea-status-table tr{display:flex;align-items:center}.tribe-events-admin__ea-status-table th{color:#0f1031;font-weight:700;line-height:1.17;margin-top:10px;padding:5px 25px}.tribe-events-admin__ea-status-table td{align-items:center;color:#0f1031;display:flex;font-size:16px;line-height:1.63;padding:10px 25px;width:25%}.tribe-events-admin__ea-status-table td:nth-child(2){width:45%}.tribe-events-admin__ea-status-table td:nth-child(3){display:flex;justify-content:flex-end;width:30%}.tribe-events-admin__ea-status-table-dark{background-color:#f9f7f4}.tribe-events-admin__ea-status-table td img{height:21px;margin-right:14px;-o-object-fit:contain;object-fit:contain;width:21px}.tribe_events_page_tec-troubleshooting{background-color:#fff}#tribe-community,#tribe-ticketing{display:none}.tribe-events-admin__troubleshooting-notice{background-color:#161b7d;color:#fff;font-size:16px;line-height:1;margin-left:-1.55vw;padding:24px 0}.tribe-events-admin__troubleshooting-notice_title{margin:0 auto;max-width:1024px;padding-left:25px;width:90%}.tribe-events-admin__troubleshooting-notice_title a{border-bottom:2px solid #fff;color:#fff;font-size:16px;line-height:1;padding-bottom:2px;text-decoration:none}.tribe-events-admin__troubleshooting-notice_title a:focus{box-shadow:none;outline:none}.tribe-events-admin__troubleshooting-notice_title a:hover{border-bottom:2px solid #f3eee8;color:#f3eee8}.tribe_events_page_tribe-help #tec-help-community,.tribe_events_page_tribe-help #tec-help-ticketing{display:none}.tribe_events_page_tribe-help .tribe-events-admin-title{padding-top:25px}.tribe_events_page_tribe-help .tribe-events-admin-title img{height:67px}body.tribe-welcome #fs_connect{border:1px solid #e1e1e4;border-radius:16px;box-shadow:none;box-sizing:border-box;margin-left:22px}body.tribe-welcome #fs_connect .fs-actions{background-color:transparent}body.tribe-welcome #fs_connect .fs-permissions{border-top:1px solid #e1e1e4;margin:0 16px}body.tribe-welcome #fs_connect button{background-color:#3d54ff;border-color:#3d54ff}body.tribe-welcome #fs_connect .button-secondary{background:#fff;border-color:#3d54ff;color:#3d54ff}body.tribe-welcome #fs_connect a{color:#3d54ff}body.tribe-welcome #fs_connect a:focus{box-shadow:none;outline:none}body.tribe-welcome #fs_connect a:hover{color:#161b7d}@media screen and (max-width:782px){.tribe-half-column,.tribe-row .tribe-half-column:last-child{margin:0 0 20px;width:100%}input[type=email]{width:100%}<<<<<<< HEAD =======>>>>>>>b509f7a664980817599b22fafa19c531746d5b03 .events-cal .subsubsub{float:none}.events-cal .search-box{width:98%}.events-cal #search-submit{width:100%}.events-cal .tablenav.top{display:none}}@media screen and (min-width:500px){.api-check .tribe-mascot{display:block}.api-check .notice-content{margin-right:180px}}@media screen and (min-width:320px){.tribe-marketing-notice .tribe-marketing-notice__icon{display:block}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px}}@media screen and (min-width:600px) and (max-width:782px){.tribe-marketing-notice .tribe-marketing-notice__content{margin-left:145px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px;padding:0}}@media screen and (min-width:782px){.tribe-marketing-notice .tribe-marketing-notice__content{margin-left:130px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px;padding:0}.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe-welcome .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:642px}}@media screen and (min-width:400px){.notice-tribe-banner .tribe-marketing-notice__icon{width:67px}}@media screen and (min-width:800px){.notice-tribe-banner h3{display:inline-block;font-size:1rem;margin:0 .5rem 0 0}.notice-tribe-banner a{line-height:1.5}.notice-tribe-banner a,.notice-tribe-banner p{font-size:1rem}.notice-tribe-banner p{margin:0 .5rem 0 0}.notice-tribe-banner .tribe-marketing-notice__cta{display:inline-block;margin-left:.5rem}}@media screen and (min-width:1215px){.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:992px}.tribe-welcome .notice-tribe-banner .tribe-marketing-notice{max-width:1036px}}@media screen and (min-width:710px){.tribe-events-admin-content-wrapper{width:670px}.tribe-events-admin-card--2up{display:inline-block;width:calc(50% - 20px)}.tribe-events-admin-card--2up.tribe-events-admin-card--first{margin-right:36px}.tribe-events-admin-card--2up.tribe-events-admin-card--last{margin-right:0}.tribe-events-admin-card--2up .tribe-events-admin-card__image{height:100px;margin-bottom:12px}.tribe-events-admin-card--2up .tribe-events-admin-card__title{margin-bottom:27px;max-width:340px}.tribe-events-admin-card--3up{display:inline-block;margin-bottom:32px;width:calc(50% - 18px)}.tribe-events-admin-card--3up.tribe-events-admin-card--first{margin-right:32px}.tribe-events-admin-card--3up.tribe-events-admin-card--middle{margin-right:0}.tribe-events-admin-card__title{font-size:20px;line-height:23px}.tribe-events-admin-section-header{font-size:28px;line-height:32px;margin-bottom:21px}.tribe-events-admin-card--1up{display:inline-block;margin-left:32px;width:calc(50% - 18px)}.tribe-events-admin-card--1up .tribe-events-admin-card__description{height:71px}.tribe-events-admin-card--1up .tribe-events-admin-card__image{margin-bottom:28px}.tribe-events-admin-card--no-pad{height:154px;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{margin-left:50%;padding:42px 0 10px}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin-left:50%}.tribe-events-admin-card--promo-blue{display:block;margin-left:0;min-height:170px;width:100%}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{float:left;max-width:300px}.tribe-events-admin-graphic{max-width:250px;top:0}.tribe-events-admin-graphic--desktop-only{display:block}.tribe-events-admin-graphic--mobile-only{display:none}.tribe-events-admin-card__form{float:right;width:300px}input[type=email].tribe-events-admin-card__input{width:300px}.tribe-events-admin-title{padding-top:50px}.tribe-events-admin-title__description{padding-top:15px}.tribe-events-admin-title__heading{font-size:48px;line-height:55px;margin:0}.tribe-events-admin-title__logo{margin-right:14px;padding-top:5px;width:40px}.tribe-events-admin-tickets .tribe-events-admin-card__title{font-size:18px}.tribe-events-admin-tickets .tribe-events-admin-card--2up .tribe-events-admin-card__title{font-size:18px;height:66px}.tribe-events-admin-tickets .tribe-events-admin-title__logo{margin-right:8px;padding-top:4px;width:60px}}@media screen and (min-width:1217px){.tribe-events-admin-content-wrapper{max-width:1060px;width:100%}.tribe-events-admin-card--2up{margin-right:36px;width:486px}.tribe-events-admin-card--3up{width:310px}.tribe-events-admin-card--3up.tribe-events-admin-card--first,.tribe-events-admin-card--3up.tribe-events-admin-card--middle{margin-right:36px}.tribe-events-admin-card--3up.tribe-events-admin-card--last{margin-right:0}.tribe-events-admin-quick-nav{padding:0 36px}.tribe-events-admin-card--1up{margin:0 0 36px;padding:33px 44px 30px;text-align:left;width:1012px}.tribe-events-admin-card--1up .tribe-events-admin-card__description{height:auto}.tribe-events-admin-card--1up .tribe-events-admin-card__image{float:left;margin:0 48px 10px 0}.tribe-events-admin-card--no-pad{padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__image{margin:0;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{margin-left:50%;padding:42px 0 10px}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin-left:50%}.tribe-events-admin-card--promo-blue{min-height:150px}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{max-width:450px}.tribe-events-admin-graphic{max-width:none}.tribe-events-admin-card__form,input[type=email].tribe-events-admin-card__input{width:365px}.tribe-events-admin-quick-nav{border-radius:100px;display:inline-block;height:54px;margin:24px 0 94px;max-width:1010px;padding:0 36px 0 0}.tribe-events-admin-quick-nav__link-item{display:inline-block;padding:18px 10px 0}.tribe-events-admin-quick-nav__title{padding:19px 6px 17px 32px}.tribe-events-admin-tickets .tribe-events-admin-card--2up .tribe-events-admin-card__title{height:auto}}@media screen and (max-width:768px){.tribe-events-admin-header__logo-word-mark{width:285px}.tribe-events-admin-header__right-image{height:160px}.tribe-events-admin-header__description{max-width:100%}.tribe-events-admin-tab-nav li{margin-right:20px}.tribe-events-admin-tab-nav .selected{border-bottom:2px solid #334aff;padding-bottom:10px}.tribe-events-admin-2col-grid{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr))}.tribe-events-admin-3col-grid{grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr))}.tribe-events-admin-extensions-title{max-width:100%}.tribe-events-admin-cta{align-items:flex-start;flex-direction:column;overflow:hidden}.tribe-events-admin-footer-logo{width:225px}.tribe-events-admin__system-information{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr));margin:50px 0}}@media screen and (max-width:480px){.tribe-events-admin-header__logo-word-mark{width:260px}.tribe-events-admin-header__right-image{height:120px}.tribe-events-admin-header__title{font-size:35px}.tribe-events-admin-header__description{max-width:100%}.tribe-events-admin-tab-nav{border:1px solid #e1e1e4;border-radius:20px;flex-direction:column;padding:18px 22px}.tribe-events-admin-tab-nav li{margin-bottom:18px;margin-right:0}.tribe-events-admin-tab-nav .selected{border-bottom:2px solid #334aff;padding-bottom:10px;width:-moz-fit-content;width:fit-content}.tribe-events-admin__line{border:none}.tribe-events-admin-products-card,.tribe-events-admin-products-description{display:none}.tribe-events-admin-container,.tribe-events-admin-content-wrapper.tribe-events-admin-container{max-width:90%}.tribe-events-admin-2col-grid,.tribe-events-admin-3col-grid,.tribe-events-admin-4col-grid{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr))}.tribe-events-admin-section-header{margin:0}.tribe-events-admin-extensions-title{max-width:100%}.tribe-events-admin-cta__image{height:auto;width:90%}.tribe-events-admin-cta__content,.tribe-events-admin__troubleshooting-cta{align-items:flex-start;padding:32px 23px 45px;width:auto}.tribe-events-admin-cta__content-title{font-size:22px;text-align:left}.tribe-events-admin-cta__content-subtitle{text-align:left}.tribe-events-admin-footer-logo{width:210px}.tribe-events-admin__system-information{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr));margin:50px 0}.tribe-events-admin__troubleshooting-notice{margin-left:-20px}.tribe-events-admin__troubleshooting-notice_title{max-width:90%}}@media screen and (min-width:1200px){.tribe-events-admin-products-card__group{max-width:47%}}@media screen and (min-width:500px) and (max-width:1080px){.tribe-events-admin-4col-grid{grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr))}}@media screen and (max-width:1080px){.tribe-events-admin-cta__content-title{font-size:24px}}@media only screen and (max-width:1920px){.tribe-events-admin__system-information-widget-copy{right:20.5vw}}@media only screen and (max-width:1280px){.tribe-events-admin__system-information-widget-copy{right:22vw}}@media only screen and (max-width:768px){.tribe-events-admin__system-information-widget-copy{left:10px;right:auto}.tribe-events-admin__recent-log-filters{flex-direction:column}.tribe-events-admin__recent-log-filters-field{margin-bottom:30px;margin-right:0}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:first-child,.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(2),.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(3){padding-right:30px}.tribe-events-admin__issues-found-card-title h3{max-width:90%}}@media only screen and (max-width:480px){.tribe-events-admin__system-information-widget-copy{left:10px;right:auto}.tribe-events-admin__recent-log-filters{flex-direction:column}.tribe-events-admin__recent-log-filters-field{margin-bottom:30px;margin-right:0}.tribe-events-admin__recent-log-filters-select-wrapper:after{right:25px}.tribe-events-admin__issues-found-card-title h3{max-width:80%}.tribe-events-admin__ea-status-table{overflow:scroll}.tribe-events-admin__ea-status-table td{min-width:150px}.tribe-events-admin__ea-status-table td:nth-child(2),.tribe-events-admin__ea-status-table td:nth-child(3){width:100%}}
|
1 |
+
.invalid input,input:out-of-range{border:2px solid red!important}.valid input{border:1px solid green}.clearfix{zoom:1}.placeholder{color:#999;cursor:text;padding:4px}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::placeholder,textarea::placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.bubble{background-color:#f9f9f9;border:1px solid #dfdfdf;border-radius:3px;border-spacing:0;padding:10px}.tribe-sticky-tooltip{color:#bbb}td.tribe_message{padding-bottom:10px!important}#tribe_thanks{float:left;margin:5px 0 0;width:200px}.tribe_brand{font-family:Georgia,serif!important;font-size:17px!important;font-weight:400;margin:8px 0}.tribe-rating{color:#3d54ff}.tribe-rating:hover{color:#1c39bb}#tribe-upgrade{background:#f6f6f6;border:1px solid #ccc;border-radius:5px;margin:20px 0 30px;padding:0 20px 20px}#tribe-upgrade .message{background-color:#ffffe0;border:1px solid #e6db55;border-radius:3px;padding:6px 12px}table.plugins .tribe-plugin-update-message{background:#d54e21;color:#fff;display:inline-table;margin:6px 0;padding:10px 12px}table.plugins .tribe-plugin-update-message h4{display:inline;font-weight:700;margin-right:8px}table.plugins .tribe-plugin-update-message h4:after{content:" \00BB "}table.plugins .tribe-plugin-update-message a{color:#fff;text-decoration:underline}.tribe-settings-form{max-width:1000px}.tribe-settings-form fieldset{clear:both;display:inline-block;padding:10px 0}.tribe-settings-form fieldset.tribe-field-license_key legend{width:auto}.tribe-settings-form legend{float:left;font-weight:700;margin-right:20px;width:220px}.tribe-settings-form .tribe-field-wrap{float:left;max-width:500px}.tribe-settings-form .tribe-field-wrap :first-child{margin-top:0}.tribe-settings-form .tribe-field-checkbox_list label,.tribe-settings-form .tribe-field-radio label{display:block;margin:5px 0 5px 20px;text-indent:-20px}.tribe-settings-form .tribe-field-checkbox_list label>p,.tribe-settings-form .tribe-field-radio label>p{margin-left:1px;text-indent:0}.tribe-settings-form .tribe-field-checkbox_list label input,.tribe-settings-form .tribe-field-radio label input{margin-right:5px}.tribe-settings-form .tribe-settings-form-wrap .description,.tribe-settings-form .tribe-settings-form-wrap fieldset,.tribe-settings-form fieldset[id^=tribe-field-geoloc_]{padding-left:12px}.tribe-settings-form .tribe-settings-form-wrap fieldset .description{margin-left:0;max-width:450px;padding-left:0}.tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection{margin-bottom:18px}.tribe-settings-form .tribe-settings-form-wrap #tribe-field-stylesheetOption .description{color:#999;margin-left:1px}.tribe-settings-form .tribe-settings-form-wrap h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}.tribe-settings-form .tribe-settings-form-wrap .contained,.tribe-settings-form .tribe-settings-form-wrap .system-info,.tribe-settings-form .tribe-settings-form-wrap .tribe-sysinfo-optin-msg,.tribe-settings-form .tribe-settings-form-wrap h3+p{margin:0 0 10px;padding-left:12px}.tribe_settings .tribe-field-indent{margin-left:245px}.tribe_settings #pu_dashboard_message{display:none}.tribe_settings .tribe-errors-list{margin-left:15px}.tribe_settings .expiring-license{color:red}.tribe_settings .tribe-error{border:1px solid red}.tribe_settings .tribe-field-description{margin-bottom:0;position:relative;top:-12px}.tribe_settings #ical-link{top:-14px}#modern-tribe-info{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:8px 20px 12px}#modern-tribe-info img{margin:10px 0}#modern-tribe-info ul{list-style:disc;margin-left:20px}#modern-tribe-info ul ul{list-style:circle}.tribe-field-inline-dropdown{margin-left:0;margin-right:0}.tribe-field-inline-text{line-height:28px;margin:0 2px}.tribe-field-textarea.tribe-size-small textarea{height:60px;width:180px}.tribe-field-textarea.tribe-size-medium textarea{height:80px;width:300px}.tribe-field-textarea.tribe-size-large textarea{height:120px;width:450px}.tribe-field-email.tribe-size-small input,.tribe-field-license_key.tribe-size-small input,.tribe-field-text.tribe-size-small input{width:50px}.tribe-field-email.tribe-size-medium input,.tribe-field-license_key.tribe-size-medium input,.tribe-field-text.tribe-size-medium input{width:225px}.tribe-field-email.tribe-size-large input,.tribe-field-license_key.tribe-size-large input,.tribe-field-text.tribe-size-large input{width:450px}.tribe-field-dropdown.tribe-size-small select{width:100px}.tribe-field-dropdown.tribe-size-medium select{width:300px}.tribe-field-dropdown.tribe-size-large select{width:450px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap{max-width:600px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap .description{max-width:100%}.tribe-field-dropdown_chosen.tribe-size-small select{width:100px}.tribe-field-dropdown_chosen.tribe-size-medium select{width:200px}.tribe-field-dropdown_chosen.tribe-size-large select{width:300px}.tribe-field-wrap .tooltip:first-child{font-style:normal}.tribe-field.indent{margin-left:252px;width:75%}.tribe-field.indent legend{font-weight:400;width:auto}.tribe-field.indent .tribe-field-wrap{padding-right:12px}.tribe-field.indent.tribe-field-radio .tribe-field-wrap{clear:left;margin-top:12px}.tribe-field.light-bordered{background-color:#fff;border:1px solid #d3d3d3}.ajax-loading-license,.invalid-key,.valid-key{display:none;margin:0 5px}.ajax-loading-license{position:relative;top:5px}.key-validity{display:inline-block}.invalid-key,.optin-fail{color:red}.optin-success,.valid-key{color:green}.valid-key.service-msg{color:#b72}#additional-field-table{margin-bottom:20px}.tribe-admin-box-left{float:left;width:20%}.tribe-admin-box-left,.tribe-admin-box-right{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:0 20px 15px}.tribe-admin-box-right{float:right;width:68%}.ajax-loader{float:right;margin:10px}.tribe-arrangeable-item{border:1px solid #d3d3d3;border-radius:3px}.tribe-arrangeable-item .ui-state-default{border:none}.tribe-arrangeable-item-top{padding:6px}.tribe-arrangeable-item-top:hover{cursor:move}.tribe-arrangeable-action{float:right}.tribe-arrangeable-child{background-color:#f9f9f9;border-top:1px solid #d3d3d3;display:none;padding:25px}.tribe-arrangeable-child label{display:block;margin:0 0 7px}.tribe_events_active_filter_type_options{margin:10px 0}.tribe_events_active_filter_type_options label{margin:7px 0}#event_organizer td small,.OrganizerInfo td small{display:block;margin:0;max-width:250px}#event_organizer .organizer-email,.OrganizerInfo .organizer-email{vertical-align:top}.tribe-table-field-label{max-width:100%;width:200px}#tribe-help-general,#tribe-help-sidebar{float:left;margin-top:20px}#tribe-help-general p{margin-left:15px}#tribe-help-general ul{list-style-type:square}#tribe-help-general ol,#tribe-help-general ul{margin-bottom:20px;margin-left:35px}#tribe-help-general h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}#tribe-help-general h3~h3{margin-top:2.25em}#tribe-help-general h3+p{margin:0 0 20px;padding-left:12px}#tribe-help-general{width:65%}.tribe-help-section{padding-bottom:10px}.tribe-section-type-box{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;padding:8px 20px 12px}.tribe-section-type-box img{height:auto;margin:10px 0;max-width:300px}.tribe-section-type-box ul{list-style:disc;margin-left:20px}.tribe-section-type-box ul ul{list-style:circle}#tribe-log-controls{padding-bottom:1rem;padding-left:12px}#tribe-log-controls>div{display:inline-block;padding-right:1rem}#tribe-log-controls .working{opacity:1;transition:opacity .2s}#tribe-log-controls .working.hidden{opacity:0;transition:opacity .2s}#tribe-log-viewer,#tribe-system-info dl.support-stats,.template-updates-wrapper{background:#000;border-radius:2px;color:#888;max-height:400px;overflow:scroll;padding:10px}#tribe-system-info dl.support-stats dt,.template-updates-wrapper dt{clear:both;float:left;font-weight:700;text-transform:uppercase;width:25%}#tribe-system-info dl.support-stats dd,.template-updates-wrapper dd{margin-left:25%;padding-left:10px}.system-info-copy .system-info-copy-btn{padding:6px}.system-info-copy .system-info-copy-btn .dashicons{padding-right:10px}.template-updates-wrapper p{margin-top:0}#tribe-help-sidebar{margin:20px 0 0 3%;max-width:225px;width:32%}.tribe-help-plugin-info{border:1px solid #ccc;padding:0 12px 12px}.tribe-help-plugin-info dd,.tribe-help-plugin-info dt{display:inline;margin:0}.tribe-help-plugin-info dt{font-weight:700}.tribe-help-plugin-info dd:after{content:"";display:block;height:.4em}.tribe-help-plugin-info dd:last-child:after{height:0}.tribe-help-plugin-info+.tribe-help-plugin-info{margin-top:20px}.tribe-help-plugin-info>div{line-height:2em}.tribe-help-plugin-info .star-rating{display:inline-block;margin-left:3px;position:relative;top:-2px}.tribe-help-plugin-info .tribe-list-addons{color:#21a6cb;font-size:24px;list-style:circle inside;margin-bottom:10px;margin-top:10px;padding-left:4px}.tribe-help-plugin-info .tribe-list-addons a{font-size:13px;left:-5px;position:relative;top:-5px}.tribe-help-plugin-info .tribe-list-addons .tribe-active-addon{list-style:disc inside}.ui-widget-overlay{background:#666;filter:alpha(opacity=50);opacity:.5}.ui-widget-shadow{background:#000;border-radius:5px;filter:alpha(opacity=20);margin:-5px 0 0 -5px;opacity:.2;padding:5px}.ui-resizable{position:relative}.ui-resizable-handle{display:block;font-size:.1px;position:absolute;z-index:99999}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;left:0;top:-5px;width:100%}.ui-resizable-s{bottom:-5px;cursor:s-resize;height:7px;left:0;width:100%}.ui-resizable-e{cursor:e-resize;height:100%;right:-5px;top:0;width:7px}.ui-resizable-w{cursor:w-resize;height:100%;left:-5px;top:0;width:7px}.ui-resizable-se{bottom:1px;cursor:se-resize;height:12px;right:1px;width:12px}.ui-resizable-sw{bottom:-5px;cursor:sw-resize;height:9px;left:-5px;width:9px}.ui-resizable-nw{cursor:nw-resize;height:9px;left:-5px;top:-5px;width:9px}.ui-resizable-ne{cursor:ne-resize;height:9px;right:-5px;top:-5px;width:9px}.ui-dialog{padding:.2em;position:relative;width:375px}.ui-dialog .ui-dialog-titlebar{padding:.5em .3em .3em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0 .2em}.ui-dialog .ui-dialog-titlebar-close{height:18px;margin:-10px 0 0;padding:1px;position:absolute;right:.3em;top:50%;width:19px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin-left:-8px;margin-top:-8px}.ui-dialog .ui-dialog-titlebar-close:focus,.ui-dialog .ui-dialog-titlebar-close:hover{padding:0}.ui-dialog .ui-dialog-content{background:none;border:0;overflow:auto;padding:.5em 1em;zoom:1}.ui-dialog .ui-dialog-buttonpane{background-image:none;border-width:1px 0 0;margin:.5em 0 0;padding:.3em 1em .5em!important;text-align:right}.ui-dialog .ui-dialog-buttonpane button{cursor:pointer;line-height:1.4em;margin:.5em .4em!important;overflow:visible;padding:.2em .6em .3em;text-shadow:none;width:auto}.ui-dialog .ui-resizable-se{bottom:3px;height:14px;right:3px;width:14px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:none!important;text-align:center}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button .ui-button-text{display:block;line-height:1.4}#ui-datepicker-div{display:none}#tribe-loading{background:#fff;background:hsla(0,0%,100%,.8);display:none;height:100%;left:0;position:absolute;top:0;transition:all 1s linear;width:100%;z-index:4}#tribe-loading span{background:url(../images/tribe-loading.gif) 0 0 no-repeat;background-size:32px 32px;height:32px;left:50%;margin:-16px 0 0 -16px;position:absolute;top:50%;width:32px}.tribe_update_page{max-width:850px}.tribe-half-column{float:left;margin-bottom:30px;margin-right:5%;width:45%}.tribe-row:after,.tribe-row:before{content:"";display:table}.tribe-row,.tribe-row:after{clear:both}.tribe-row .tribe-half-column:last-child{margin-right:0;width:50%}.tribe_update_page h2{font-size:30px;line-height:1.2;margin-bottom:20px}.tribe_update_page h3{font-size:24px;font-weight:400;line-height:24px;margin-top:0}.tribe_update_page h4{font-size:18px;font-weight:600;line-height:18px;margin:0}.tribe_update_page p{font-size:15px}p.tribe-update-message{font-size:18px;font-weight:400}.tribe_update_page h4:before{content:"\f145";font-family:dashicons;font-size:34px;line-height:1;margin-right:5px;position:relative;top:5px}a.tribe-rating-link{text-decoration:none}.tribe-update-links{margin-top:30px}.tribe_update_page li:before{content:"\2022";padding-right:3px}.tribe_update_page .rss-widget{margin:1em 0}.tribe_update_page a.rsswidget{font-size:14px;font-weight:400;line-height:1}.tribe_update_page .rss-widget li:before{display:none}.tribe-events-widget-admin-form__input-section p{margin:0}.tribe-events-widget-admin-form__input-section h4{margin:.5em 0}.tribe-update-bar{display:inline-block}.tribe-update-bar .progress{border:1px solid #ccc;float:left;margin-right:1rem;padding:1px;width:18rem}.tribe-update-bar .progress .bar{background:#7ad03a;height:1rem;width:1%}#tribe-dialog-wrapper>div{padding:1rem}#tribe-dialog-wrapper>div .stage{display:none}#tribe-dialog-wrapper #heading{background:#fff}#tribe-dialog-wrapper label{display:block}#tribe-dialog-wrapper .select-single-container{border:1px solid #888;height:300px;overflow-y:scroll}#tribe-dialog-wrapper .select-single-container label{opacity:1;padding:3px 5px;transition:opacity .2s}#tribe-dialog-wrapper .select-single-container label:nth-child(odd){background:#fff}#tribe-dialog-wrapper .select-single-container label.selected{background:#0073aa;color:#fff;font-weight:700}#tribe-dialog-wrapper .select-single-container label input{display:none}#tribe-dialog-wrapper .select-single-container.updating label{opacity:.35;transition:opacity .2s}.ui-front{z-index:1000000}.wp-list-table.plugins .column-description .update-message{color:#d54e21}.api-check{min-height:100px;padding:1em}.api-check+.notice-dismiss:hover:before{color:#fff}.api-check:after,.api-check:before{content:"";display:table}.api-check:after{clear:both}.api-check .tribe-mascot{bottom:0;display:none;padding:0 1rem 0 0;position:absolute;right:0;top:0}.api-check .tribe-mascot img{display:inline-block;height:100%;max-height:150px;max-width:150px;vertical-align:middle;width:auto}.api-check p{line-height:1.7;margin-bottom:1em}.api-check a{text-decoration:none}.api-check a:hover{text-decoration:underline}.api-check .plugin-list{display:inline;font-weight:600;margin:0;padding:0}.api-check .plugin-list span.plugin-invalid:after{content:", "}.api-check .plugin-list span.plugin-invalid:last-of-type:after{content:""}.tribe-marketing-notice{padding:1em}.tribe-marketing-notice+.notice-dismiss:hover:before{color:#fff}.tribe-marketing-notice:after,.tribe-marketing-notice:before{content:"";display:table}.tribe-marketing-notice:after{clear:both}.tribe-marketing-notice .tribe-marketing-notice__icon{display:none;flex-shrink:0;padding:0;position:static}.tribe-marketing-notice .tribe-marketing-notice__icon img{display:inline-block;max-height:100%;max-width:none;vertical-align:middle;width:100%}.tribe-marketing-notice h3{margin-bottom:.5em;margin-top:.5em}.tribe-marketing-notice p{line-height:1.7;margin-bottom:.5em}.tribe-marketing-notice a{text-decoration:none}.tribe-marketing-notice a:hover{text-decoration:underline}#wpcontent .notice-tribe-banner{align-items:center;background:#161b7d;border:0;box-shadow:none;display:flex;justify-content:flex-start;margin:0 0 16px;padding-right:0}.notice-tribe-banner .tribe-marketing-notice__icon{width:47px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:0;padding:1em 0}.notice-tribe-banner h3{color:#fff;display:block;font-size:.875rem;line-height:1.25;margin:0 0 .25rem}.notice-tribe-banner a{border-bottom:1px solid #fff;line-height:1.25;margin:0;text-decoration:none}.notice-tribe-banner a:hover{text-decoration:none}.notice-tribe-banner a,.notice-tribe-banner p{color:#fff;display:inline-block;font-size:.875rem;line-height:1.25}.notice-tribe-banner p{display:inline-block;margin:0;padding:0}.notice-tribe-banner .tribe-marketing-notice{align-items:center;display:flex;justify-content:flex-start;margin:0 auto;min-height:65px;padding:0 .75rem;width:100%}.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe-welcome .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:100%}.notice-tribe-banner .notice-dismiss{position:static}.notice-tribe-banner .notice-dismiss:before{color:#eaf1ff}.tribe-dropdown,.tribe-ea-dropdown{max-width:100%;width:auto}.tribe-dropdown.select2-container .selection,.tribe-ea-dropdown.select2-container .selection{margin-top:inherit}.tribe-dropdown .select2-selection--single,.tribe-ea-dropdown .select2-selection--single{height:32px}.tribe-dropdown .select2-selection--single .select2-selection__clear,.tribe-ea-dropdown .select2-selection--single .select2-selection__clear{line-height:28px}.tribe-dropdown .select2-selection--single .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--single .select2-selection__rendered{line-height:32px;padding-right:28px}.tribe-dropdown.select2-container--focus .select2-selection--single,.tribe-ea-dropdown.select2-container--focus .select2-selection--single{border-color:#5897fb;box-shadow:0 0 5px rgba(0,0,0,.1)}.tribe-dropdown.select2-container--open .select2-search__field,.tribe-ea-dropdown.select2-container--open .select2-search__field{padding:0}.tribe-dropdown.select2-container--open .select2-dropdown--below,.tribe-ea-dropdown.select2-container--open .select2-dropdown--below{border-top:1px solid #aaa;margin-top:-1px}.tribe-dropdown.select2-container--open .select2-dropdown--above,.tribe-ea-dropdown.select2-container--open .select2-dropdown--above{border-bottom:1px solid #aaa;margin-bottom:-16px}.tribe-dropdown.select2-container--open .select2-selection--single,.tribe-ea-dropdown.select2-container--open .select2-selection--single{border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:#aaa}.tribe-dropdown.select2-container--open .select2-selection__arrow b,.tribe-ea-dropdown.select2-container--open .select2-selection__arrow b{transform:rotate(180deg)}.tribe-dropdown.select2-selection--single,.tribe-ea-dropdown.select2-selection--single{background-image:none;border:1px solid #ccc;border-radius:3px;overflow:hidden}.tribe-dropdown.select2-selection--single>.select2-selection__rendered,.tribe-ea-dropdown.select2-selection--single>.select2-selection__rendered{white-space:normal}.tribe-dropdown.select2-selection--single .select2-selection__arrow,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow{background:transparent;background-image:none;border-left:0;top:2px;width:26px}.tribe-dropdown.select2-selection--single .select2-selection__arrow b,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow b{background:#fff url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E") no-repeat right 5px top 55%;background-size:auto;background-size:16px 16px;border:0;bottom:0;display:block;height:auto;left:0;margin:0;padding:0;right:0;top:0;width:auto}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered{background-image:none;border:1px solid #ccc;border-radius:3px;min-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline{line-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input{padding-bottom:0;padding-top:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice{line-height:19px;margin-top:2px;padding-bottom:0;padding-top:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div{line-height:inherit}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove{left:4px;top:3px;transition-property:border,color}.select2-results .select2-results__option{color:#939393;font-weight:400;margin-bottom:0}.select2-results .select2-results__option[aria-disabled=true]{background-color:#e0e0e0}.select2-results.select2-results__option--highlighted{background-color:#efefef;color:#a1a1a1;cursor:default;display:block}.wp-core-ui .button-red{background-color:#a00;border-color:#9b2124;box-shadow:inset 0 1px 0 rgba(120,200,230,.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red.hover,.wp-core-ui .button-red:focus,.wp-core-ui .button-red:hover{background-color:#a00;border-color:#7f1c1f;box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.3)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red:focus{border-color:#500f0e;box-shadow:inset 0 1px 0 rgba(120,200,230,.6),1px 1px 2px rgba(0,0,0,.4)}.wp-core-ui .button-red.active,.wp-core-ui .button-red.active:focus,.wp-core-ui .button-red.active:hover,.wp-core-ui .button-red:active{background:#7f1c1f;border-color:#601312 #ae2426 #ae2426;box-shadow:inset 0 1px 0 rgba(0,0,0,.1);color:hsla(0,0%,100%,.95);text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red-disabled,.wp-core-ui .button-red:disabled,.wp-core-ui .button-red[disabled]{background:#ba292b!important;border-color:#7f1c1f!important;box-shadow:none!important;color:#e79496!important;cursor:default;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important}.ticket_form .select2-container .select2-selection--single .select2-selection__arrow{display:none}.clear{zoom:1}.clear:after,.clear:before{content:" ";display:table}.clear:after{clear:both}.checkmark:after{border:solid #0ab152;border-width:0 3px 3px 0;content:"";display:block;height:15px;transform:rotate(45deg);width:8px}.checkmark.checkmark-right:after{float:right;margin-right:2em}.checkmark.checkmark-left:after{float:left;margin-left:2em}.checkmark.no-checkmark:after{display:none}.complete,.ok,.on,.yes,[data-status=complete],[data-status=ok],[data-status=on],[data-status=yes]{color:#0ab152}.incomplete,.ko,.no,.off,[data-status=incomplete],[data-status=ko],[data-status=no],[data-status=off]{color:#ff2500}.plugin-card-event-tickets-plus .column-downloaded,.plugin-card-event-tickets-plus .column-rating,.plugin-card-event-tickets-plus .column-updated,.plugin-card-event-tickets .column-downloaded,.plugin-card-event-tickets .column-rating,.plugin-card-event-tickets .column-updated,.plugin-card-events-calendar-pro .column-downloaded,.plugin-card-events-calendar-pro .column-rating,.plugin-card-events-calendar-pro .column-updated,.plugin-card-events-community-tickets .column-downloaded,.plugin-card-events-community-tickets .column-rating,.plugin-card-events-community-tickets .column-updated,.plugin-card-events-community .column-downloaded,.plugin-card-events-community .column-rating,.plugin-card-events-community .column-updated,.plugin-card-image-widget-plus .column-downloaded,.plugin-card-image-widget-plus .column-rating,.plugin-card-image-widget-plus .column-updated,.plugin-card-image-widget .column-downloaded,.plugin-card-image-widget .column-rating,.plugin-card-image-widget .column-updated,.plugin-card-the-events-calendar .column-downloaded,.plugin-card-the-events-calendar .column-rating,.plugin-card-the-events-calendar .column-updated,.plugin-card-tribe-eventbrite .column-downloaded,.plugin-card-tribe-eventbrite .column-rating,.plugin-card-tribe-eventbrite .column-updated,.plugin-card-tribe-filterbar .column-downloaded,.plugin-card-tribe-filterbar .column-rating,.plugin-card-tribe-filterbar .column-updated{display:none}.tribe-events-admin-content-wrapper{font-style:normal;margin:0 auto;padding:20px;width:calc(100% - 40px)}.tribe-events-admin-card{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;display:block;margin:0 auto 36px;padding:27px;text-align:center}.tribe-events-admin-card--2up .tribe-events-admin-card__title{max-width:260px}.tribe-events-admin-card--3up .tribe-events-admin-card__description{height:71px}.tribe-events-admin-card--3up .tribe-events-admin-card__image{margin-bottom:28px}.tribe-events-admin-card__button{background-color:#fff;border:none;color:#3d54ff;font-size:14px;font-weight:700;letter-spacing:1px;line-height:16px;position:absolute;right:20px;text-transform:uppercase;top:17px}.tribe-events-admin-card__button:hover{color:#161b7d}.tribe-events-admin-card__description{color:#000;font-size:14px;font-style:normal;font-weight:400;line-height:22px;margin-top:16px}.tribe-events-admin-card__image{display:block;height:100px;margin:0 auto}.tribe-events-admin-card__link{color:#3d54ff;display:inline-block;font-size:16px;font-style:normal;font-weight:700;line-height:18px;margin-top:24px;position:relative;text-decoration:none}.tribe-events-admin-card__link:hover{color:#161b7d}.tribe-events-admin-card__link:after{border-style:solid;border-width:0 0 1px;bottom:-4px;content:"";left:0;position:absolute;width:100%}.tribe-events-admin-card__title{color:#0f1031;font-size:20px;font-weight:700;line-height:23px;margin:auto}.tribe-events-admin-card-grid{max-width:1048px}.tribe-events-admin-section-header{color:#000;font-size:24px;font-weight:700;line-height:28px;margin:21px 0 24px}input[type=checkbox].tribe-common-switch__input{display:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label{background:#fff;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;cursor:pointer;display:block;height:18px;outline:0;padding:3px;position:relative;transition:all .2s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:27px}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:after,input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:before{content:"";display:block;height:10px;position:relative;width:10px}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:after{background:#878787;border-radius:2px;content:"";left:0;transition:all .2s ease}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:before{display:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label::-moz-selection{background:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label::selection{background:none}input[type=checkbox].tribe-common-switch__input:checked+.tribe-common-switch__label:after{background:#2e709d;left:50%}body.tribe-welcome,body.tribe_events_page_tribe-help{background-color:#fff;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}body.tribe-welcome .update-nag,body.tribe_events_page_tribe-help .update-nag{display:none}body.tribe-welcome #wpcontent,body.tribe_events_page_tribe-help #wpcontent{padding:0}body.tribe-welcome .tribe_settings,body.tribe_events_page_tribe-help .tribe_settings{margin:0}body.tribe-welcome #wpfooter,body.tribe-welcome .tribe_settings>h1,body.tribe_events_page_tribe-help #wpfooter,body.tribe_events_page_tribe-help .tribe_settings>h1{display:none}body.tribe-welcome #wpbody-content,body.tribe_events_page_tribe-help #wpbody-content{padding-bottom:25px}body.tribe-welcome .tribe-dependency-error,body.tribe_events_page_tribe-help .tribe-dependency-error{display:none}.tribe-events-admin-header__logo-word-mark{display:inline-block;height:auto;margin:0 0 26px;vertical-align:middle;width:312px}.tribe-events-admin-content-wrapper{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding:0 0 30px}.tribe-events-admin-header{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding:45px 0 0}.tribe-events-admin-header__right-image{height:280px;position:absolute;right:0;top:0;width:auto;z-index:-1}.tribe-events-admin-header__title{font-size:48px;line-height:48px;margin:0 0 18px}.tribe-events-admin-header__description{font-size:18px;line-height:28px;margin-bottom:44px;max-width:60%}.tribe-events-admin-tab-nav{display:flex;margin:0}.tribe-events-admin-tab-nav li{cursor:pointer;font-size:16px;font-weight:500;margin-bottom:0;margin-right:30px}.tribe-events-admin-tab-nav li:hover{color:#334aff}.tribe-events-admin-tab-nav .selected{border-bottom:3px solid #334aff;color:#334aff;padding-bottom:17px}.tribe-events-admin-tab-nav li:after{background:#334aff;border-radius:100px;bottom:0;content:"";display:block;height:3px;left:0;position:absolute;right:0}.tribe-events-admin__line{border-top:1px solid #e1e1e4}.tribe-events-admin-products-description{color:#0f1031;font-size:14px;line-height:2}.tribe-events-admin-products-card{align-items:center;border:1px solid #e1e1e4;border-radius:20px;display:flex;padding:10px 15px}.tribe-events-admin-products-card__icon{height:40px;-o-object-fit:contain;object-fit:contain;width:40px}.tribe-events-admin-products-card__group{margin:0 20px;max-width:55%}.tribe-events-admin-products-card__group-title{color:#0f1031;font-size:16px;font-weight:700;line-height:1;margin:0}.tribe-events-admin-products-card__group-description{font-size:12px;margin-top:5px}.tribe-events-admin-products-card__button{background-color:#fff;border:1px solid #e1e1e4;border-radius:20px;color:#0f1031;font-size:12px;font-weight:700;letter-spacing:1px;line-height:16px;margin-left:auto;padding:10px 15px;text-decoration:none;text-transform:uppercase}.tribe-events-admin-products-card__button:hover{background-color:#334aff;color:#fff}.tribe-events-admin-products-card__button:active,.tribe-events-admin-products-card__button:focus{box-shadow:none;outline:none}.tribe-events-admin-products-card__button--active,.tribe-events-admin-products-card__button--active:active,.tribe-events-admin-products-card__button--active:focus,.tribe-events-admin-products-card__button--active:hover{background:rgba(61,84,255,.16);color:#334aff;cursor:not-allowed;text-transform:uppercase}.tribe-events-admin-card--1up{width:100%}.tribe-events-admin-card--no-pad{padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__image{display:block;height:152px;margin:0;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{font-size:28px;line-height:34px;text-align:left}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin:0;padding:0;text-align:left}.tribe-events-admin-card--no-pad .tribe-events-admin-card__link{margin:0;padding:0}.tribe-events-admin-card--faq{display:inline-block;font-size:0;height:147px;margin:0 0 0 30px;padding:24px 16px 22px 20px;width:230px}.tribe-events-admin-card--faq:first-child{margin-left:0}.tribe-events-admin-card--faq img{float:left;height:22px;width:16px}.tribe-events-admin-card--faq .tribe-events-admin-faq__question{color:#334aff;font-size:16px;line-height:19px;margin:0 0 12px 26px;text-align:left}.tribe-events-admin-card--faq .tribe-events-admin-faq__answer{font-size:13px;line-height:16px;margin-left:26px;text-align:left}.tribe-events-admin-video{border-radius:16px;height:200px;margin-bottom:72px;-webkit-mask-image:-webkit-radial-gradient(circle,#fff 100%,#000 0);overflow:hidden;-webkit-transform:rotate(.000001deg)}.tribe-events-admin-video iframe{width:100%}.tribe-events-admin-card--promo-blue{background-color:#3d54ff;background-image:url(../images/welcome/promo.jpg)}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{color:#fff;font-size:16px;margin-bottom:16px;text-align:left}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__title{color:#fff;text-align:left}.tribe-events-admin-graphic{position:absolute;right:0;top:106px;z-index:-1}.tribe-events-admin-graphic--desktop-only{display:none}.tribe-events-admin-graphic--mobile-only{display:block}.tribe-events-admin-card__form{position:relative}input[type=email].tribe-events-admin-card__input{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;font-size:14px;height:54px}input[type=email].tribe-events-admin-card__input:-ms-input-placeholder{color:rgba(15,16,49,.72);letter-spacing:.5px;padding-left:10px}input[type=email].tribe-events-admin-card__input::placeholder{color:rgba(15,16,49,.72);letter-spacing:.5px;padding-left:10px}.tribe-events-admin-container,.tribe-events-admin-content-wrapper.tribe-events-admin-container{margin:0 auto;max-width:1024px;width:90%}.tribe-events-admin-2col-grid{display:grid;grid-gap:15px 30px;gap:15px 30px;grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-3col-grid{display:grid;grid-gap:30px;gap:30px;grid-template-areas:". . .";grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-4col-grid{display:grid;grid-gap:30px;gap:30px;grid-template-areas:". . . .";grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-products{margin:10px 0 0}.tribe-events-admin-quick-nav{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;display:block;margin:40px 0 78px;padding:18px 23px 2px}.tribe-events-admin-quick-nav__link{color:#3d54ff;font-size:16px;font-weight:700;line-height:18px;text-align:center;text-decoration:none}.tribe-events-admin-quick-nav__link:hover{color:#161b7d}.tribe-events-admin-quick-nav__link-item{display:block;padding-bottom:19px}.tribe-events-admin-quick-nav__links{display:inline}.tribe-events-admin-quick-nav__title{color:rgba(15,16,49,.72);display:inline-block;font-size:14px;font-weight:400;line-height:16px;padding-bottom:14px;text-transform:uppercase}.tribe-events-admin-title{padding-top:14px}.tribe-events-admin-title__description{color:#0f1031;font-size:16px;font-weight:400;line-height:24px;max-width:584px;padding-top:15px}.tribe-events-admin-title__heading{color:#0f1031;display:inline-block;font-size:24px;font-weight:700;line-height:28px;margin:5px 0 0}.tribe-events-admin-title__logo{margin-right:8px;vertical-align:top;width:34px}.tribe-events-admin-notice{background-color:#3d54ff;height:65px}.tribe-events-admin-notice .tribe-events-admin-content-wrapper{padding-bottom:0;padding-top:8px}.tribe-events-admin-notice p{color:#fff;display:inline-block;font-family:Helvetica;font-size:16px;line-height:18px;margin-top:0;padding-bottom:12px;padding-left:16px;vertical-align:middle;width:calc(100% - 60px)}.tribe-events-admin-notice__logo{display:inline-block}.tribe-events-admin-tickets .tribe-events-admin-section-header{font-size:28px;line-height:32px}.tribe-events-admin-tickets .tribe-events-admin-graphic--desktop-only{width:365px}.tribe-events-admin-tickets .tribe-events-admin-graphic--mobile-only{top:230px;width:300px}.tribe-events-admin-tickets .tribe-events-admin-title__heading{margin-top:0}.tribe-events-admin-tickets .tribe-events-admin-title__logo{margin-right:4px;width:32px}.tribe-events-admin-kb{margin:10px 0 0}.tribe-events-admin-kb-card{border:1px solid #e1e1e4;border-radius:20px}.tribe-events-admin-kb-card__image{height:auto;width:100%}.tribe-events-admin-kb-card__title{color:#0f1031;flex-grow:0;font-size:20px;font-weight:700;line-height:1.2;margin:0;padding:20px 28px 10px}.tribe-events-admin-kb-card__links{margin:0;padding:0 28px 25px}.tribe-events-admin-kb-card__links li{margin:0 0 10px}.tribe-events-admin-kb-card__links li a{color:#334aff;font-size:14px;line-height:1.2;text-decoration:none}.tribe-events-admin-kb-card__links li a:focus{box-shadow:none;outline:none}.tribe-events-admin-kb-card__links li a:hover{color:#1c39bb}.tribe-events-admin-section-header{align-items:center;display:flex;justify-content:space-between;margin:50px 0 0}.tribe-events-admin-section-header h3{color:#0f1031;font-size:28px;font-weight:700;line-height:1}.tribe-events-admin-section-header a{border-bottom:2px solid #334aff;color:#334aff;font-size:14px;padding-bottom:2px;text-decoration:none}.tribe-events-admin-section-header a:focus{box-shadow:none;outline:none}.tribe-events-admin-section-header a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-faq{margin:10px 0 0}.tribe-events-admin-faq-card{border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;padding:24px 15px 19px 19px}.tribe-events-admin-faq-card a{color:#0f1031}.tribe-events-admin-faq-card a:focus{box-shadow:none;outline:none}.tribe-events-admin-faq-card a:hover{color:#1c39bb}.tribe-events-admin-faq-card__icon img{height:22px;width:16px}.tribe-events-admin-faq-card__content{margin-left:10px}.tribe-events-admin-faq__question,.tribe-events-admin-faq__question a{color:#334aff;font-size:16px;text-decoration:none}.tribe-events-admin-faq__question a:focus{box-shadow:none;outline:none}.tribe-events-admin-faq__question a:hover{color:#1c39bb}.tribe-events-admin-faq__answer{color:#0f1031;font-size:13px;margin-top:18px}.tribe-events-admin-extensions-title{color:#0f1031;font-size:16px;line-height:1.5;margin:0 0 30px;max-width:70%}.tribe-events-admin-extensions{margin:10px 0 0}.tribe-events-admin-extensions-card{border:1px solid #e1e1e4;border-radius:20px;border-top:8px solid #334aff;padding:48px 35px 24px 25px}.tribe-events-admin-extensions-card__title{font-size:20px;margin:0}.tribe-events-admin-extensions-card__title a{color:#0f1031;font-family:Helvetica;font-size:20px;font-weight:700;line-height:1.2;text-decoration:none}.tribe-events-admin-extensions-card__title a:active,.tribe-events-admin-extensions-card__title a:focus,.tribe-events-admin-extensions-card__title a:hover{box-shadow:none;color:#334aff}.tribe-events-admin-extensions-card__description{color:#0f1031;font-family:Helvetica;font-size:14px;line-height:1.43;margin:20px 0}.tribe-events-admin-cta{align-items:center;border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;margin:60px 0}.tribe-events-admin-cta__image{height:152px;-o-object-fit:contain;object-fit:contain;width:auto}.tribe-events-admin-cta__content,.tribe-events-admin__troubleshooting-cta{align-items:center;display:flex;flex-direction:column;justify-content:center;padding:20px 0;width:100%}.tribe-events-admin-cta__content-title{color:#0f1031;font-size:28px;font-weight:700;line-height:normal;margin:0 0 10px;text-align:center}.tribe-events-admin-cta__content-subtitle{color:#0f1031;font-size:16px;line-height:1.5;margin-bottom:10px;text-align:center}.tribe-events-admin-cta__content-description a{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;font-weight:700;padding-bottom:2px;text-decoration:none}.tribe-events-admin-cta__content-description a:focus{box-shadow:none;outline:none}.tribe-events-admin-cta__content-description a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-footer-logo{display:inline-block;vertical-align:middle;width:228px}.tribe-events-admin-step{margin:10px 0 0}.tribe-events-admin-step-card{border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;padding:24px 15px 19px 19px}.tribe-events-admin-step-card a{border-bottom:2px solid #334aff;color:#334aff;padding-bottom:2px;text-decoration:none}.tribe-events-admin-step-card a:focus{box-shadow:none;outline:none}.tribe-events-admin-step-card a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-step-card__icon img{height:43px;margin-right:5px;width:42px}.tribe-events-admin-step-card__content{margin-left:10px}.tribe-events-admin-step__title{color:#0f1031;font-size:20px;font-weight:700;line-height:1.2;margin-bottom:10px}.tribe-events-admin-step__answer{color:#0f1031;font-size:13px;margin-top:18px}.tribe-events-admin__system-information{display:grid;grid-gap:15px 30px;gap:15px 30px;grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:1fr;margin:100px 0;position:relative}.tribe-events-admin__troubleshooting-title{color:#0f1031;font-size:28px;font-weight:700;line-height:1;margin:0}.tribe-events-admin__troubleshooting-description{color:#0f1031;font-size:18px;line-height:1.2;line-height:1.44;margin:20px 0}.tribe-events-admin__system-information-select{display:flex;margin:30px 0 20px}.tribe-events-admin__system-information-select input[type=checkbox]{margin:0 10px 0 0}.tribe-events-admin__system-information-select label{color:#0f1031;font-size:16px;line-height:1.2}.tribe-events-admin__system-information-content small{color:#0f1031;font-size:12px;line-height:1.2}.tribe-events-admin__recent-template-changes .template-updates-wrapper,.tribe-events-admin__system-information-widget{background:#0f1031;border-radius:16px;color:#fff;font-size:14px;line-height:1.14;max-height:280px;overflow:scroll;-ms-overflow-style:none;padding:12px 0 0 27px;scrollbar-width:none}.tribe-events-admin__system-information-widget a{color:#334aff}.tribe-events-admin__system-information-widget a:hover{opacity:.8}.tribe-events-admin__recent-template-changes .template-updates-wrapper{padding:30px 0 30px 27px}.tribe-events-admin__recent-template-changes .template-updates-wrapper::-webkit-scrollbar,.tribe-events-admin__system-information-widget::-webkit-scrollbar{display:none}.tribe-events-admin__system-information-widget-copy{bottom:10px;position:absolute}.tribe-events-admin__system-information-widget-copy button{background-color:#334aff;border:none;border-radius:100px;color:#fff;cursor:pointer;font-size:16px;font-weight:700;outline:none;padding:18px 25px;text-align:center}.tribe-events-admin__system-information-widget-copy button:hover{background-color:#1c39bb}.tribe-events-admin__system-information-widget-copy button .dashicons,.tribe-events-admin__system-information-widget-copy button .dashicons-before:before{display:none}.tribe-events-admin__system-information-widget-copy button .optin-success{color:#fff;font-size:16px;font-weight:700;text-align:center}.tribe-events-admin__recent-template-changes p{color:#0f1031;font-size:18px;line-height:1.2;line-height:1.44;margin:20px 0}.tribe-events-admin__recent-log{margin-top:50px}.tribe-events-admin__troubleshooting-event-log-wrapper label{color:#0f1031;display:block;font-size:16px;line-height:1.63;margin-bottom:10px}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-controls{margin:20px 0 10px}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-viewer{background:#0f1031;border-radius:16px;color:#fff;font-size:14px;line-height:1.14;max-height:280px;min-height:60px;overflow:scroll;-ms-overflow-style:none;padding:12px 0 0 27px;scrollbar-width:none}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-viewer::-webkit-scrollbar{display:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;padding-bottom:2px;text-decoration:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log:focus{box-shadow:none;outline:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__troubleshooting-event-log-wrapper .tribe-events-admin__recent-log-filters-select-wrapper:after{display:none}.tribe-events-admin__recent-log-filters{display:flex;padding:20px 0 40px}.tribe-events-admin__recent-log-filters-field{margin-right:40px}.tribe-events-admin__recent-log-filters-select-wrapper:after{content:url(../images/help/polygon.svg);height:13px;pointer-events:none;position:absolute;right:22px;top:20px;width:14px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default .select2-selection--single{border:1px solid #e1e1e4!important;border-radius:16px;color:#0f1031;font-size:14px;line-height:1.14;padding:0 25px 0 15px!important}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls{margin-bottom:20px;padding:0}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:first-child,.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(2),.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(3){padding-right:75px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-selection__clear{display:none}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default .select2-selection--single .select2-selection__arrow{right:5px}.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple,.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default.select2-container--open.select2-container--below .select2-selection--single{border-bottom-left-radius:16px;border-bottom-right-radius:16px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container .select2-selection--single .select2-selection__rendered{width:100%}.tribe-events-admin__recent-log-filters-select-wrapper select.focus-visible,.tribe-events-admin__recent-log-filters-select-wrapper select:focus-visible{outline:none}.tribe-events-admin__recent-log-filters-select-wrapper select option{color:#0f1031;font-size:14px;line-height:1.14}.tribe-events-admin__ea-status{margin-top:50px}.tribe-events-admin__issues-found-card{background-color:#f3eee8;border-radius:8px;margin-bottom:20px}.tribe-events-admin__issues-found-card:last-of-type{margin-bottom:100px}.tribe-events-admin__issues-found-card-title{align-items:center;cursor:pointer;display:flex;padding:10px 20px 10px 17px;position:relative}.tribe-events-admin__issues-found-card-title img{height:21px;margin-right:14px;-o-object-fit:contain;object-fit:contain;width:21px}.tribe-events-admin__issues-found-card-title h3{margin:0}.tribe-events-admin__issues-found-card-title span{color:#0f1031;display:block}.tribe-events-admin__issues-found-card-title i{background-image:url(../images/help/arrow-down.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:15px;margin:12px 20px;position:absolute;right:0;top:0;transition:all .3s ease;width:15px}.tribe-events-admin__issues-found-card-title.active i{background-image:url(../images/help/arrow-up.svg);background-repeat:no-repeat;top:5px}.tribe-events-admin__issues-found-card-description{display:none;padding:0 20px 20px 55px}.tribe-events-admin__issues-found-card-description p{color:#0f1031;font-size:16px;margin:0}.tribe-events-admin__issues-found-card-description-actions{display:flex;padding:20px 0 10px}.tribe-events-admin__issues-found-card-description-actions a{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;margin-right:20px;padding-bottom:5px;text-decoration:none}.tribe-events-admin__issues-found-card-description-actions a:focus{box-shadow:none;outline:none}.tribe-events-admin__issues-found-card-description-actions a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__ea-status-table-wrapper{overflow-x:auto}.tribe-events-admin__ea-status-table{border:1px solid #e1e1e4;border-radius:16px;margin:30px 0 40px;overflow:hidden}.tribe-events-admin__ea-status-table a{border-bottom:2px solid #334aff;color:#334aff;padding-bottom:2px;text-decoration:none}.tribe-events-admin__ea-status-table a:focus{box-shadow:none;outline:none}.tribe-events-admin__ea-status-table a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__ea-status-table tr{display:flex;align-items:center}.tribe-events-admin__ea-status-table th{color:#0f1031;font-weight:700;line-height:1.17;margin-top:10px;padding:5px 25px}.tribe-events-admin__ea-status-table td{align-items:center;color:#0f1031;display:flex;font-size:16px;line-height:1.63;padding:10px 25px;width:25%}.tribe-events-admin__ea-status-table td:nth-child(2){width:45%}.tribe-events-admin__ea-status-table td:nth-child(3){display:flex;justify-content:flex-end;width:30%}.tribe-events-admin__ea-status-table-dark{background-color:#f9f7f4}.tribe-events-admin__ea-status-table td img{height:21px;margin-right:14px;-o-object-fit:contain;object-fit:contain;width:21px}.tribe_events_page_tec-troubleshooting{background-color:#fff}#tribe-community,#tribe-ticketing{display:none}.tribe-events-admin__troubleshooting-notice{background-color:#161b7d;color:#fff;font-size:16px;line-height:1;margin-left:-1.55vw;padding:24px 0}.tribe-events-admin__troubleshooting-notice_title{margin:0 auto;max-width:1024px;padding-left:25px;width:90%}.tribe-events-admin__troubleshooting-notice_title a{border-bottom:2px solid #fff;color:#fff;font-size:16px;line-height:1;padding-bottom:2px;text-decoration:none}.tribe-events-admin__troubleshooting-notice_title a:focus{box-shadow:none;outline:none}.tribe-events-admin__troubleshooting-notice_title a:hover{border-bottom:2px solid #f3eee8;color:#f3eee8}.tribe_events_page_tribe-help #tec-help-community,.tribe_events_page_tribe-help #tec-help-ticketing{display:none}.tribe_events_page_tribe-help .tribe-events-admin-title{padding-top:25px}.tribe_events_page_tribe-help .tribe-events-admin-title img{height:67px}body.tribe-welcome #fs_connect{border:1px solid #e1e1e4;border-radius:16px;box-shadow:none;box-sizing:border-box;margin-left:22px}body.tribe-welcome #fs_connect .fs-actions{background-color:transparent}body.tribe-welcome #fs_connect .fs-permissions{border-top:1px solid #e1e1e4;margin:0 16px}body.tribe-welcome #fs_connect button{background-color:#3d54ff;border-color:#3d54ff}body.tribe-welcome #fs_connect .button-secondary{background:#fff;border-color:#3d54ff;color:#3d54ff}body.tribe-welcome #fs_connect a{color:#3d54ff}body.tribe-welcome #fs_connect a:focus{box-shadow:none;outline:none}body.tribe-welcome #fs_connect a:hover{color:#161b7d}@media only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min--moz-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){#tribe-loading span{background-image:url(../images/tribe-loading@2x.gif)}}@media screen and (max-width:782px){.tribe-half-column,.tribe-row .tribe-half-column:last-child{margin:0 0 20px;width:100%}input[type=email]{width:100%}.events-cal .subsubsub{float:none}.events-cal .search-box{width:98%}.events-cal #search-submit{width:100%}.events-cal .tablenav.top{display:none}}@media screen and (min-width:500px){.api-check .tribe-mascot{display:block}.api-check .notice-content{margin-right:180px}}@media screen and (min-width:320px){.tribe-marketing-notice .tribe-marketing-notice__icon{display:block}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px}}@media screen and (min-width:600px) and (max-width:782px){.tribe-marketing-notice .tribe-marketing-notice__content{margin-left:145px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px;padding:0}}@media screen and (min-width:782px){.tribe-marketing-notice .tribe-marketing-notice__content{margin-left:130px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px;padding:0}.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe-welcome .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:642px}}@media screen and (min-width:400px){.notice-tribe-banner .tribe-marketing-notice__icon{width:67px}}@media screen and (min-width:800px){.notice-tribe-banner h3{display:inline-block;font-size:1rem;margin:0 .5rem 0 0}.notice-tribe-banner a{line-height:1.5}.notice-tribe-banner a,.notice-tribe-banner p{font-size:1rem}.notice-tribe-banner p{margin:0 .5rem 0 0}.notice-tribe-banner .tribe-marketing-notice__cta{display:inline-block;margin-left:.5rem}}@media screen and (min-width:1215px){.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:992px}.tribe-welcome .notice-tribe-banner .tribe-marketing-notice{max-width:1036px}}@media screen and (min-width:710px){.tribe-events-admin-content-wrapper{width:670px}.tribe-events-admin-card--2up{display:inline-block;width:calc(50% - 20px)}.tribe-events-admin-card--2up.tribe-events-admin-card--first{margin-right:36px}.tribe-events-admin-card--2up.tribe-events-admin-card--last{margin-right:0}.tribe-events-admin-card--2up .tribe-events-admin-card__image{height:100px;margin-bottom:12px}.tribe-events-admin-card--2up .tribe-events-admin-card__title{margin-bottom:27px;max-width:340px}.tribe-events-admin-card--3up{display:inline-block;margin-bottom:32px;width:calc(50% - 18px)}.tribe-events-admin-card--3up.tribe-events-admin-card--first{margin-right:32px}.tribe-events-admin-card--3up.tribe-events-admin-card--middle{margin-right:0}.tribe-events-admin-card__title{font-size:20px;line-height:23px}.tribe-events-admin-section-header{font-size:28px;line-height:32px;margin-bottom:21px}.tribe-events-admin-card--1up{display:inline-block;margin-left:32px;width:calc(50% - 18px)}.tribe-events-admin-card--1up .tribe-events-admin-card__description{height:71px}.tribe-events-admin-card--1up .tribe-events-admin-card__image{margin-bottom:28px}.tribe-events-admin-card--no-pad{height:154px;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{margin-left:50%;padding:42px 0 10px}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin-left:50%}.tribe-events-admin-card--promo-blue{display:block;margin-left:0;min-height:170px;width:100%}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{float:left;max-width:300px}.tribe-events-admin-graphic{max-width:250px;top:0}.tribe-events-admin-graphic--desktop-only{display:block}.tribe-events-admin-graphic--mobile-only{display:none}.tribe-events-admin-card__form{float:right;width:300px}input[type=email].tribe-events-admin-card__input{width:300px}.tribe-events-admin-title{padding-top:50px}.tribe-events-admin-title__description{padding-top:15px}.tribe-events-admin-title__heading{font-size:48px;line-height:55px;margin:0}.tribe-events-admin-title__logo{margin-right:14px;padding-top:5px;width:40px}.tribe-events-admin-tickets .tribe-events-admin-card__title{font-size:18px}.tribe-events-admin-tickets .tribe-events-admin-card--2up .tribe-events-admin-card__title{font-size:18px;height:66px}.tribe-events-admin-tickets .tribe-events-admin-title__logo{margin-right:8px;padding-top:4px;width:60px}}@media screen and (min-width:1217px){.tribe-events-admin-content-wrapper{max-width:1060px;width:100%}.tribe-events-admin-card--2up{margin-right:36px;width:486px}.tribe-events-admin-card--3up{width:310px}.tribe-events-admin-card--3up.tribe-events-admin-card--first,.tribe-events-admin-card--3up.tribe-events-admin-card--middle{margin-right:36px}.tribe-events-admin-card--3up.tribe-events-admin-card--last{margin-right:0}.tribe-events-admin-quick-nav{padding:0 36px}.tribe-events-admin-card--1up{margin:0 0 36px;padding:33px 44px 30px;text-align:left;width:1012px}.tribe-events-admin-card--1up .tribe-events-admin-card__description{height:auto}.tribe-events-admin-card--1up .tribe-events-admin-card__image{float:left;margin:0 48px 10px 0}.tribe-events-admin-card--no-pad{padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__image{margin:0;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{margin-left:50%;padding:42px 0 10px}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin-left:50%}.tribe-events-admin-card--promo-blue{min-height:150px}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{max-width:450px}.tribe-events-admin-graphic{max-width:none}.tribe-events-admin-card__form,input[type=email].tribe-events-admin-card__input{width:365px}.tribe-events-admin-quick-nav{border-radius:100px;display:inline-block;height:54px;margin:24px 0 94px;max-width:1010px;padding:0 36px 0 0}.tribe-events-admin-quick-nav__link-item{display:inline-block;padding:18px 10px 0}.tribe-events-admin-quick-nav__title{padding:19px 6px 17px 32px}.tribe-events-admin-tickets .tribe-events-admin-card--2up .tribe-events-admin-card__title{height:auto}}@media screen and (max-width:768px){.tribe-events-admin-header__logo-word-mark{width:285px}.tribe-events-admin-header__right-image{height:160px}.tribe-events-admin-header__description{max-width:100%}.tribe-events-admin-tab-nav li{margin-right:20px}.tribe-events-admin-tab-nav .selected{border-bottom:2px solid #334aff;padding-bottom:10px}.tribe-events-admin-2col-grid{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr))}.tribe-events-admin-3col-grid{grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr))}.tribe-events-admin-extensions-title{max-width:100%}.tribe-events-admin-cta{align-items:flex-start;flex-direction:column;overflow:hidden}.tribe-events-admin-footer-logo{width:225px}.tribe-events-admin__system-information{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr));margin:50px 0}}@media screen and (max-width:480px){.tribe-events-admin-header__logo-word-mark{width:260px}.tribe-events-admin-header__right-image{height:120px}.tribe-events-admin-header__title{font-size:35px}.tribe-events-admin-header__description{max-width:100%}.tribe-events-admin-tab-nav{border:1px solid #e1e1e4;border-radius:20px;flex-direction:column;padding:18px 22px}.tribe-events-admin-tab-nav li{margin-bottom:18px;margin-right:0}.tribe-events-admin-tab-nav .selected{border-bottom:2px solid #334aff;padding-bottom:10px;width:-moz-fit-content;width:fit-content}.tribe-events-admin__line{border:none}.tribe-events-admin-products-card,.tribe-events-admin-products-description{display:none}.tribe-events-admin-container,.tribe-events-admin-content-wrapper.tribe-events-admin-container{max-width:90%}.tribe-events-admin-2col-grid,.tribe-events-admin-3col-grid,.tribe-events-admin-4col-grid{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr))}.tribe-events-admin-section-header{margin:0}.tribe-events-admin-extensions-title{max-width:100%}.tribe-events-admin-cta__image{height:auto;width:90%}.tribe-events-admin-cta__content,.tribe-events-admin__troubleshooting-cta{align-items:flex-start;padding:32px 23px 45px;width:auto}.tribe-events-admin-cta__content-title{font-size:22px;text-align:left}.tribe-events-admin-cta__content-subtitle{text-align:left}.tribe-events-admin-footer-logo{width:210px}.tribe-events-admin__system-information{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr));margin:50px 0}.tribe-events-admin__troubleshooting-notice{margin-left:-20px}.tribe-events-admin__troubleshooting-notice_title{max-width:90%}}@media screen and (min-width:1200px){.tribe-events-admin-products-card__group{max-width:47%}}@media screen and (min-width:500px) and (max-width:1080px){.tribe-events-admin-4col-grid{grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr))}}@media screen and (max-width:1080px){.tribe-events-admin-cta__content-title{font-size:24px}}@media only screen and (max-width:1920px){.tribe-events-admin__system-information-widget-copy{right:20.5vw}}@media only screen and (max-width:1280px){.tribe-events-admin__system-information-widget-copy{right:22vw}}@media only screen and (max-width:768px){.tribe-events-admin__system-information-widget-copy{left:10px;right:auto}.tribe-events-admin__recent-log-filters{flex-direction:column}.tribe-events-admin__recent-log-filters-field{margin-bottom:30px;margin-right:0}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:first-child,.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(2),.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(3){padding-right:30px}.tribe-events-admin__issues-found-card-title h3{max-width:90%}}@media only screen and (max-width:480px){.tribe-events-admin__system-information-widget-copy{left:10px;right:auto}.tribe-events-admin__recent-log-filters{flex-direction:column}.tribe-events-admin__recent-log-filters-field{margin-bottom:30px;margin-right:0}.tribe-events-admin__recent-log-filters-select-wrapper:after{right:25px}.tribe-events-admin__issues-found-card-title h3{max-width:80%}.tribe-events-admin__ea-status-table{overflow:scroll}.tribe-events-admin__ea-status-table td{min-width:150px}.tribe-events-admin__ea-status-table td:nth-child(2),.tribe-events-admin__ea-status-table td:nth-child(3){width:100%}}
|
common/src/resources/css/variables-full.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
:root{--tec-border-radius-default:4px;--tec-border-width-week-event:2px;--border-radius-default:var(--tec-border-radius-default);--border-width-week-event:var(--tec-border-width-week-event);--tec-box-shadow-default:0 2px 5px 0 var(--tec-color-box-shadow);--tec-box-shadow-tooltip:0 2px 12px 0 var(--tec-color-box-shadow);--tec-box-shadow-card:0 1px 6px 2px var(--tec-color-box-shadow);--tec-box-shadow-multiday:16px 6px 6px -2px var(--tec-color-box-shadow-secondary);--box-shadow-default:var(--tec-box-shadow-default);--box-shadow-tooltip:var(--tec-box-shadow-tooltip);--box-shadow-card:var(--tec-box-shadow-card);--box-shadow-multiday:var(--tec-box-shadow-multiday);--tec-form-color-background:var(--tec-color-background);--tec-form-color-border-default:var(--tec-color-text-primary);--tec-form-color-border-active:var(--tec-color-accent-secondary);--tec-form-color-border-secondary:var(--tec-color-border-tertiary);--tec-form-color-accent-primary:var(--tec-color-accent-primary);--tec-form-box-shadow-default:var(--tec-box-shadow-default);--form-color-background:var(--tec-form-color-background);--form-color-border-default:var(--tec-form-color-border-default);--form-color-border-active:var(--tec-form-color-border-active);--form-color-border-secondary:var(--tec-form-color-border-secondary);--form-color-accent-primary:var(--tec-form-color-accent-primary);--form-box-shadow-default:var(--tec-form-box-shadow-default);--tec-opacity-background:0.07;--tec-opacity-select-highlighted:0.3;--tec-opacity-icon-hover:0.8;--tec-opacity-icon-active:0.9;--tec-opacity-default:1;--opacity-background:var(--tec-opacity-background);--opacity-select-highlighted:var(--tec-opacity-select-highlighted);--opacity-icon-hover:var(--tec-opacity-icon-hover);--opacity-icon-active:var(--tec-opacity-icon-active);--opacity-default:var(--tec-opacity-default);--tec-transition:all 0.2s ease;--tec-transition-background-color:background-color 0.2s ease;--tec-transition-color-border-color:color 0.2s ease,border-color 0.2s ease;--tec-transition-transform:transform 0.2s ease;--tec-transition-border-color:border-color 0.2s ease;--tec-transition-color:color 0.2s ease;--tec-transition-opacity:opacity 0.2s ease;--transition:var(--tec-transition);--transition-background-color:var(--tec-transition-background-color);--transition-color-border-color:var(--tec-transition-color-border-color);--transition-transform:var(--tec-transition-transform);--transition-border-color:var(--tec-transition-border-color);--transition-color:var(--tec-transition-color);--transition-opacity:var(--tec-transition-opacity);--tec-font-family-sans-serif:"Helvetica Neue",Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;--tec-font-weight-regular:400;--tec-font-weight-bold:700;--tec-font-size-0:11px;--tec-font-size-1:12px;--tec-font-size-2:14px;--tec-font-size-3:16px;--tec-font-size-4:18px;--tec-font-size-5:20px;--tec-font-size-6:22px;--tec-font-size-7:24px;--tec-font-size-8:28px;--tec-font-size-9:32px;--tec-font-size-10:42px;--tec-line-height-0:1.38;--tec-line-height-1:1.42;--tec-line-height-2:1.5;--tec-line-height-3:1.62;--font-family-sans-serif:var(--tec-font-family-sans-serif);--font-family-base:var(--tec-font-family-sans-serif);--font-weight-regular:var(--tec-font-weight-regular);--font-weight-bold:var(--tec-font-weight-bold);--font-size-0:var(--tec-font-size-0);--font-size-1:var(--tec-font-size-1);--font-size-2:var(--tec-font-size-2);--font-size-3:var(--tec-font-size-3);--font-size-4:var(--tec-font-size-4);--font-size-5:var(--tec-font-size-5);--font-size-6:var(--tec-font-size-6);--font-size-7:var(--tec-font-size-7);--font-size-8:var(--tec-font-size-8);--font-size-9:var(--tec-font-size-9);--font-size-10:var(--tec-font-size-10);--line-height-0:var(--tec-line-height-0);--line-height-1:var(--tec-line-height-1);--line-height-2:var(--tec-line-height-2);--line-height-3:var(--tec-line-height-3)}
|
common/src/resources/css/variables-skeleton.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
:root{--tec-grid-gutter:48px;--tec-grid-gutter-negative:calc(var(--tec-grid-gutter)*-1);--tec-grid-gutter-half:calc(var(--tec-grid-gutter)/2);--tec-grid-gutter-half-negative:calc(var(--tec-grid-gutter-half)*-1);--tec-grid-gutter-small:42px;--tec-grid-gutter-small-negative:calc(var(--tec-grid-gutter-small)*-1);--tec-grid-gutter-small-half:calc(var(--tec-grid-gutter-small)/2);--tec-grid-gutter-small-half-negative:calc(var(--tec-grid-gutter-small-half)*-1);--tec-grid-gutter-page:42px;--tec-grid-gutter-page-small:19.5px;--tec-grid-width-default:1176px;--tec-grid-width-min:320px;--tec-grid-width:calc(var(--tec-grid-width-default) + var(--tec-grid-gutter-page)*2);--tec-grid-width-1-of-2:50%;--tec-grid-width-1-of-3:33.333%;--tec-grid-width-1-of-4:25%;--tec-grid-width-1-of-5:20%;--tec-grid-width-1-of-7:14.285%;--tec-grid-width-1-of-8:12.5%;--tec-grid-width-1-of-9:11.111%;--grid-gutter:var(--tec-grid-gutter);--grid-gutter-negative:var(--tec-grid-gutter-negative);--grid-gutter-half:var(--tec-grid-gutter-half);--grid-gutter-half-negative:var(--tec-grid-gutter-half-negative);--grid-gutter-small:var(--tec-grid-gutter-small);--grid-gutter-small-negative:var(--tec-grid-gutter-small-negative);--grid-gutter-small-half:var(--tec-grid-gutter-small-half);--grid-gutter-small-half-negative:var(--tec-grid-gutter-small-half-negative);--grid-gutter-page:var(--tec-grid-gutter-page);--grid-gutter-page-small:var(--tec-grid-gutter-page-small);--grid-width-default:var(--tec-grid-width-default);--grid-width-min:var(--tec-grid-width-min);--grid-width:var(--tec-grid-width);--grid-width-1-of-2:var(--tec-grid-width-1-of-2);--grid-width-1-of-3:var(--tec-grid-width-1-of-3);--grid-width-1-of-4:var(--tec-grid-width-1-of-4);--grid-width-1-of-5:var(--tec-grid-width-1-of-5);--grid-width-1-of-7:var(--tec-grid-width-1-of-7);--grid-width-1-of-8:var(--tec-grid-width-1-of-8);--grid-width-1-of-9:var(--tec-grid-width-1-of-9);--tec-spacer-0:4px;--tec-spacer-1:8px;--tec-spacer-2:12px;--tec-spacer-3:16px;--tec-spacer-4:20px;--tec-spacer-5:24px;--tec-spacer-6:28px;--tec-spacer-7:32px;--tec-spacer-8:40px;--tec-spacer-9:48px;--tec-spacer-10:56px;--tec-spacer-11:64px;--tec-spacer-12:80px;--tec-spacer-13:96px;--tec-spacer-14:160px;--spacer-0:var(--tec-spacer-0);--spacer-1:var(--tec-spacer-1);--spacer-2:var(--tec-spacer-2);--spacer-3:var(--tec-spacer-3);--spacer-4:var(--tec-spacer-4);--spacer-5:var(--tec-spacer-5);--spacer-6:var(--tec-spacer-6);--spacer-7:var(--tec-spacer-7);--spacer-8:var(--tec-spacer-8);--spacer-9:var(--tec-spacer-9);--spacer-10:var(--tec-spacer-10);--spacer-11:var(--tec-spacer-11);--spacer-12:var(--tec-spacer-12);--spacer-13:var(--tec-spacer-13);--spacer-14:var(--tec-spacer-14);--tec-z-index-spinner-container:100;--tec-z-index-views-selector:30;--tec-z-index-dropdown:30;--tec-z-index-events-bar-button:20;--tec-z-index-search:10;--tec-z-index-filters:9;--tec-z-index-scroller:7;--tec-z-index-week-event-hover:5;--tec-z-index-map-event-hover:5;--tec-z-index-map-event-hover-actions:6;--tec-z-index-multiday-event:5;--tec-z-index-multiday-event-bar:2;--z-index-spinner-container:var(--tec-z-index-spinner-container);--z-index-views-selector:var(--tec-z-index-views-selector);--z-index-dropdown:var(--tec-z-index-dropdown);--z-index-events-bar-button:var(--tec-z-index-events-bar-button);--z-index-search:var(--tec-z-index-search);--z-index-filters:var(--tec-z-index-filters);--z-index-scroller:var(--tec-z-index-scroller);--z-index-week-event-hover:var(--tec-z-index-week-event-hover);--z-index-map-event-hover:var(--tec-z-index-map-event-hover);--z-index-map-event-hover-actions:var(--tec-z-index-map-event-hover-actions);--z-index-multiday-event:var(--tec-z-index-multiday-event);--z-index-multiday-event-bar:var(--tec-z-index-multiday-event-bar);--tec-color-text-primary:#141827;--tec-color-text-primary-light:rgba(20,24,39,.62);--tec-color-text-secondary:#5d5d5d;--tec-color-text-disabled:#d5d5d5;--tec-color-text-events-title:var(--tec-color-text-primary);--tec-color-text-event-title:var(--tec-color-text-events-title);--tec-color-text-event-date:var(--tec-color-text-primary);--tec-color-text-secondary-event-date:var(--tec-color-text-secondary);--tec-color-icon-primary:#5d5d5d;--tec-color-icon-primary-alt:#757575;--tec-color-icon-secondary:#bababa;--tec-color-icon-active:#141827;--tec-color-icon-disabled:#d5d5d5;--tec-color-icon-focus:#334aff;--tec-color-icon-error:#da394d;--tec-color-event-icon:#141827;--tec-color-event-icon-hover:#334aff;--tec-color-accent-primary:#334aff;--tec-color-accent-primary-hover:rgba(51,74,255,.8);--tec-color-accent-primary-active:rgba(51,74,255,.9);--tec-color-accent-primary-background:rgba(51,74,255,.07);--tec-color-accent-secondary:#141827;--tec-color-accent-secondary-hover:rgba(20,24,39,.8);--tec-color-accent-secondary-active:rgba(20,24,39,.9);--tec-color-accent-secondary-background:rgba(20,24,39,.07);--tec-color-button-primary:var(--tec-color-accent-primary);--tec-color-button-primary-hover:var(--tec-color-accent-primary-hover);--tec-color-button-primary-active:var(--tec-color-accent-primary-active);--tec-color-button-primary-background:var(--tec-color-accent-primary-background);--tec-color-button-secondary:var(--tec-color-accent-secondary);--tec-color-button-secondary-hover:var(--tec-color-accent-secondary-hover);--tec-color-button-secondary-active:var(--tec-color-accent-secondary-active);--tec-color-button-secondary-background:var(--tec-color-accent-secondary-background);--tec-color-link-primary:var(--tec-color-text-primary);--tec-color-link-accent:var(--tec-color-accent-primary);--tec-color-link-accent-hover:rgba(51,74,255,.8);--tec-color-border-default:#d5d5d5;--tec-color-border-secondary:#e4e4e4;--tec-color-border-tertiary:#7d7d7d;--tec-color-border-hover:#5d5d5d;--tec-color-border-active:#141827;--tec-color-background:#fff;--tec-color-background-events:transparent;--tec-color-background-transparent:hsla(0,0%,100%,.6);--tec-color-background-secondary:#f7f6f6;--tec-color-background-messages:rgba(20,24,39,.07);--tec-color-background-secondary-hover:#f0eeee;--tec-color-background-error:rgba(218,57,77,.08);--tec-color-box-shadow:rgba(0,0,0,.14);--tec-color-box-shadow-secondary:rgba(0,0,0,.1);--tec-color-scroll-track:rgba(0,0,0,.25);--tec-color-scroll-bar:rgba(0,0,0,.5);--tec-color-background-primary-multiday:rgba(51,74,255,.24);--tec-color-background-primary-multiday-hover:rgba(51,74,255,.34);--tec-color-background-secondary-multiday:rgba(20,24,39,.24);--tec-color-background-secondary-multiday-hover:rgba(20,24,39,.34);--tec-color-accent-primary-week-event:rgba(51,74,255,.1);--tec-color-accent-primary-week-event-hover:rgba(51,74,255,.2);--tec-color-accent-primary-week-event-featured:rgba(51,74,255,.04);--tec-color-accent-primary-week-event-featured-hover:rgba(51,74,255,.14);--tec-color-background-secondary-datepicker:var(--tec-color-background-secondary);--tec-color-accent-primary-background-datepicker:var(--tec-color-accent-primary-background);--color-text-primary:var(--tec-color-text-primary);--color-text-primary-light:var(--tec-color-text-primary-light);--color-text-secondary:var(--tec-color-text-secondary);--color-text-disabled:var(--tec-color-text-disabled);--color-icon-primary:var(--tec-color-icon-primary);--color-icon-primary-alt:var(--tec-color-icon-primary);--color-icon-secondary:var(--tec-color-icon-secondary);--color-icon-active:var(--tec-color-icon-active);--color-icon-disabled:var(--tec-color-icon-disabled);--color-icon-focus:var(--tec-color-icon-focus);--color-icon-error:var(--tec-color-icon-error);--color-accent-primary:var(--tec-color-accent-primary);--color-accent-primary-hover:var(--tec-color-accent-primary-hover);--color-accent-primary-active:var(--tec-color-accent-primary-active);--color-accent-primary-background:var(--tec-color-accent-primary-background);--color-accent-primary-multiday:var(--tec-color-accent-primary-multiday);--color-accent-primary-multiday-hover:var(--tec-color-accent-primary-multiday-hover);--color-accent-primary-week-event:var(--tec-color-accent-primary-week-event);--color-accent-primary-week-event-hover:var(--tec-color-accent-primary-week-event-hover);--color-accent-primary-week-event-featured:var(--tec-color-accent-primary-week-event-featured);--color-accent-primary-week-event-featured-hover:var(--tec-color-accent-primary-week-event-featured-hover);--color-accent-secondary:var(--tec-color-accent-secondary);--color-accent-secondary-hover:var(--tec-color-accent-secondary-hover);--color-accent-secondary-active:var(--tec-color-accent-secondary-active);--color-accent-secondary-background:var(--tec-color-accent-secondary-background);--color-border-default:var(--tec-color-border-default);--color-border-secondary:var(--tec-color-border-secondary);--color-border-tertiary:var(--tec-color-border-tertiary);--color-border-hover:var(--tec-color-border-hover);--color-border-active:var(--tec-color-border-active);--color-background:var(--tec-color-background);--color-background-transparent:var(--tec-color-background-transparent);--color-background-secondary:var(--tec-color-background-secondary);--color-background-messages:var(--tec-color-background-messages);--color-background-secondary-hover:var(--tec-color-background-secondary-hover);--color-background-error:var(--tec-color-icon-error);--color-box-shadow:var(--tec-color-box-shadow);--color-box-shadow-secondary:var(--tec-color-box-shadow-secondary);--color-scroll-track:var(--tec-color-scroll-track);--color-scroll-bar:var(--tec-color-scroll-bar)}
|
common/vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit45000f0908896b286907423ec7c5ab9b::getLoader();
|
common/vendor/autoload_52.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit78905504a638b87540454f23ee595a11::getLoader();
|
common/vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -19,15 +19,15 @@ class ComposerAutoloaderInitaee01d981b64ab474e5e655b123ccdaf
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
25 |
|
26 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
27 |
if ($useStaticLoader) {
|
28 |
require_once __DIR__ . '/autoload_static.php';
|
29 |
|
30 |
-
call_user_func(\Composer\Autoload\
|
31 |
} else {
|
32 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
33 |
foreach ($map as $namespace => $path) {
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInit45000f0908896b286907423ec7c5ab9b
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInit45000f0908896b286907423ec7c5ab9b', 'loadClassLoader'), true, true);
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit45000f0908896b286907423ec7c5ab9b', 'loadClassLoader'));
|
25 |
|
26 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
27 |
if ($useStaticLoader) {
|
28 |
require_once __DIR__ . '/autoload_static.php';
|
29 |
|
30 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit45000f0908896b286907423ec7c5ab9b::getInitializer($loader));
|
31 |
} else {
|
32 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
33 |
foreach ($map as $namespace => $path) {
|
common/vendor/composer/autoload_real_52.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real_52.php generated by xrstf/composer-php52
|
4 |
|
5 |
-
class
|
6 |
private static $loader;
|
7 |
|
8 |
public static function loadClassLoader($class) {
|
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitd5e39499ce3b1c1732409f4fe733064e {
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new xrstf_Composer52_ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
25 |
|
26 |
$vendorDir = dirname(dirname(__FILE__));
|
27 |
$baseDir = dirname($vendorDir);
|
2 |
|
3 |
// autoload_real_52.php generated by xrstf/composer-php52
|
4 |
|
5 |
+
class ComposerAutoloaderInit78905504a638b87540454f23ee595a11 {
|
6 |
private static $loader;
|
7 |
|
8 |
public static function loadClassLoader($class) {
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInit78905504a638b87540454f23ee595a11', 'loadClassLoader'), true /*, true */);
|
23 |
self::$loader = $loader = new xrstf_Composer52_ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit78905504a638b87540454f23ee595a11', 'loadClassLoader'));
|
25 |
|
26 |
$vendorDir = dirname(dirname(__FILE__));
|
27 |
$baseDir = dirname($vendorDir);
|
common/vendor/composer/autoload_static.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $prefixLengthsPsr4 = array (
|
10 |
'T' =>
|
@@ -242,10 +242,10 @@ class ComposerStaticInitaee01d981b64ab474e5e655b123ccdaf
|
|
242 |
public static function getInitializer(ClassLoader $loader)
|
243 |
{
|
244 |
return \Closure::bind(function () use ($loader) {
|
245 |
-
$loader->prefixLengthsPsr4 =
|
246 |
-
$loader->prefixDirsPsr4 =
|
247 |
-
$loader->prefixesPsr0 =
|
248 |
-
$loader->classMap =
|
249 |
|
250 |
}, null, ClassLoader::class);
|
251 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInit45000f0908896b286907423ec7c5ab9b
|
8 |
{
|
9 |
public static $prefixLengthsPsr4 = array (
|
10 |
'T' =>
|
242 |
public static function getInitializer(ClassLoader $loader)
|
243 |
{
|
244 |
return \Closure::bind(function () use ($loader) {
|
245 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInit45000f0908896b286907423ec7c5ab9b::$prefixLengthsPsr4;
|
246 |
+
$loader->prefixDirsPsr4 = ComposerStaticInit45000f0908896b286907423ec7c5ab9b::$prefixDirsPsr4;
|
247 |
+
$loader->prefixesPsr0 = ComposerStaticInit45000f0908896b286907423ec7c5ab9b::$prefixesPsr0;
|
248 |
+
$loader->classMap = ComposerStaticInit45000f0908896b286907423ec7c5ab9b::$classMap;
|
249 |
|
250 |
}, null, ClassLoader::class);
|
251 |
}
|
event-tickets.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Event Tickets
|
4 |
Plugin URI: https://evnt.is/1acb
|
5 |
Description: Event Tickets allows you to sell basic tickets and collect RSVPs from any post, page, or event.
|
6 |
-
Version: 5.1.
|
7 |
Author: The Events Calendar
|
8 |
Author URI: https://evnt.is/1aor
|
9 |
License: GPLv2 or later
|
3 |
Plugin Name: Event Tickets
|
4 |
Plugin URI: https://evnt.is/1acb
|
5 |
Description: Event Tickets allows you to sell basic tickets and collect RSVPs from any post, page, or event.
|
6 |
+
Version: 5.1.9
|
7 |
Author: The Events Calendar
|
8 |
Author URI: https://evnt.is/1aor
|
9 |
License: GPLv2 or later
|
lang/event-tickets-cs_CZ.mo
CHANGED
Binary file
|
lang/event-tickets-es_ES.mo
CHANGED
Binary file
|
lang/event-tickets-fi.mo
CHANGED
Binary file
|
lang/event-tickets-fr_CA.mo
DELETED
Binary file
|
lang/event-tickets-ja.mo
CHANGED
Binary file
|
lang/event-tickets-nl_NL.mo
CHANGED
Binary file
|
lang/event-tickets.pot
CHANGED
@@ -2,176 +2,64 @@
|
|
2 |
# This file is distributed under the same license as the Event Tickets package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: Event Tickets 5.
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/event-tickets\n"
|
7 |
-
"POT-Creation-Date: 2021-08-
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
-
"PO-Revision-Date: 2021-08-
|
12 |
"Last-Translator: \n"
|
13 |
"Language-Team: \n"
|
14 |
|
15 |
-
#. #-#-#-#-# event-tickets.pot (Event Tickets 5.
|
16 |
#. Plugin Name of the plugin/theme
|
17 |
-
#: event-tickets.php:62 src/Tribe/Admin/Notices.php:92 src/Tribe/Main.php:
|
18 |
#: src/Tribe/Privacy.php:59 src/admin-views/admin-welcome-message.php:58
|
19 |
msgid "Event Tickets"
|
20 |
msgstr ""
|
21 |
|
22 |
-
#: src/Tickets/Commerce/
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
#: src/admin-views/tribe-commerce-settings.php:40
|
28 |
-
msgid "these instructions"
|
29 |
-
msgstr ""
|
30 |
-
|
31 |
-
#. Translators: %1$s: The word "ticket" in lowercase, %2$s: The "these
|
32 |
-
#. instructions" link.
|
33 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:82
|
34 |
-
msgctxt "tickets fields settings PayPal setup"
|
35 |
-
msgid ""
|
36 |
-
"Ie Tickets Commerce to sell %1$s, you must configure your PayPal account to "
|
37 |
-
"communicate with your WordPress site. If you need help getting set up, "
|
38 |
-
"follow %2$s"
|
39 |
-
msgstr ""
|
40 |
-
|
41 |
-
#. Translators: %s: The site link.
|
42 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:94
|
43 |
-
#: src/admin-views/tribe-commerce-settings.php:47
|
44 |
-
msgid "Your site address is: %s"
|
45 |
-
msgstr ""
|
46 |
-
|
47 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:99
|
48 |
-
#: src/admin-views/tribe-commerce-settings.php:45
|
49 |
-
msgid ""
|
50 |
-
"Have you entered this site's address in the Notification URL field in IPN "
|
51 |
-
"Settings?"
|
52 |
-
msgstr ""
|
53 |
-
|
54 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:108
|
55 |
-
#: src/admin-views/tribe-commerce-settings.php:117
|
56 |
-
msgid "PayPal configuration status:"
|
57 |
-
msgstr ""
|
58 |
-
|
59 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:111
|
60 |
-
#: src/admin-views/tribe-commerce-settings.php:120
|
61 |
-
msgid ""
|
62 |
-
"For help creating and configuring your account, call PayPal at "
|
63 |
-
"1-844-720-4038 (USA)"
|
64 |
-
msgstr ""
|
65 |
-
|
66 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:117
|
67 |
-
msgid "Configure PayPal Legacy:"
|
68 |
-
msgstr ""
|
69 |
-
|
70 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:123
|
71 |
-
#: src/admin-views/tribe-commerce-settings.php:83
|
72 |
-
msgid "PayPal email to receive payments:"
|
73 |
-
msgstr ""
|
74 |
-
|
75 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:131
|
76 |
-
#: src/admin-views/tribe-commerce-settings.php:91
|
77 |
-
msgid ""
|
78 |
-
"Have you enabled instant payment notifications (IPN) in your PayPal "
|
79 |
-
"account's Selling Tools?"
|
80 |
-
msgstr ""
|
81 |
-
|
82 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:133
|
83 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:145
|
84 |
-
#: src/Tribe/Attendees.php:549 src/admin-views/tribe-commerce-settings.php:93
|
85 |
-
#: src/admin-views/tribe-commerce-settings.php:105
|
86 |
-
msgid "Yes"
|
87 |
-
msgstr ""
|
88 |
-
|
89 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:134
|
90 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:146
|
91 |
-
#: src/admin-views/tribe-commerce-settings.php:94
|
92 |
-
#: src/admin-views/tribe-commerce-settings.php:106
|
93 |
-
msgid "No"
|
94 |
-
msgstr ""
|
95 |
-
|
96 |
-
#. Translators: %s: The PayPal notification history link.
|
97 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:169
|
98 |
-
#: src/admin-views/tribe-commerce-settings.php:209
|
99 |
-
msgid ""
|
100 |
-
"You can see and manage your IPN Notifications history from the IPN "
|
101 |
-
"Notifications settings area (%s)."
|
102 |
-
msgstr ""
|
103 |
-
|
104 |
-
#. Translators: %s: The PayPal notification settings link.
|
105 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:176
|
106 |
-
#: src/admin-views/tribe-commerce-settings.php:221
|
107 |
-
msgid ""
|
108 |
-
"Override the default IPN notify URL with this value. This value must be the "
|
109 |
-
"same set in PayPal IPN Notifications settings area (%s)."
|
110 |
-
msgstr ""
|
111 |
-
|
112 |
-
#: src/Tickets/Commerce/Gateways/Legacy/Settings.php:191
|
113 |
-
#: src/admin-views/tribe-commerce-settings.php:219
|
114 |
-
msgid "IPN Notify URL"
|
115 |
-
msgstr ""
|
116 |
-
|
117 |
-
#: src/Tickets/Commerce/Gateways/PayPal/AjaxRequestHandler.php:110
|
118 |
-
msgid "Unexpected response from PayPal when onboarding"
|
119 |
-
msgstr ""
|
120 |
-
|
121 |
-
#: src/Tickets/Commerce/Gateways/PayPal/AjaxRequestHandler.php:117
|
122 |
-
msgid "PayPal account onboarded"
|
123 |
-
msgstr ""
|
124 |
-
|
125 |
-
#: src/Tickets/Commerce/Gateways/PayPal/AjaxRequestHandler.php:136
|
126 |
-
msgid "Must include valid 2-character country code"
|
127 |
-
msgstr ""
|
128 |
-
|
129 |
-
#: src/Tickets/Commerce/Gateways/PayPal/AjaxRequestHandler.php:159
|
130 |
-
msgid "Partner details not found"
|
131 |
-
msgstr ""
|
132 |
-
|
133 |
-
#: src/Tickets/Commerce/Gateways/PayPal/AjaxRequestHandler.php:187
|
134 |
-
msgid "PayPal account disconnected"
|
135 |
msgstr ""
|
136 |
|
137 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
138 |
msgid ""
|
139 |
"Make sure to complete the entire PayPal process. Do not close the window you "
|
140 |
"have finished the process."
|
141 |
msgstr ""
|
142 |
|
143 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
144 |
msgid ""
|
145 |
"The last screen of the PayPal connect process includes a button to be sent "
|
146 |
"back to your site. It is important you click this and do not close the "
|
147 |
"window yourself."
|
148 |
msgstr ""
|
149 |
|
150 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
151 |
msgid "If you’re still having problems connecting:"
|
152 |
msgstr ""
|
153 |
|
154 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
155 |
msgid "Having trouble connecting to PayPal?"
|
156 |
msgstr ""
|
157 |
|
158 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
159 |
-
msgid "Access not allowed"
|
160 |
-
msgstr ""
|
161 |
-
|
162 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:39
|
163 |
msgid "Disconnect PayPal Account"
|
164 |
msgstr ""
|
165 |
|
166 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:
|
167 |
msgid "Are you sure you want to disconnect your PayPal account?"
|
168 |
msgstr ""
|
169 |
|
170 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:
|
171 |
msgid "You’re connected to PayPal! Here’s what’s next..."
|
172 |
msgstr ""
|
173 |
|
174 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:
|
175 |
msgid ""
|
176 |
"PayPal allows you to accept credit or debit cards directly on your website. "
|
177 |
"Because of\n"
|
@@ -183,307 +71,366 @@ msgid ""
|
|
183 |
"comprised of, but not limited to:"
|
184 |
msgstr ""
|
185 |
|
186 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:
|
187 |
msgid ""
|
188 |
"Using a trusted, secure hosting provider – preferably one which claims and "
|
189 |
"actively promotes PCI compliance."
|
190 |
msgstr ""
|
191 |
|
192 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:
|
193 |
msgid ""
|
194 |
"Maintain security best practices when setting passwords and limit access to "
|
195 |
"your server."
|
196 |
msgstr ""
|
197 |
|
198 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:
|
199 |
msgid "Implement an SSL certificate to keep your payments secure."
|
200 |
msgstr ""
|
201 |
|
202 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:
|
203 |
msgid "Keep plugins up to date to ensure latest security fixes are present."
|
204 |
msgstr ""
|
205 |
|
206 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:
|
207 |
msgid ""
|
208 |
"You have connected your account for test mode. You will need to connect "
|
209 |
"again once you are in live mode."
|
210 |
msgstr ""
|
211 |
|
212 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:
|
213 |
msgid "PayPal Commerce"
|
214 |
msgstr ""
|
215 |
|
216 |
-
|
217 |
-
#: src/Tickets/Commerce/Gateways/PayPal/SDK/DataTransferObjects/PayPalWebhookHeaders.php:91
|
218 |
-
msgid "Missing PayPal webhook header: %s"
|
219 |
-
msgstr ""
|
220 |
-
|
221 |
-
#: src/Tickets/Commerce/Gateways/PayPal/SDK/Models/PayPalOrder.php:162
|
222 |
msgid "To create a PayPalOrder object, please provide valid %1$s"
|
223 |
msgstr ""
|
224 |
|
225 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
226 |
msgid ""
|
227 |
"To create a PayPalPayment object, please provide valid id, amount, status, "
|
228 |
"create_time, update_time and links"
|
229 |
msgstr ""
|
230 |
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
#: src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/Webhooks.php:155
|
236 |
-
#: src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/Webhooks.php:204
|
237 |
-
#: src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/Webhooks.php:273
|
238 |
-
#: src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/Webhooks.php:364
|
239 |
-
msgid "PayPal request error: %s"
|
240 |
msgstr ""
|
241 |
|
242 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
243 |
-
msgid "
|
244 |
msgstr ""
|
245 |
|
246 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
247 |
-
msgid "
|
248 |
msgstr ""
|
249 |
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
msgstr ""
|
256 |
|
257 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
258 |
-
|
259 |
-
#: src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/PayPalAuth.php:239
|
260 |
-
msgid "Unexpected PayPal Commerce Connect response"
|
261 |
msgstr ""
|
262 |
|
263 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
264 |
msgid ""
|
265 |
-
"
|
|
|
|
|
|
|
266 |
msgstr ""
|
267 |
|
268 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
msgid "Unexpected PayPal response when verifying signature"
|
270 |
msgstr ""
|
271 |
|
272 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
273 |
msgid "Unexpected PayPal response when getting list of webhooks"
|
274 |
msgstr ""
|
275 |
|
276 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
277 |
msgid "The PayPal webhook does not exist"
|
278 |
msgstr ""
|
279 |
|
280 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
281 |
msgid "Unexpected PayPal response when getting webhook"
|
282 |
msgstr ""
|
283 |
|
284 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
285 |
msgid ""
|
286 |
"PayPal webhook limit has been reached, you need to go into your developer."
|
287 |
"paypal.com account and remove webhooks from the associated account"
|
288 |
msgstr ""
|
289 |
|
290 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
291 |
msgid "Unexpected PayPal response when creating webhook"
|
292 |
msgstr ""
|
293 |
|
294 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
295 |
msgid ""
|
296 |
"The PayPal webhook was not able to be updated because it did not exist, "
|
297 |
"attempting to create it now"
|
298 |
msgstr ""
|
299 |
|
300 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
301 |
msgid "Unexpected PayPal response when updating webhook"
|
302 |
msgstr ""
|
303 |
|
304 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Settings.php:
|
305 |
msgid "-- Please select a country --"
|
306 |
msgstr ""
|
307 |
|
308 |
-
|
309 |
-
|
|
|
310 |
msgstr ""
|
311 |
|
312 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Settings.php:
|
313 |
-
msgid "
|
|
|
314 |
msgstr ""
|
315 |
|
316 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Settings.php:
|
317 |
-
msgid "
|
318 |
msgstr ""
|
319 |
|
320 |
-
|
321 |
-
#: src/
|
322 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
msgstr ""
|
324 |
|
325 |
-
#: src/Tickets/Commerce/Gateways/PayPal/
|
|
|
326 |
msgid ""
|
327 |
-
"
|
|
|
328 |
msgstr ""
|
329 |
|
330 |
-
|
331 |
-
|
|
|
332 |
msgstr ""
|
333 |
|
334 |
#. Translators: %s: The PayPal payment event.
|
335 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/
|
336 |
msgid "Mismatched event type for webhook event: %s"
|
337 |
msgstr ""
|
338 |
|
339 |
#. Translators: %s: The PayPal payment event.
|
340 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/
|
341 |
msgid "Missing PayPal payment for webhook event: %s"
|
342 |
msgstr ""
|
343 |
|
344 |
#. Translators: %s: The PayPal payment ID.
|
345 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/
|
346 |
msgid "Missing order for PayPal payment from webhook: %s"
|
347 |
msgstr ""
|
348 |
|
349 |
#. Translators: %1$s: The status name; %2$s: The payment information.
|
350 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/
|
351 |
msgid "Change %1$s in PayPal from webhook: %2$s"
|
352 |
msgstr ""
|
353 |
|
354 |
#. Translators: %s: The error message.
|
355 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/
|
356 |
msgid "PayPal capture request error: %s"
|
357 |
msgstr ""
|
358 |
|
359 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/
|
360 |
msgid "Unexpected PayPal capture response"
|
361 |
msgstr ""
|
362 |
|
363 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/
|
364 |
msgid ""
|
365 |
"There was a problem updating your PayPal Payments webhook. Please disconnect "
|
366 |
"your account and reconnect it."
|
367 |
msgstr ""
|
368 |
|
369 |
#. Translators: %s: The event type.
|
370 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/
|
371 |
msgid "PayPal webhook event type not registered or supported: %s"
|
372 |
msgstr ""
|
373 |
|
374 |
#. Translators: %s: The event type.
|
375 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/
|
376 |
msgid "Received PayPal webhook event for type: %s"
|
377 |
msgstr ""
|
378 |
|
379 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/
|
380 |
msgid "Failed PayPal webhook event verification"
|
381 |
msgstr ""
|
382 |
|
383 |
#. Translators: %s: The event type.
|
384 |
-
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/
|
385 |
msgid "Error processing webhook: %s"
|
386 |
msgstr ""
|
387 |
|
388 |
-
#: src/Tickets/Commerce/
|
389 |
-
|
390 |
-
|
391 |
-
"merchant ID. Paypal return URL is:"
|
392 |
-
msgstr ""
|
393 |
-
|
394 |
-
#: src/Tickets/Commerce/Gateways/PayPal/onBoardingRedirectHandler.php:201
|
395 |
-
msgid ""
|
396 |
-
"There was a problem with creating webhook on PayPal. A gateway error log "
|
397 |
-
"also added to get details information about PayPal response."
|
398 |
-
msgstr ""
|
399 |
-
|
400 |
-
#: src/Tickets/Commerce/Gateways/PayPal/onBoardingRedirectHandler.php:224
|
401 |
-
msgid "PayPal Commerce account connected successfully."
|
402 |
-
msgstr ""
|
403 |
-
|
404 |
-
#: src/Tickets/Commerce/Gateways/PayPal/onBoardingRedirectHandler.php:296
|
405 |
-
msgid "PayPal client access token API request response is:"
|
406 |
-
msgstr ""
|
407 |
-
|
408 |
-
#: src/Tickets/Commerce/Gateways/PayPal/onBoardingRedirectHandler.php:302
|
409 |
-
msgid "PayPal client rest api credentials API request response is:"
|
410 |
-
msgstr ""
|
411 |
-
|
412 |
-
#: src/Tickets/Commerce/Gateways/PayPal/onBoardingRedirectHandler.php:306
|
413 |
-
msgid ""
|
414 |
-
"There was a problem with PayPal client rest API request and we could not "
|
415 |
-
"find valid client id and secret."
|
416 |
-
msgstr ""
|
417 |
-
|
418 |
-
#: src/Tickets/Commerce/Gateways/PayPal/onBoardingRedirectHandler.php:359
|
419 |
-
msgid "PayPal merchant status check API request response is:"
|
420 |
-
msgstr ""
|
421 |
-
|
422 |
-
#: src/Tickets/Commerce/Gateways/PayPal/onBoardingRedirectHandler.php:364
|
423 |
-
msgid ""
|
424 |
-
"A valid SSL certificate is required to accept payments and set up your "
|
425 |
-
"PayPal account. Once a\n"
|
426 |
-
"\t\t\t\t\tcertificate is installed and the site is using https, please "
|
427 |
-
"disconnect and reconnect your account."
|
428 |
msgstr ""
|
429 |
|
430 |
-
#: src/Tickets/Commerce/
|
431 |
-
msgid ""
|
432 |
-
"There was a problem with the status check for your account. Please try "
|
433 |
-
"disconnecting and connecting again. If the problem persists, please contact "
|
434 |
-
"support."
|
435 |
msgstr ""
|
436 |
|
437 |
-
#: src/Tickets/Commerce/
|
438 |
-
msgid "
|
439 |
msgstr ""
|
440 |
|
441 |
-
#: src/Tickets/Commerce/
|
442 |
-
|
|
|
|
|
|
|
443 |
msgstr ""
|
444 |
|
445 |
-
#: src/Tickets/Commerce/
|
446 |
-
|
447 |
-
"
|
448 |
-
|
449 |
-
"\t\t\t\taccount country matches the country setting. If the problem "
|
450 |
-
"persists, please contact PayPal."
|
451 |
msgstr ""
|
452 |
|
453 |
-
#: src/Tickets/Commerce/
|
454 |
-
|
|
|
|
|
455 |
msgstr ""
|
456 |
|
457 |
-
#: src/Tickets/Commerce/
|
458 |
-
|
|
|
459 |
msgstr ""
|
460 |
|
461 |
-
#: src/Tickets/Commerce/
|
462 |
-
|
|
|
463 |
msgstr ""
|
464 |
|
465 |
-
|
466 |
-
#: src/
|
467 |
-
msgid ""
|
468 |
-
"There was a problem setting up the webhooks for your PayPal account. Please "
|
469 |
-
"try disconnecting and reconnecting your PayPal account. If the problem "
|
470 |
-
"persists, please contact support and provide them with the latest %1$s"
|
471 |
msgstr ""
|
472 |
|
473 |
-
#: src/Tickets/Commerce/Settings.php:
|
474 |
-
#: src/Tribe/Main.php:
|
475 |
#: src/admin-views/tribe-commerce-settings.php:4
|
476 |
msgid "Event Tickets Plus"
|
477 |
msgstr ""
|
478 |
|
479 |
-
#: src/Tickets/Commerce/Settings.php:
|
480 |
#: src/admin-views/tribe-commerce-settings.php:9
|
481 |
msgid "Check it out!"
|
482 |
msgstr ""
|
483 |
|
484 |
#. Translators: %1$s: The Event Tickets Plus link, %2$s: The word "ticket" in
|
485 |
#. lowercase, %3$s: The "Check it out!" link.
|
486 |
-
#: src/Tickets/Commerce/Settings.php:
|
487 |
msgctxt "about Tickets Commerce"
|
488 |
msgid ""
|
489 |
"Tickets Commerce is a light implementation of a commerce gateway using "
|
@@ -494,48 +441,40 @@ msgid ""
|
|
494 |
"%3$s"
|
495 |
msgstr ""
|
496 |
|
497 |
-
#: src/Tickets/Commerce/Settings.php:
|
498 |
-
msgid "-- No page set --"
|
499 |
-
msgstr ""
|
500 |
-
|
501 |
-
#: src/Tickets/Commerce/Settings.php:162
|
502 |
-
msgid "Tickets Commerce"
|
503 |
-
msgstr ""
|
504 |
-
|
505 |
-
#: src/Tickets/Commerce/Settings.php:170
|
506 |
msgid "Enable Tickets Commerce"
|
507 |
msgstr ""
|
508 |
|
509 |
-
#: src/Tickets/Commerce/Settings.php:
|
510 |
-
msgid "
|
511 |
msgstr ""
|
512 |
|
513 |
-
#: src/Tickets/Commerce/Settings.php:
|
514 |
msgid "Enable Test Mode"
|
515 |
msgstr ""
|
516 |
|
517 |
-
#: src/Tickets/Commerce/Settings.php:
|
518 |
msgid ""
|
519 |
"Enables Test mode for testing payments. Any payments made will be done on "
|
520 |
"\"sandbox\" accounts."
|
521 |
msgstr ""
|
522 |
|
523 |
-
#: src/Tickets/Commerce/Settings.php:
|
524 |
#: src/admin-views/tribe-commerce-settings.php:136
|
525 |
msgid "Currency Code"
|
526 |
msgstr ""
|
527 |
|
528 |
-
#: src/Tickets/Commerce/Settings.php:
|
529 |
msgid "The currency that will be used for Tickets Commerce transactions."
|
530 |
msgstr ""
|
531 |
|
532 |
-
#: src/Tickets/Commerce/Settings.php:
|
533 |
#: src/admin-views/tribe-commerce-settings.php:144
|
534 |
msgid "Stock Handling"
|
535 |
msgstr ""
|
536 |
|
537 |
#. Translators: %s: The word "ticket" in lowercase.
|
538 |
-
#: src/Tickets/Commerce/Settings.php:
|
539 |
msgctxt "tickets fields settings paypal stock handling"
|
540 |
msgid ""
|
541 |
"When a customer purchases a %s, the payment gateway might flag the order as "
|
@@ -544,61 +483,61 @@ msgid ""
|
|
544 |
msgstr ""
|
545 |
|
546 |
#. Translators: %s: The word "ticket" in lowercase.
|
547 |
-
#: src/Tickets/Commerce/Settings.php:
|
548 |
#: src/admin-views/tribe-commerce-settings.php:150
|
549 |
msgid "Decrease available %s stock as soon as a Pending order is created."
|
550 |
msgstr ""
|
551 |
|
552 |
#. Translators: %s: The word "ticket" in lowercase.
|
553 |
-
#: src/Tickets/Commerce/Settings.php:
|
554 |
msgid ""
|
555 |
"Only decrease available %s stock if an order is confirmed as Completed by "
|
556 |
"the payment gateway."
|
557 |
msgstr ""
|
558 |
|
559 |
-
#: src/Tickets/Commerce/Settings.php:
|
560 |
msgid "Checkout page"
|
561 |
msgstr ""
|
562 |
|
563 |
#. Translators: %s: The [shortcode] for the success page.
|
564 |
-
#: src/Tickets/Commerce/Settings.php:
|
565 |
msgid ""
|
566 |
"This is the page where customers go to complete their purchase. Use the %s "
|
567 |
"shortcode to display the checkout experience in the page content."
|
568 |
msgstr ""
|
569 |
|
570 |
-
#: src/Tickets/Commerce/Settings.php:
|
571 |
#: src/admin-views/tribe-commerce-settings.php:162
|
572 |
msgid "Success page"
|
573 |
msgstr ""
|
574 |
|
575 |
#. Translators: %s: The [shortcode] for the success page.
|
576 |
-
#: src/Tickets/Commerce/Settings.php:
|
577 |
msgid ""
|
578 |
"After a successful order, users will be redirected to this page. Use the %s "
|
579 |
"shortcode to display the order confirmation to the user in the page content."
|
580 |
msgstr ""
|
581 |
|
582 |
-
#: src/Tickets/Commerce/Settings.php:
|
583 |
#: src/admin-views/tribe-commerce-settings.php:176
|
584 |
msgid "Confirmation email sender address"
|
585 |
msgstr ""
|
586 |
|
587 |
#. Translators: %s: The word "tickets" in lowercase.
|
588 |
-
#: src/Tickets/Commerce/Settings.php:
|
589 |
msgctxt "tickets fields settings confirmation email"
|
590 |
msgid ""
|
591 |
"Email address that %s customers will receive confirmation from. Leave empty "
|
592 |
"to use the default WordPress site email address."
|
593 |
msgstr ""
|
594 |
|
595 |
-
#: src/Tickets/Commerce/Settings.php:
|
596 |
#: src/admin-views/tribe-commerce-settings.php:185
|
597 |
msgid "Confirmation email sender name"
|
598 |
msgstr ""
|
599 |
|
600 |
#. Translators: %s: The word "ticket" in lowercase.
|
601 |
-
#: src/Tickets/Commerce/Settings.php:
|
602 |
#: src/admin-views/tribe-commerce-settings.php:186
|
603 |
msgctxt "tickets fields settings paypal email sender"
|
604 |
msgid ""
|
@@ -606,13 +545,13 @@ msgid ""
|
|
606 |
"purchase."
|
607 |
msgstr ""
|
608 |
|
609 |
-
#: src/Tickets/Commerce/Settings.php:
|
610 |
#: src/admin-views/tribe-commerce-settings.php:194
|
611 |
msgid "Confirmation email subject"
|
612 |
msgstr ""
|
613 |
|
614 |
#. Translators: %s: The word "ticket" in lowercase.
|
615 |
-
#: src/Tickets/Commerce/Settings.php:
|
616 |
#: src/admin-views/tribe-commerce-settings.php:195
|
617 |
msgctxt "tickets fields settings paypal email subject"
|
618 |
msgid ""
|
@@ -621,12 +560,96 @@ msgid ""
|
|
621 |
msgstr ""
|
622 |
|
623 |
#. Translators: %s: The word "tickets" in lowercase.
|
624 |
-
#: src/Tickets/Commerce/Settings.php:
|
625 |
#: src/admin-views/tribe-commerce-settings.php:197
|
626 |
msgctxt "tickets fields settings paypal email subject"
|
627 |
msgid "You have %s!"
|
628 |
msgstr ""
|
629 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
630 |
#: src/Tribe/Abstract_Attendance_Totals.php:65
|
631 |
msgctxt "total sold tooltip"
|
632 |
msgid "Includes all ticketed attendees regardless of order status."
|
@@ -637,13 +660,6 @@ msgctxt "total complete tooltip"
|
|
637 |
msgid "Includes ticketed attendees with orders marked Completed."
|
638 |
msgstr ""
|
639 |
|
640 |
-
#: src/Tribe/Admin/Columns/Tickets.php:56
|
641 |
-
#: src/Tribe/Admin/Manager/Service_Provider.php:173 src/Tribe/Attendees.php:212
|
642 |
-
#: src/Tribe/Commerce/PayPal/Main.php:458
|
643 |
-
#: src/Tribe/Tabbed_View/Attendee_Report_Tab.php:22 src/admin-views/list.php:95
|
644 |
-
msgid "Attendees"
|
645 |
-
msgstr ""
|
646 |
-
|
647 |
#: src/Tribe/Admin/Manager/Service_Provider.php:56
|
648 |
msgid "Insecure request."
|
649 |
msgstr ""
|
@@ -889,29 +905,29 @@ msgstr ""
|
|
889 |
msgid "Unticketed"
|
890 |
msgstr ""
|
891 |
|
892 |
-
#: src/Tribe/Assets.php:
|
893 |
msgid "%s header image"
|
894 |
msgstr ""
|
895 |
|
896 |
-
#: src/Tribe/Assets.php:
|
897 |
msgid "Set as %s header"
|
898 |
msgstr ""
|
899 |
|
900 |
-
#: src/Tribe/Assets.php:
|
901 |
msgid "Are you sure you want to delete this ticket? This cannot be undone."
|
902 |
msgstr ""
|
903 |
|
904 |
-
#: src/Tribe/Assets.php:
|
905 |
msgid ""
|
906 |
"It looks like you have modified your shared capacity setting but have not "
|
907 |
"saved or updated the post."
|
908 |
msgstr ""
|
909 |
|
910 |
-
#: src/Tribe/Assets.php:
|
911 |
msgid "Please enter in without thousand separators and currency symbols."
|
912 |
msgstr ""
|
913 |
|
914 |
-
#: src/Tribe/Assets.php:
|
915 |
msgid ""
|
916 |
"There is unsaved attendee information. Are you sure you want to continue?"
|
917 |
msgstr ""
|
@@ -1029,6 +1045,11 @@ msgctxt "attendee export"
|
|
1029 |
msgid "Purchaser Email Address"
|
1030 |
msgstr ""
|
1031 |
|
|
|
|
|
|
|
|
|
|
|
1032 |
#: src/Tribe/Attendees.php:660
|
1033 |
msgid "attendees"
|
1034 |
msgstr ""
|
@@ -1340,27 +1361,11 @@ msgstr ""
|
|
1340 |
msgid "U.S. Dollar (USD)"
|
1341 |
msgstr ""
|
1342 |
|
1343 |
-
#. Translators: %1$s: the post/event title, %2$d: the post/event ID.
|
1344 |
-
#: src/Tribe/Commerce/Orders_Tabbed_View.php:36
|
1345 |
-
#: src/admin-views/attendees.php:34
|
1346 |
-
msgctxt "attendees report screen heading"
|
1347 |
-
msgid "Attendees for: %1$s [#%2$d]"
|
1348 |
-
msgstr ""
|
1349 |
-
|
1350 |
-
#: src/Tribe/Commerce/PayPal/Attendance_Totals.php:77
|
1351 |
-
#: src/Tribe/RSVP/Attendance_Totals.php:49
|
1352 |
-
msgctxt "attendee summary"
|
1353 |
-
msgid "Total %s:"
|
1354 |
-
msgstr ""
|
1355 |
-
|
1356 |
-
#: src/Tribe/Commerce/PayPal/Attendance_Totals.php:78
|
1357 |
-
msgctxt "attendee summary"
|
1358 |
-
msgid "Complete:"
|
1359 |
-
msgstr ""
|
1360 |
-
|
1361 |
-
#: src/Tribe/Commerce/PayPal/Attendance_Totals.php:79
|
1362 |
-
msgctxt "attendee summary"
|
1363 |
-
msgid "Cancelled:"
|
1364 |
msgstr ""
|
1365 |
|
1366 |
#: src/Tribe/Commerce/PayPal/Endpoints/Success_Template.php:99
|
@@ -1403,12 +1408,6 @@ msgid ""
|
|
1403 |
"%s(s) in an email."
|
1404 |
msgstr ""
|
1405 |
|
1406 |
-
#: src/Tribe/Commerce/PayPal/Frontend/Tickets_Form.php:75
|
1407 |
-
msgid ""
|
1408 |
-
"Your PayPal %1$s has been received! Check your email for your PayPal %1$s "
|
1409 |
-
"confirmation."
|
1410 |
-
msgstr ""
|
1411 |
-
|
1412 |
#: src/Tribe/Commerce/PayPal/Handler/IPN.php:143
|
1413 |
msgctxt "a PayPal configuration status"
|
1414 |
msgid "complete"
|
@@ -1438,10 +1437,6 @@ msgctxt "ticket provider"
|
|
1438 |
msgid "Tribe Commerce"
|
1439 |
msgstr ""
|
1440 |
|
1441 |
-
#: src/Tribe/Commerce/PayPal/Main.php:442
|
1442 |
-
msgid "Tickets"
|
1443 |
-
msgstr ""
|
1444 |
-
|
1445 |
#: src/Tribe/Commerce/PayPal/Main.php:444
|
1446 |
msgid "Tribe Commerce Tickets"
|
1447 |
msgstr ""
|
@@ -1450,46 +1445,6 @@ msgstr ""
|
|
1450 |
msgid "Tribe Commerce Ticket"
|
1451 |
msgstr ""
|
1452 |
|
1453 |
-
#: src/Tribe/Commerce/PayPal/Main.php:470
|
1454 |
-
msgid "Orders"
|
1455 |
-
msgstr ""
|
1456 |
-
|
1457 |
-
#: src/Tribe/Commerce/PayPal/Main.php:1726
|
1458 |
-
msgid "Sales report"
|
1459 |
-
msgstr ""
|
1460 |
-
|
1461 |
-
#: src/Tribe/Commerce/PayPal/Main.php:1752
|
1462 |
-
msgid "Report"
|
1463 |
-
msgstr ""
|
1464 |
-
|
1465 |
-
#: src/Tribe/Commerce/PayPal/Main.php:1910 src/Tribe/RSVP.php:2355
|
1466 |
-
msgid "Return to the %1$sAttendees Report%2$s."
|
1467 |
-
msgstr ""
|
1468 |
-
|
1469 |
-
#: src/Tribe/Commerce/PayPal/Main.php:1917 src/Tribe/RSVP.php:2362
|
1470 |
-
msgid "Post updated. %1$s"
|
1471 |
-
msgstr ""
|
1472 |
-
|
1473 |
-
#: src/Tribe/Commerce/PayPal/Main.php:1921 src/Tribe/RSVP.php:2366
|
1474 |
-
msgid "Post published. %1$s"
|
1475 |
-
msgstr ""
|
1476 |
-
|
1477 |
-
#: src/Tribe/Commerce/PayPal/Main.php:1924 src/Tribe/RSVP.php:2369
|
1478 |
-
msgid "Post submitted."
|
1479 |
-
msgstr ""
|
1480 |
-
|
1481 |
-
#: src/Tribe/Commerce/PayPal/Main.php:1925 src/Tribe/RSVP.php:2370
|
1482 |
-
msgid "Post scheduled."
|
1483 |
-
msgstr ""
|
1484 |
-
|
1485 |
-
#: src/Tribe/Commerce/PayPal/Main.php:1926 src/Tribe/RSVP.php:2371
|
1486 |
-
msgid "Post draft updated."
|
1487 |
-
msgstr ""
|
1488 |
-
|
1489 |
-
#: src/Tribe/Commerce/PayPal/Main.php:2961 src/Tribe/RSVP.php:2014
|
1490 |
-
msgid "(deleted)"
|
1491 |
-
msgstr ""
|
1492 |
-
|
1493 |
#: src/Tribe/Commerce/PayPal/Notices.php:43
|
1494 |
msgid "PayPal is using PDT data but you have not set the PDT identity token"
|
1495 |
msgstr ""
|
@@ -1517,11 +1472,6 @@ msgstr ""
|
|
1517 |
msgid "Search Orders"
|
1518 |
msgstr ""
|
1519 |
|
1520 |
-
#: src/Tribe/Commerce/PayPal/Orders/Sales.php:258
|
1521 |
-
#: src/admin-views/tpp-orders.php:173
|
1522 |
-
msgid "Completed"
|
1523 |
-
msgstr ""
|
1524 |
-
|
1525 |
#: src/Tribe/Commerce/PayPal/Orders/Sales.php:262
|
1526 |
msgid "Not completed"
|
1527 |
msgstr ""
|
@@ -1612,14 +1562,6 @@ msgstr ""
|
|
1612 |
msgid "Sell only available"
|
1613 |
msgstr ""
|
1614 |
|
1615 |
-
#: src/Tribe/Commerce/PayPal/Tickets_View.php:106
|
1616 |
-
msgid "This ticket is no longer active."
|
1617 |
-
msgstr ""
|
1618 |
-
|
1619 |
-
#: src/Tribe/Commerce/PayPal/Tickets_View.php:137
|
1620 |
-
msgid "unavailable"
|
1621 |
-
msgstr ""
|
1622 |
-
|
1623 |
#: src/Tribe/Editor/Attendee_Registration.php:127
|
1624 |
msgid "return to the content editor"
|
1625 |
msgstr ""
|
@@ -1781,113 +1723,113 @@ msgstr ""
|
|
1781 |
msgid "Free"
|
1782 |
msgstr ""
|
1783 |
|
1784 |
-
#: src/Tribe/Main.php:
|
1785 |
msgctxt "provider_plugin_name"
|
1786 |
msgid "Tickets"
|
1787 |
msgstr ""
|
1788 |
|
1789 |
-
#: src/Tribe/Main.php:
|
1790 |
msgid ""
|
1791 |
"When The Events Calendar and Event Tickets are both activated, The Events "
|
1792 |
"Calendar must be running version %1$s or greater. Please %2$supdate now.%3$s"
|
1793 |
msgstr ""
|
1794 |
|
1795 |
-
#: src/Tribe/Main.php:
|
1796 |
msgid ""
|
1797 |
"Sorry, Event Tickets requires WordPress %s or higher. Please upgrade your "
|
1798 |
"WordPress install."
|
1799 |
msgstr ""
|
1800 |
|
1801 |
-
#: src/Tribe/Main.php:
|
1802 |
msgid ""
|
1803 |
"Sorry, Event Tickets requires PHP %s or higher. Talk to your Web host about "
|
1804 |
"moving you to a newer version of PHP."
|
1805 |
msgstr ""
|
1806 |
|
1807 |
-
#: src/Tribe/Main.php:
|
1808 |
msgid "Support for Event Tickets"
|
1809 |
msgstr ""
|
1810 |
|
1811 |
-
#: src/Tribe/Main.php:
|
1812 |
msgid "Settings overview"
|
1813 |
msgstr ""
|
1814 |
|
1815 |
-
#: src/Tribe/Main.php:
|
1816 |
msgid "Features overview"
|
1817 |
msgstr ""
|
1818 |
|
1819 |
-
#: src/Tribe/Main.php:
|
1820 |
msgid "Troubleshooting common problems"
|
1821 |
msgstr ""
|
1822 |
|
1823 |
-
#: src/Tribe/Main.php:
|
1824 |
msgid "Customizing Event Tickets"
|
1825 |
msgstr ""
|
1826 |
|
1827 |
-
#: src/Tribe/Main.php:
|
1828 |
msgid "New User Primer"
|
1829 |
msgstr ""
|
1830 |
|
1831 |
-
#: src/Tribe/Main.php:
|
1832 |
msgctxt "help feature box section"
|
1833 |
msgid ""
|
1834 |
"We are committed to helping you sell %1$s for your event. Check out our "
|
1835 |
"handy %2$s to get started."
|
1836 |
msgstr ""
|
1837 |
|
1838 |
-
#: src/Tribe/Main.php:
|
1839 |
msgid "open-source forum on WordPress.org"
|
1840 |
msgstr ""
|
1841 |
|
1842 |
-
#: src/Tribe/Main.php:
|
1843 |
msgid ""
|
1844 |
"If you have tried the above steps and are still having trouble, you can post "
|
1845 |
"a new thread to our %s. Our support staff monitors these forums once a week "
|
1846 |
"and would be happy to assist you there."
|
1847 |
msgstr ""
|
1848 |
|
1849 |
-
#: src/Tribe/Main.php:
|
1850 |
msgid "premium support on our website"
|
1851 |
msgstr ""
|
1852 |
|
1853 |
-
#: src/Tribe/Main.php:
|
1854 |
msgid ""
|
1855 |
"Looking for more immediate support? We offer %1$s with the purchase of any "
|
1856 |
"of our premium plugins (like %2$s). Pick up a license and you can post there "
|
1857 |
"directly and expect a response within 24-48 hours during weekdays."
|
1858 |
msgstr ""
|
1859 |
|
1860 |
-
#: src/Tribe/Main.php:
|
1861 |
msgid "post a thread"
|
1862 |
msgstr ""
|
1863 |
|
1864 |
-
#: src/Tribe/Main.php:
|
1865 |
msgid ""
|
1866 |
"Already have Event Tickets Plus? You can %s in our premium support forums. "
|
1867 |
"Our support team monitors the forums and will respond to your thread within "
|
1868 |
"24-48 hours (during the week)."
|
1869 |
msgstr ""
|
1870 |
|
1871 |
-
#: src/Tribe/Main.php:
|
1872 |
msgid ""
|
1873 |
"If you have a valid license for one of our paid plugins, you can %s in our "
|
1874 |
"premium support forums. Our support team monitors the forums and will "
|
1875 |
"respond to your thread within 24-48 hours (during the week)."
|
1876 |
msgstr ""
|
1877 |
|
1878 |
-
#: src/Tribe/Main.php:
|
1879 |
msgid "Event Tickets - Legacy"
|
1880 |
msgstr ""
|
1881 |
|
1882 |
-
#: src/Tribe/Main.php:
|
1883 |
msgid "Welcome to Event Tickets!"
|
1884 |
msgstr ""
|
1885 |
|
1886 |
-
#: src/Tribe/Main.php:
|
1887 |
msgid "Buy"
|
1888 |
msgstr ""
|
1889 |
|
1890 |
-
#: src/Tribe/Main.php:
|
1891 |
msgid ""
|
1892 |
"When Event Tickets and Event Tickets Plus are both activated, Event Tickets "
|
1893 |
"Plus must be running version %1$s or greater. Please %2$smanually update now"
|
@@ -2490,18 +2432,6 @@ msgstr ""
|
|
2490 |
msgid "List of meta for each ticket to be saved for Attendee Registration"
|
2491 |
msgstr ""
|
2492 |
|
2493 |
-
#: src/Tribe/REST/V1/Endpoints/Commerce/PayPal_Webhook.php:48
|
2494 |
-
msgid "Processes the Webhook as long as it includes valid Payment Event data"
|
2495 |
-
msgstr ""
|
2496 |
-
|
2497 |
-
#: src/Tribe/REST/V1/Endpoints/Commerce/PayPal_Webhook.php:55
|
2498 |
-
msgid "Whether the processing was successful"
|
2499 |
-
msgstr ""
|
2500 |
-
|
2501 |
-
#: src/Tribe/REST/V1/Endpoints/Commerce/PayPal_Webhook.php:64
|
2502 |
-
msgid "The webhook was invalid and was not processed"
|
2503 |
-
msgstr ""
|
2504 |
-
|
2505 |
#: src/Tribe/REST/V1/Endpoints/Single_Attendee.php:19
|
2506 |
msgid "Returns the data of the attendee with the specified post ID"
|
2507 |
msgstr ""
|
@@ -3153,7 +3083,7 @@ msgid "Select a User:"
|
|
3153 |
msgstr ""
|
3154 |
|
3155 |
#: src/admin-views/attendees-email.php:36
|
3156 |
-
#: src/views/modal/registration-js.php:
|
3157 |
msgid "or"
|
3158 |
msgstr ""
|
3159 |
|
@@ -3187,6 +3117,33 @@ msgstr ""
|
|
3187 |
msgid "Search attendees"
|
3188 |
msgstr ""
|
3189 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3190 |
#: src/admin-views/editor/button-view-orders.php:46
|
3191 |
msgid "View Orders"
|
3192 |
msgstr ""
|
@@ -3272,12 +3229,6 @@ msgctxt "ticket type label"
|
|
3272 |
msgid "%s Type:"
|
3273 |
msgstr ""
|
3274 |
|
3275 |
-
#: src/admin-views/editor/list-row.php:99
|
3276 |
-
#: src/admin-views/rsvp-metabox-capacity.php:10
|
3277 |
-
#: src/admin-views/tpp-metabox-capacity.php:16
|
3278 |
-
msgid "Capacity:"
|
3279 |
-
msgstr ""
|
3280 |
-
|
3281 |
#: src/admin-views/editor/list-row.php:104
|
3282 |
msgid "Available:"
|
3283 |
msgstr ""
|
@@ -3674,6 +3625,74 @@ msgid ""
|
|
3674 |
"statuses:"
|
3675 |
msgstr ""
|
3676 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3677 |
#: src/admin-views/privacy.php:16
|
3678 |
msgid "Hello,"
|
3679 |
msgstr ""
|
@@ -3809,11 +3828,6 @@ msgid ""
|
|
3809 |
"to these external services. These services may be located abroad."
|
3810 |
msgstr ""
|
3811 |
|
3812 |
-
#: src/admin-views/rsvp-metabox-capacity.php:19
|
3813 |
-
#: src/admin-views/tpp-metabox-capacity.php:25
|
3814 |
-
msgid "Leave blank for unlimited"
|
3815 |
-
msgstr ""
|
3816 |
-
|
3817 |
#: src/admin-views/rsvp-metabox-not-going.php:17
|
3818 |
msgid "Can't Go:"
|
3819 |
msgstr ""
|
@@ -3907,49 +3921,27 @@ msgstr ""
|
|
3907 |
msgid "Connected for payments as"
|
3908 |
msgstr ""
|
3909 |
|
3910 |
-
#: src/admin-views/settings/tickets-commerce/paypal-commerce/connect-with-paypal.php:62
|
3911 |
-
msgid "Disconnect"
|
3912 |
-
msgstr ""
|
3913 |
-
|
3914 |
#: src/admin-views/settings/tickets-commerce/paypal-commerce/connect-with-paypal.php:68
|
3915 |
msgid "APIs Connected:"
|
3916 |
msgstr ""
|
3917 |
|
3918 |
-
#: src/admin-views/settings/tickets-commerce/paypal-commerce/connect-with-paypal.php:70
|
3919 |
-
msgid "Payments"
|
3920 |
-
msgstr ""
|
3921 |
-
|
3922 |
#: src/admin-views/settings/tickets-commerce/paypal-commerce/connect-with-paypal.php:71
|
3923 |
msgid "Refunds"
|
3924 |
msgstr ""
|
3925 |
|
3926 |
-
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:
|
3927 |
-
msgid "Accept payments with PayPal Commerce"
|
3928 |
-
msgstr ""
|
3929 |
-
|
3930 |
-
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:19
|
3931 |
-
msgid ""
|
3932 |
-
"Allow your customers to pay using Debit or Credit Cards directly on your "
|
3933 |
-
"website."
|
3934 |
-
msgstr ""
|
3935 |
-
|
3936 |
-
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:23
|
3937 |
msgid "PayPal Logo Image"
|
3938 |
msgstr ""
|
3939 |
|
3940 |
-
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:
|
3941 |
msgid "Credit and Debit Card payments"
|
3942 |
msgstr ""
|
3943 |
|
3944 |
-
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:
|
3945 |
msgid "Easy no-API key connection"
|
3946 |
msgstr ""
|
3947 |
|
3948 |
-
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:
|
3949 |
-
msgid "Accept payments from around the world"
|
3950 |
-
msgstr ""
|
3951 |
-
|
3952 |
-
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:37
|
3953 |
msgid "Supports 3D Secure payments"
|
3954 |
msgstr ""
|
3955 |
|
@@ -3966,14 +3958,6 @@ msgstr ""
|
|
3966 |
msgid "Click to hide history"
|
3967 |
msgstr ""
|
3968 |
|
3969 |
-
#: src/admin-views/tpp-metabox-sku.php:20
|
3970 |
-
msgid "SKU:"
|
3971 |
-
msgstr ""
|
3972 |
-
|
3973 |
-
#: src/admin-views/tpp-metabox-sku.php:33
|
3974 |
-
msgid "A unique identifying code for each %s type you're selling"
|
3975 |
-
msgstr ""
|
3976 |
-
|
3977 |
#: src/admin-views/tpp-orders.php:32
|
3978 |
msgid "Orders Report"
|
3979 |
msgstr ""
|
@@ -4006,6 +3990,10 @@ msgid ""
|
|
4006 |
"%3$s"
|
4007 |
msgstr ""
|
4008 |
|
|
|
|
|
|
|
|
|
4009 |
#: src/admin-views/tribe-commerce-settings.php:41
|
4010 |
msgctxt "tickets fields settings PayPal setup"
|
4011 |
msgid ""
|
@@ -4014,6 +4002,16 @@ msgid ""
|
|
4014 |
"set up, follow %2$s"
|
4015 |
msgstr ""
|
4016 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4017 |
#: src/admin-views/tribe-commerce-settings.php:55
|
4018 |
msgid "Tribe Commerce"
|
4019 |
msgstr ""
|
@@ -4030,6 +4028,31 @@ msgstr ""
|
|
4030 |
msgid "Configure PayPal:"
|
4031 |
msgstr ""
|
4032 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4033 |
#: src/admin-views/tribe-commerce-settings.php:129
|
4034 |
msgid "PayPal Sandbox"
|
4035 |
msgstr ""
|
@@ -4069,6 +4092,22 @@ msgid ""
|
|
4069 |
"empty to use the default WordPress site email address."
|
4070 |
msgstr ""
|
4071 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4072 |
#. Translators: %1$s: dynamic "RSVP" text.
|
4073 |
#: src/admin-views/tribe-options-display.php:28
|
4074 |
msgctxt "title of settings section"
|
@@ -4637,18 +4676,18 @@ msgstr ""
|
|
4637 |
msgid "One Moment..."
|
4638 |
msgstr ""
|
4639 |
|
4640 |
-
#: src/views/modal/registration-js.php:
|
4641 |
msgid "Attendee Details"
|
4642 |
msgstr ""
|
4643 |
|
4644 |
-
#: src/views/modal/registration-js.php:
|
4645 |
#: src/views/registration-js/content.php:100
|
4646 |
msgctxt ""
|
4647 |
"Note about missing required fields, %s is the html-wrapped number of tickets."
|
4648 |
msgid "You have %s ticket(s) with a field that requires information."
|
4649 |
msgstr ""
|
4650 |
|
4651 |
-
#: src/views/modal/registration-js.php:
|
4652 |
#: src/views/registration-js/content.php:196
|
4653 |
msgctxt ""
|
4654 |
"Note that there are more tickets in the cart, %s is the html-wrapped number."
|
@@ -4657,20 +4696,20 @@ msgid ""
|
|
4657 |
"information."
|
4658 |
msgstr ""
|
4659 |
|
4660 |
-
#: src/views/modal/registration-js.php:
|
4661 |
#: src/views/registration/content.php:111
|
4662 |
msgid "Save and Checkout"
|
4663 |
msgstr ""
|
4664 |
|
4665 |
-
#: src/views/modal/registration-js.php:
|
4666 |
msgid "Save and View Cart"
|
4667 |
msgstr ""
|
4668 |
|
4669 |
-
#: src/views/modal/registration-js.php:
|
4670 |
msgid "Checkout Now"
|
4671 |
msgstr ""
|
4672 |
|
4673 |
-
#: src/views/modal/registration.php:
|
4674 |
msgid "Save Attendee Info"
|
4675 |
msgstr ""
|
4676 |
|
@@ -4962,6 +5001,63 @@ msgstr ""
|
|
4962 |
msgid "Buy now"
|
4963 |
msgstr ""
|
4964 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4965 |
#: src/views/v2/rsvp/actions/full.php:22
|
4966 |
msgid "RSVP Closed"
|
4967 |
msgstr ""
|
2 |
# This file is distributed under the same license as the Event Tickets package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: Event Tickets 5.1.9\n"
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/event-tickets\n"
|
7 |
+
"POT-Creation-Date: 2021-08-31 16:17:29+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2021-08-31 16:17\n"
|
12 |
"Last-Translator: \n"
|
13 |
"Language-Team: \n"
|
14 |
|
15 |
+
#. #-#-#-#-# event-tickets.pot (Event Tickets 5.1.9) #-#-#-#-#
|
16 |
#. Plugin Name of the plugin/theme
|
17 |
+
#: event-tickets.php:62 src/Tribe/Admin/Notices.php:92 src/Tribe/Main.php:691
|
18 |
#: src/Tribe/Privacy.php:59 src/admin-views/admin-welcome-message.php:58
|
19 |
msgid "Event Tickets"
|
20 |
msgstr ""
|
21 |
|
22 |
+
#: src/Tickets/Commerce/Attendee.php:176 src/Tribe/Admin/Columns/Tickets.php:56
|
23 |
+
#: src/Tribe/Admin/Manager/Service_Provider.php:173 src/Tribe/Attendees.php:212
|
24 |
+
#: src/Tribe/Commerce/PayPal/Main.php:458
|
25 |
+
#: src/Tribe/Tabbed_View/Attendee_Report_Tab.php:22 src/admin-views/list.php:95
|
26 |
+
msgid "Attendees"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
msgstr ""
|
28 |
|
29 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Ajax_Request_Handler.php:30
|
30 |
msgid ""
|
31 |
"Make sure to complete the entire PayPal process. Do not close the window you "
|
32 |
"have finished the process."
|
33 |
msgstr ""
|
34 |
|
35 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Ajax_Request_Handler.php:31
|
36 |
msgid ""
|
37 |
"The last screen of the PayPal connect process includes a button to be sent "
|
38 |
"back to your site. It is important you click this and do not close the "
|
39 |
"window yourself."
|
40 |
msgstr ""
|
41 |
|
42 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Ajax_Request_Handler.php:32
|
43 |
msgid "If you’re still having problems connecting:"
|
44 |
msgstr ""
|
45 |
|
46 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Ajax_Request_Handler.php:38
|
47 |
msgid "Having trouble connecting to PayPal?"
|
48 |
msgstr ""
|
49 |
|
50 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:42
|
|
|
|
|
|
|
|
|
51 |
msgid "Disconnect PayPal Account"
|
52 |
msgstr ""
|
53 |
|
54 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:43
|
55 |
msgid "Are you sure you want to disconnect your PayPal account?"
|
56 |
msgstr ""
|
57 |
|
58 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:44
|
59 |
msgid "You’re connected to PayPal! Here’s what’s next..."
|
60 |
msgstr ""
|
61 |
|
62 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:46
|
63 |
msgid ""
|
64 |
"PayPal allows you to accept credit or debit cards directly on your website. "
|
65 |
"Because of\n"
|
71 |
"comprised of, but not limited to:"
|
72 |
msgstr ""
|
73 |
|
74 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:56
|
75 |
msgid ""
|
76 |
"Using a trusted, secure hosting provider – preferably one which claims and "
|
77 |
"actively promotes PCI compliance."
|
78 |
msgstr ""
|
79 |
|
80 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:57
|
81 |
msgid ""
|
82 |
"Maintain security best practices when setting passwords and limit access to "
|
83 |
"your server."
|
84 |
msgstr ""
|
85 |
|
86 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:58
|
87 |
msgid "Implement an SSL certificate to keep your payments secure."
|
88 |
msgstr ""
|
89 |
|
90 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:59
|
91 |
msgid "Keep plugins up to date to ensure latest security fixes are present."
|
92 |
msgstr ""
|
93 |
|
94 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Assets.php:62
|
95 |
msgid ""
|
96 |
"You have connected your account for test mode. You will need to connect "
|
97 |
"again once you are in live mode."
|
98 |
msgstr ""
|
99 |
|
100 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:43
|
101 |
msgid "PayPal Commerce"
|
102 |
msgstr ""
|
103 |
|
104 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Models/PayPal_Order.php:160
|
|
|
|
|
|
|
|
|
|
|
105 |
msgid "To create a PayPalOrder object, please provide valid %1$s"
|
106 |
msgstr ""
|
107 |
|
108 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Models/PayPal_Payment.php:113
|
109 |
msgid ""
|
110 |
"To create a PayPalPayment object, please provide valid id, amount, status, "
|
111 |
"create_time, update_time and links"
|
112 |
msgstr ""
|
113 |
|
114 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:38
|
115 |
+
msgid ""
|
116 |
+
"There was a problem with creating webhook on PayPal. A gateway error log "
|
117 |
+
"also added to get details information about PayPal response."
|
|
|
|
|
|
|
|
|
|
|
118 |
msgstr ""
|
119 |
|
120 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:68
|
121 |
+
msgid "PayPal client access token API request response is:"
|
122 |
msgstr ""
|
123 |
|
124 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:74
|
125 |
+
msgid "PayPal client rest API credentials API request response is:"
|
126 |
msgstr ""
|
127 |
|
128 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:78
|
129 |
+
msgid ""
|
130 |
+
"There was a problem with PayPal client rest API request and we could not "
|
131 |
+
"find valid client id and secret."
|
132 |
+
msgstr ""
|
133 |
+
|
134 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:107
|
135 |
+
msgid "PayPal merchant status check API request response is:"
|
136 |
+
msgstr ""
|
137 |
+
|
138 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:112
|
139 |
+
msgid ""
|
140 |
+
"A valid SSL certificate is required to accept payments and set up your "
|
141 |
+
"PayPal account. Once a\n"
|
142 |
+
"\t\t\t\t\tcertificate is installed and the site is using https, please "
|
143 |
+
"disconnect and reconnect your account."
|
144 |
+
msgstr ""
|
145 |
+
|
146 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:117
|
147 |
+
msgid ""
|
148 |
+
"There was a problem with the status check for your account. Please try "
|
149 |
+
"disconnecting and connecting again. If the problem persists, please contact "
|
150 |
+
"support."
|
151 |
+
msgstr ""
|
152 |
+
|
153 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:130
|
154 |
+
msgid "Set up an account to receive payment from PayPal"
|
155 |
msgstr ""
|
156 |
|
157 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:134
|
158 |
+
msgid "Confirm your primary email address"
|
|
|
|
|
159 |
msgstr ""
|
160 |
|
161 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:142
|
162 |
msgid ""
|
163 |
+
"Your account was expected to be able to accept custom payments, but is not. "
|
164 |
+
"Please make sure your\n"
|
165 |
+
"\t\t\t\taccount country matches the country setting. If the problem "
|
166 |
+
"persists, please contact PayPal."
|
167 |
msgstr ""
|
168 |
|
169 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:160
|
170 |
+
msgid "Reach out to PayPal to enable PPCP_CUSTOM for your account"
|
171 |
+
msgstr ""
|
172 |
+
|
173 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:172
|
174 |
+
msgid "Reach out to PayPal to resolve the following capabilities:"
|
175 |
+
msgstr ""
|
176 |
+
|
177 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:200
|
178 |
+
msgid "logged data"
|
179 |
+
msgstr ""
|
180 |
+
|
181 |
+
#. Translators: %1$s: The logged data link.
|
182 |
+
#: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:207
|
183 |
+
msgid ""
|
184 |
+
"There was a problem setting up the webhooks for your PayPal account. Please "
|
185 |
+
"try disconnecting and reconnecting your PayPal account. If the problem "
|
186 |
+
"persists, please contact support and provide them with the latest %1$s"
|
187 |
+
msgstr ""
|
188 |
+
|
189 |
+
#: src/Tickets/Commerce/Gateways/PayPal/REST/On_Boarding_Endpoint.php:139
|
190 |
+
msgid "Unexpected response from PayPal when on boarding"
|
191 |
+
msgstr ""
|
192 |
+
|
193 |
+
#: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:234
|
194 |
+
msgid "Order ID in PayPal"
|
195 |
+
msgstr ""
|
196 |
+
|
197 |
+
#: src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php:73
|
198 |
+
msgid "Processes the Webhook as long as it includes valid Payment Event data"
|
199 |
+
msgstr ""
|
200 |
+
|
201 |
+
#: src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php:80
|
202 |
+
msgid "Whether the processing was successful"
|
203 |
+
msgstr ""
|
204 |
+
|
205 |
+
#: src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php:89
|
206 |
+
msgid "The webhook was invalid and was not processed"
|
207 |
+
msgstr ""
|
208 |
+
|
209 |
+
#. Translators: %s: The error message.
|
210 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Authorization.php:69
|
211 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:100
|
212 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:149
|
213 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:198
|
214 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:267
|
215 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:359
|
216 |
+
msgid "PayPal request error: %s"
|
217 |
+
msgstr ""
|
218 |
+
|
219 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Authorization.php:80
|
220 |
+
msgid "Unexpected PayPal response when getting token from client credentials"
|
221 |
+
msgstr ""
|
222 |
+
|
223 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:111
|
224 |
msgid "Unexpected PayPal response when verifying signature"
|
225 |
msgstr ""
|
226 |
|
227 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:160
|
228 |
msgid "Unexpected PayPal response when getting list of webhooks"
|
229 |
msgstr ""
|
230 |
|
231 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:211
|
232 |
msgid "The PayPal webhook does not exist"
|
233 |
msgstr ""
|
234 |
|
235 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:214
|
236 |
msgid "Unexpected PayPal response when getting webhook"
|
237 |
msgstr ""
|
238 |
|
239 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:292
|
240 |
msgid ""
|
241 |
"PayPal webhook limit has been reached, you need to go into your developer."
|
242 |
"paypal.com account and remove webhooks from the associated account"
|
243 |
msgstr ""
|
244 |
|
245 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:296
|
246 |
msgid "Unexpected PayPal response when creating webhook"
|
247 |
msgstr ""
|
248 |
|
249 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:375
|
250 |
msgid ""
|
251 |
"The PayPal webhook was not able to be updated because it did not exist, "
|
252 |
"attempting to create it now"
|
253 |
msgstr ""
|
254 |
|
255 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Repositories/Webhooks.php:383
|
256 |
msgid "Unexpected PayPal response when updating webhook"
|
257 |
msgstr ""
|
258 |
|
259 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Settings.php:33
|
260 |
msgid "-- Please select a country --"
|
261 |
msgstr ""
|
262 |
|
263 |
+
#. Translators: %s: The PayPal telephone number.
|
264 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Settings.php:82
|
265 |
+
msgid "Please call a PayPal support representative at %s"
|
266 |
msgstr ""
|
267 |
|
268 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Settings.php:86
|
269 |
+
msgid ""
|
270 |
+
"Please reach out to PayPal support from your PayPal account Resolution Center"
|
271 |
msgstr ""
|
272 |
|
273 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Settings.php:89
|
274 |
+
msgid " and relay the following message:"
|
275 |
msgstr ""
|
276 |
|
277 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php:77
|
278 |
+
#: src/Tribe/Commerce/PayPal/Main.php:1910 src/Tribe/RSVP.php:2355
|
279 |
+
msgid "Return to the %1$sAttendees Report%2$s."
|
280 |
+
msgstr ""
|
281 |
+
|
282 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php:84
|
283 |
+
#: src/Tribe/Commerce/PayPal/Main.php:1917 src/Tribe/RSVP.php:2362
|
284 |
+
msgid "Post updated. %1$s"
|
285 |
+
msgstr ""
|
286 |
+
|
287 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php:88
|
288 |
+
#: src/Tribe/Commerce/PayPal/Main.php:1921 src/Tribe/RSVP.php:2366
|
289 |
+
msgid "Post published. %1$s"
|
290 |
+
msgstr ""
|
291 |
+
|
292 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php:91
|
293 |
+
#: src/Tribe/Commerce/PayPal/Main.php:1924 src/Tribe/RSVP.php:2369
|
294 |
+
msgid "Post submitted."
|
295 |
+
msgstr ""
|
296 |
+
|
297 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php:92
|
298 |
+
#: src/Tribe/Commerce/PayPal/Main.php:1925 src/Tribe/RSVP.php:2370
|
299 |
+
msgid "Post scheduled."
|
300 |
+
msgstr ""
|
301 |
+
|
302 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php:93
|
303 |
+
#: src/Tribe/Commerce/PayPal/Main.php:1926 src/Tribe/RSVP.php:2371
|
304 |
+
msgid "Post draft updated."
|
305 |
msgstr ""
|
306 |
|
307 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php:149
|
308 |
+
#: src/Tribe/Commerce/PayPal/Frontend/Tickets_Form.php:75
|
309 |
msgid ""
|
310 |
+
"Your PayPal %1$s has been received! Check your email for your PayPal %1$s "
|
311 |
+
"confirmation."
|
312 |
msgstr ""
|
313 |
|
314 |
+
#. Translators: %s: The missing keys and header information.
|
315 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Headers.php:92
|
316 |
+
msgid "Missing PayPal webhook header: %s"
|
317 |
msgstr ""
|
318 |
|
319 |
#. Translators: %s: The PayPal payment event.
|
320 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/Payment_Event_Listener.php:97
|
321 |
msgid "Mismatched event type for webhook event: %s"
|
322 |
msgstr ""
|
323 |
|
324 |
#. Translators: %s: The PayPal payment event.
|
325 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/Payment_Event_Listener.php:112
|
326 |
msgid "Missing PayPal payment for webhook event: %s"
|
327 |
msgstr ""
|
328 |
|
329 |
#. Translators: %s: The PayPal payment ID.
|
330 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/Payment_Event_Listener.php:128
|
331 |
msgid "Missing order for PayPal payment from webhook: %s"
|
332 |
msgstr ""
|
333 |
|
334 |
#. Translators: %1$s: The status name; %2$s: The payment information.
|
335 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/Payment_Event_Listener.php:153
|
336 |
msgid "Change %1$s in PayPal from webhook: %2$s"
|
337 |
msgstr ""
|
338 |
|
339 |
#. Translators: %s: The error message.
|
340 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/Payment_Event_Listener.php:230
|
341 |
msgid "PayPal capture request error: %s"
|
342 |
msgstr ""
|
343 |
|
344 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/Payment_Event_Listener.php:241
|
345 |
msgid "Unexpected PayPal capture response"
|
346 |
msgstr ""
|
347 |
|
348 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Webhook_Checker.php:98
|
349 |
msgid ""
|
350 |
"There was a problem updating your PayPal Payments webhook. Please disconnect "
|
351 |
"your account and reconnect it."
|
352 |
msgstr ""
|
353 |
|
354 |
#. Translators: %s: The event type.
|
355 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Webhooks_Route.php:99
|
356 |
msgid "PayPal webhook event type not registered or supported: %s"
|
357 |
msgstr ""
|
358 |
|
359 |
#. Translators: %s: The event type.
|
360 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Webhooks_Route.php:111
|
361 |
msgid "Received PayPal webhook event for type: %s"
|
362 |
msgstr ""
|
363 |
|
364 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Webhooks_Route.php:120
|
365 |
msgid "Failed PayPal webhook event verification"
|
366 |
msgstr ""
|
367 |
|
368 |
#. Translators: %s: The event type.
|
369 |
+
#: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Webhooks_Route.php:134
|
370 |
msgid "Error processing webhook: %s"
|
371 |
msgstr ""
|
372 |
|
373 |
+
#: src/Tickets/Commerce/Models/Attendee_Model.php:69
|
374 |
+
#: src/Tribe/Commerce/PayPal/Main.php:2961 src/Tribe/RSVP.php:2014
|
375 |
+
msgid "(deleted)"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
msgstr ""
|
377 |
|
378 |
+
#: src/Tickets/Commerce/Module.php:19
|
379 |
+
msgid "Tickets Commerce"
|
|
|
|
|
|
|
380 |
msgstr ""
|
381 |
|
382 |
+
#: src/Tickets/Commerce/Order.php:143 src/Tribe/Commerce/PayPal/Main.php:470
|
383 |
+
msgid "Orders"
|
384 |
msgstr ""
|
385 |
|
386 |
+
#: src/Tickets/Commerce/Reports/Attendance_Totals.php:84
|
387 |
+
#: src/Tribe/Commerce/PayPal/Attendance_Totals.php:77
|
388 |
+
#: src/Tribe/RSVP/Attendance_Totals.php:49
|
389 |
+
msgctxt "attendee summary"
|
390 |
+
msgid "Total %s:"
|
391 |
msgstr ""
|
392 |
|
393 |
+
#: src/Tickets/Commerce/Reports/Attendance_Totals.php:85
|
394 |
+
#: src/Tribe/Commerce/PayPal/Attendance_Totals.php:78
|
395 |
+
msgctxt "attendee summary"
|
396 |
+
msgid "Complete:"
|
|
|
|
|
397 |
msgstr ""
|
398 |
|
399 |
+
#: src/Tickets/Commerce/Reports/Attendance_Totals.php:86
|
400 |
+
#: src/Tribe/Commerce/PayPal/Attendance_Totals.php:79
|
401 |
+
msgctxt "attendee summary"
|
402 |
+
msgid "Cancelled:"
|
403 |
msgstr ""
|
404 |
|
405 |
+
#: src/Tickets/Commerce/Reports/Event.php:53
|
406 |
+
#: src/Tribe/Commerce/PayPal/Main.php:1726
|
407 |
+
msgid "Sales report"
|
408 |
msgstr ""
|
409 |
|
410 |
+
#: src/Tickets/Commerce/Reports/Ticket.php:38
|
411 |
+
#: src/Tribe/Commerce/PayPal/Main.php:1752
|
412 |
+
msgid "Report"
|
413 |
msgstr ""
|
414 |
|
415 |
+
#: src/Tickets/Commerce/Settings.php:119
|
416 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/connect-with-paypal.php:70
|
417 |
+
msgid "Payments"
|
|
|
|
|
|
|
418 |
msgstr ""
|
419 |
|
420 |
+
#: src/Tickets/Commerce/Settings.php:134 src/Tribe/Admin/Notices.php:214
|
421 |
+
#: src/Tribe/Main.php:666 src/admin-views/admin-welcome-message.php:56
|
422 |
#: src/admin-views/tribe-commerce-settings.php:4
|
423 |
msgid "Event Tickets Plus"
|
424 |
msgstr ""
|
425 |
|
426 |
+
#: src/Tickets/Commerce/Settings.php:138
|
427 |
#: src/admin-views/tribe-commerce-settings.php:9
|
428 |
msgid "Check it out!"
|
429 |
msgstr ""
|
430 |
|
431 |
#. Translators: %1$s: The Event Tickets Plus link, %2$s: The word "ticket" in
|
432 |
#. lowercase, %3$s: The "Check it out!" link.
|
433 |
+
#: src/Tickets/Commerce/Settings.php:142
|
434 |
msgctxt "about Tickets Commerce"
|
435 |
msgid ""
|
436 |
"Tickets Commerce is a light implementation of a commerce gateway using "
|
441 |
"%3$s"
|
442 |
msgstr ""
|
443 |
|
444 |
+
#: src/Tickets/Commerce/Settings.php:154
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
445 |
msgid "Enable Tickets Commerce"
|
446 |
msgstr ""
|
447 |
|
448 |
+
#: src/Tickets/Commerce/Settings.php:199
|
449 |
+
msgid "-- No page set --"
|
450 |
msgstr ""
|
451 |
|
452 |
+
#: src/Tickets/Commerce/Settings.php:214
|
453 |
msgid "Enable Test Mode"
|
454 |
msgstr ""
|
455 |
|
456 |
+
#: src/Tickets/Commerce/Settings.php:215
|
457 |
msgid ""
|
458 |
"Enables Test mode for testing payments. Any payments made will be done on "
|
459 |
"\"sandbox\" accounts."
|
460 |
msgstr ""
|
461 |
|
462 |
+
#: src/Tickets/Commerce/Settings.php:221
|
463 |
#: src/admin-views/tribe-commerce-settings.php:136
|
464 |
msgid "Currency Code"
|
465 |
msgstr ""
|
466 |
|
467 |
+
#: src/Tickets/Commerce/Settings.php:222
|
468 |
msgid "The currency that will be used for Tickets Commerce transactions."
|
469 |
msgstr ""
|
470 |
|
471 |
+
#: src/Tickets/Commerce/Settings.php:229
|
472 |
#: src/admin-views/tribe-commerce-settings.php:144
|
473 |
msgid "Stock Handling"
|
474 |
msgstr ""
|
475 |
|
476 |
#. Translators: %s: The word "ticket" in lowercase.
|
477 |
+
#: src/Tickets/Commerce/Settings.php:233
|
478 |
msgctxt "tickets fields settings paypal stock handling"
|
479 |
msgid ""
|
480 |
"When a customer purchases a %s, the payment gateway might flag the order as "
|
483 |
msgstr ""
|
484 |
|
485 |
#. Translators: %s: The word "ticket" in lowercase.
|
486 |
+
#: src/Tickets/Commerce/Settings.php:242
|
487 |
#: src/admin-views/tribe-commerce-settings.php:150
|
488 |
msgid "Decrease available %s stock as soon as a Pending order is created."
|
489 |
msgstr ""
|
490 |
|
491 |
#. Translators: %s: The word "ticket" in lowercase.
|
492 |
+
#: src/Tickets/Commerce/Settings.php:247
|
493 |
msgid ""
|
494 |
"Only decrease available %s stock if an order is confirmed as Completed by "
|
495 |
"the payment gateway."
|
496 |
msgstr ""
|
497 |
|
498 |
+
#: src/Tickets/Commerce/Settings.php:255
|
499 |
msgid "Checkout page"
|
500 |
msgstr ""
|
501 |
|
502 |
#. Translators: %s: The [shortcode] for the success page.
|
503 |
+
#: src/Tickets/Commerce/Settings.php:259
|
504 |
msgid ""
|
505 |
"This is the page where customers go to complete their purchase. Use the %s "
|
506 |
"shortcode to display the checkout experience in the page content."
|
507 |
msgstr ""
|
508 |
|
509 |
+
#: src/Tickets/Commerce/Settings.php:270
|
510 |
#: src/admin-views/tribe-commerce-settings.php:162
|
511 |
msgid "Success page"
|
512 |
msgstr ""
|
513 |
|
514 |
#. Translators: %s: The [shortcode] for the success page.
|
515 |
+
#: src/Tickets/Commerce/Settings.php:274
|
516 |
msgid ""
|
517 |
"After a successful order, users will be redirected to this page. Use the %s "
|
518 |
"shortcode to display the order confirmation to the user in the page content."
|
519 |
msgstr ""
|
520 |
|
521 |
+
#: src/Tickets/Commerce/Settings.php:285
|
522 |
#: src/admin-views/tribe-commerce-settings.php:176
|
523 |
msgid "Confirmation email sender address"
|
524 |
msgstr ""
|
525 |
|
526 |
#. Translators: %s: The word "tickets" in lowercase.
|
527 |
+
#: src/Tickets/Commerce/Settings.php:289
|
528 |
msgctxt "tickets fields settings confirmation email"
|
529 |
msgid ""
|
530 |
"Email address that %s customers will receive confirmation from. Leave empty "
|
531 |
"to use the default WordPress site email address."
|
532 |
msgstr ""
|
533 |
|
534 |
+
#: src/Tickets/Commerce/Settings.php:300
|
535 |
#: src/admin-views/tribe-commerce-settings.php:185
|
536 |
msgid "Confirmation email sender name"
|
537 |
msgstr ""
|
538 |
|
539 |
#. Translators: %s: The word "ticket" in lowercase.
|
540 |
+
#: src/Tickets/Commerce/Settings.php:304
|
541 |
#: src/admin-views/tribe-commerce-settings.php:186
|
542 |
msgctxt "tickets fields settings paypal email sender"
|
543 |
msgid ""
|
545 |
"purchase."
|
546 |
msgstr ""
|
547 |
|
548 |
+
#: src/Tickets/Commerce/Settings.php:315
|
549 |
#: src/admin-views/tribe-commerce-settings.php:194
|
550 |
msgid "Confirmation email subject"
|
551 |
msgstr ""
|
552 |
|
553 |
#. Translators: %s: The word "ticket" in lowercase.
|
554 |
+
#: src/Tickets/Commerce/Settings.php:319
|
555 |
#: src/admin-views/tribe-commerce-settings.php:195
|
556 |
msgctxt "tickets fields settings paypal email subject"
|
557 |
msgid ""
|
560 |
msgstr ""
|
561 |
|
562 |
#. Translators: %s: The word "tickets" in lowercase.
|
563 |
+
#: src/Tickets/Commerce/Settings.php:327
|
564 |
#: src/admin-views/tribe-commerce-settings.php:197
|
565 |
msgctxt "tickets fields settings paypal email subject"
|
566 |
msgid "You have %s!"
|
567 |
msgstr ""
|
568 |
|
569 |
+
#: src/Tickets/Commerce/Status/Action_Required.php:29
|
570 |
+
msgid "Action Required"
|
571 |
+
msgstr ""
|
572 |
+
|
573 |
+
#: src/Tickets/Commerce/Status/Approved.php:29
|
574 |
+
msgid "Approved"
|
575 |
+
msgstr ""
|
576 |
+
|
577 |
+
#: src/Tickets/Commerce/Status/Completed.php:27
|
578 |
+
#: src/Tribe/Commerce/PayPal/Orders/Sales.php:258
|
579 |
+
#: src/admin-views/tpp-orders.php:173
|
580 |
+
msgid "Completed"
|
581 |
+
msgstr ""
|
582 |
+
|
583 |
+
#: src/Tickets/Commerce/Status/Created.php:30
|
584 |
+
msgid "Created"
|
585 |
+
msgstr ""
|
586 |
+
|
587 |
+
#: src/Tickets/Commerce/Status/Denied.php:28
|
588 |
+
msgid "Denied"
|
589 |
+
msgstr ""
|
590 |
+
|
591 |
+
#: src/Tickets/Commerce/Status/Not_Completed.php:28
|
592 |
+
msgid "Not Completed"
|
593 |
+
msgstr ""
|
594 |
+
|
595 |
+
#: src/Tickets/Commerce/Status/Pending.php:33
|
596 |
+
msgid "Pending"
|
597 |
+
msgstr ""
|
598 |
+
|
599 |
+
#: src/Tickets/Commerce/Status/Pending.php:92
|
600 |
+
msgid "This order contained an invalid Ticket (ID: %1$d)"
|
601 |
+
msgstr ""
|
602 |
+
|
603 |
+
#: src/Tickets/Commerce/Status/Pending.php:107
|
604 |
+
msgid "This order contained a Ticket with an invalid Event (Event ID: %1$d)"
|
605 |
+
msgstr ""
|
606 |
+
|
607 |
+
#: src/Tickets/Commerce/Status/Pending.php:121
|
608 |
+
msgid "Cannot purchase zero of \"%1$s\""
|
609 |
+
msgstr ""
|
610 |
+
|
611 |
+
#: src/Tickets/Commerce/Status/Pending.php:138
|
612 |
+
msgid "Insufficient stock for \"%1$s\""
|
613 |
+
msgstr ""
|
614 |
+
|
615 |
+
#: src/Tickets/Commerce/Status/Refunded.php:27
|
616 |
+
msgid "Refunded"
|
617 |
+
msgstr ""
|
618 |
+
|
619 |
+
#: src/Tickets/Commerce/Status/Reversed.php:27
|
620 |
+
msgid "Reversed"
|
621 |
+
msgstr ""
|
622 |
+
|
623 |
+
#: src/Tickets/Commerce/Status/Undefined.php:28
|
624 |
+
msgid "Undefined"
|
625 |
+
msgstr ""
|
626 |
+
|
627 |
+
#: src/Tickets/Commerce/Status/Voided.php:29
|
628 |
+
msgid "Voided"
|
629 |
+
msgstr ""
|
630 |
+
|
631 |
+
#: src/Tickets/Commerce/Ticket.php:118 src/Tribe/Commerce/PayPal/Main.php:442
|
632 |
+
msgid "Tickets"
|
633 |
+
msgstr ""
|
634 |
+
|
635 |
+
#: src/Tickets/Commerce/Ticket.php:120
|
636 |
+
msgid "Tickets Commerce Tickets"
|
637 |
+
msgstr ""
|
638 |
+
|
639 |
+
#: src/Tickets/Commerce/Ticket.php:121
|
640 |
+
msgid "Tickets Commerce Ticket"
|
641 |
+
msgstr ""
|
642 |
+
|
643 |
+
#: src/Tickets/Commerce/Tickets_View.php:109
|
644 |
+
#: src/Tribe/Commerce/PayPal/Tickets_View.php:106
|
645 |
+
msgid "This ticket is no longer active."
|
646 |
+
msgstr ""
|
647 |
+
|
648 |
+
#: src/Tickets/Commerce/Tickets_View.php:140
|
649 |
+
#: src/Tribe/Commerce/PayPal/Tickets_View.php:137
|
650 |
+
msgid "unavailable"
|
651 |
+
msgstr ""
|
652 |
+
|
653 |
#: src/Tribe/Abstract_Attendance_Totals.php:65
|
654 |
msgctxt "total sold tooltip"
|
655 |
msgid "Includes all ticketed attendees regardless of order status."
|
660 |
msgid "Includes ticketed attendees with orders marked Completed."
|
661 |
msgstr ""
|
662 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
663 |
#: src/Tribe/Admin/Manager/Service_Provider.php:56
|
664 |
msgid "Insecure request."
|
665 |
msgstr ""
|
905 |
msgid "Unticketed"
|
906 |
msgstr ""
|
907 |
|
908 |
+
#: src/Tribe/Assets.php:196 src/views/tickets/tpp-success.php:97
|
909 |
msgid "%s header image"
|
910 |
msgstr ""
|
911 |
|
912 |
+
#: src/Tribe/Assets.php:197
|
913 |
msgid "Set as %s header"
|
914 |
msgstr ""
|
915 |
|
916 |
+
#: src/Tribe/Assets.php:253
|
917 |
msgid "Are you sure you want to delete this ticket? This cannot be undone."
|
918 |
msgstr ""
|
919 |
|
920 |
+
#: src/Tribe/Assets.php:259
|
921 |
msgid ""
|
922 |
"It looks like you have modified your shared capacity setting but have not "
|
923 |
"saved or updated the post."
|
924 |
msgstr ""
|
925 |
|
926 |
+
#: src/Tribe/Assets.php:279 src/Tribe/Metabox.php:575
|
927 |
msgid "Please enter in without thousand separators and currency symbols."
|
928 |
msgstr ""
|
929 |
|
930 |
+
#: src/Tribe/Assets.php:472
|
931 |
msgid ""
|
932 |
"There is unsaved attendee information. Are you sure you want to continue?"
|
933 |
msgstr ""
|
1045 |
msgid "Purchaser Email Address"
|
1046 |
msgstr ""
|
1047 |
|
1048 |
+
#: src/Tribe/Attendees.php:549 src/admin-views/tribe-commerce-settings.php:93
|
1049 |
+
#: src/admin-views/tribe-commerce-settings.php:105
|
1050 |
+
msgid "Yes"
|
1051 |
+
msgstr ""
|
1052 |
+
|
1053 |
#: src/Tribe/Attendees.php:660
|
1054 |
msgid "attendees"
|
1055 |
msgstr ""
|
1361 |
msgid "U.S. Dollar (USD)"
|
1362 |
msgstr ""
|
1363 |
|
1364 |
+
#. Translators: %1$s: the post/event title, %2$d: the post/event ID.
|
1365 |
+
#: src/Tribe/Commerce/Orders_Tabbed_View.php:36
|
1366 |
+
#: src/admin-views/attendees.php:34
|
1367 |
+
msgctxt "attendees report screen heading"
|
1368 |
+
msgid "Attendees for: %1$s [#%2$d]"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1369 |
msgstr ""
|
1370 |
|
1371 |
#: src/Tribe/Commerce/PayPal/Endpoints/Success_Template.php:99
|
1408 |
"%s(s) in an email."
|
1409 |
msgstr ""
|
1410 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1411 |
#: src/Tribe/Commerce/PayPal/Handler/IPN.php:143
|
1412 |
msgctxt "a PayPal configuration status"
|
1413 |
msgid "complete"
|
1437 |
msgid "Tribe Commerce"
|
1438 |
msgstr ""
|
1439 |
|
|
|
|
|
|
|
|
|
1440 |
#: src/Tribe/Commerce/PayPal/Main.php:444
|
1441 |
msgid "Tribe Commerce Tickets"
|
1442 |
msgstr ""
|
1445 |
msgid "Tribe Commerce Ticket"
|
1446 |
msgstr ""
|
1447 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1448 |
#: src/Tribe/Commerce/PayPal/Notices.php:43
|
1449 |
msgid "PayPal is using PDT data but you have not set the PDT identity token"
|
1450 |
msgstr ""
|
1472 |
msgid "Search Orders"
|
1473 |
msgstr ""
|
1474 |
|
|
|
|
|
|
|
|
|
|
|
1475 |
#: src/Tribe/Commerce/PayPal/Orders/Sales.php:262
|
1476 |
msgid "Not completed"
|
1477 |
msgstr ""
|
1562 |
msgid "Sell only available"
|
1563 |
msgstr ""
|
1564 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1565 |
#: src/Tribe/Editor/Attendee_Registration.php:127
|
1566 |
msgid "return to the content editor"
|
1567 |
msgstr ""
|
1723 |
msgid "Free"
|
1724 |
msgstr ""
|
1725 |
|
1726 |
+
#: src/Tribe/Main.php:144
|
1727 |
msgctxt "provider_plugin_name"
|
1728 |
msgid "Tickets"
|
1729 |
msgstr ""
|
1730 |
|
1731 |
+
#: src/Tribe/Main.php:430
|
1732 |
msgid ""
|
1733 |
"When The Events Calendar and Event Tickets are both activated, The Events "
|
1734 |
"Calendar must be running version %1$s or greater. Please %2$supdate now.%3$s"
|
1735 |
msgstr ""
|
1736 |
|
1737 |
+
#: src/Tribe/Main.php:493
|
1738 |
msgid ""
|
1739 |
"Sorry, Event Tickets requires WordPress %s or higher. Please upgrade your "
|
1740 |
"WordPress install."
|
1741 |
msgstr ""
|
1742 |
|
1743 |
+
#: src/Tribe/Main.php:497
|
1744 |
msgid ""
|
1745 |
"Sorry, Event Tickets requires PHP %s or higher. Talk to your Web host about "
|
1746 |
"moving you to a newer version of PHP."
|
1747 |
msgstr ""
|
1748 |
|
1749 |
+
#: src/Tribe/Main.php:621
|
1750 |
msgid "Support for Event Tickets"
|
1751 |
msgstr ""
|
1752 |
|
1753 |
+
#: src/Tribe/Main.php:623
|
1754 |
msgid "Settings overview"
|
1755 |
msgstr ""
|
1756 |
|
1757 |
+
#: src/Tribe/Main.php:624
|
1758 |
msgid "Features overview"
|
1759 |
msgstr ""
|
1760 |
|
1761 |
+
#: src/Tribe/Main.php:625
|
1762 |
msgid "Troubleshooting common problems"
|
1763 |
msgstr ""
|
1764 |
|
1765 |
+
#: src/Tribe/Main.php:626
|
1766 |
msgid "Customizing Event Tickets"
|
1767 |
msgstr ""
|
1768 |
|
1769 |
+
#: src/Tribe/Main.php:643
|
1770 |
msgid "New User Primer"
|
1771 |
msgstr ""
|
1772 |
|
1773 |
+
#: src/Tribe/Main.php:645
|
1774 |
msgctxt "help feature box section"
|
1775 |
msgid ""
|
1776 |
"We are committed to helping you sell %1$s for your event. Check out our "
|
1777 |
"handy %2$s to get started."
|
1778 |
msgstr ""
|
1779 |
|
1780 |
+
#: src/Tribe/Main.php:662
|
1781 |
msgid "open-source forum on WordPress.org"
|
1782 |
msgstr ""
|
1783 |
|
1784 |
+
#: src/Tribe/Main.php:663
|
1785 |
msgid ""
|
1786 |
"If you have tried the above steps and are still having trouble, you can post "
|
1787 |
"a new thread to our %s. Our support staff monitors these forums once a week "
|
1788 |
"and would be happy to assist you there."
|
1789 |
msgstr ""
|
1790 |
|
1791 |
+
#: src/Tribe/Main.php:665
|
1792 |
msgid "premium support on our website"
|
1793 |
msgstr ""
|
1794 |
|
1795 |
+
#: src/Tribe/Main.php:667
|
1796 |
msgid ""
|
1797 |
"Looking for more immediate support? We offer %1$s with the purchase of any "
|
1798 |
"of our premium plugins (like %2$s). Pick up a license and you can post there "
|
1799 |
"directly and expect a response within 24-48 hours during weekdays."
|
1800 |
msgstr ""
|
1801 |
|
1802 |
+
#: src/Tribe/Main.php:669 src/Tribe/Main.php:674
|
1803 |
msgid "post a thread"
|
1804 |
msgstr ""
|
1805 |
|
1806 |
+
#: src/Tribe/Main.php:670
|
1807 |
msgid ""
|
1808 |
"Already have Event Tickets Plus? You can %s in our premium support forums. "
|
1809 |
"Our support team monitors the forums and will respond to your thread within "
|
1810 |
"24-48 hours (during the week)."
|
1811 |
msgstr ""
|
1812 |
|
1813 |
+
#: src/Tribe/Main.php:675
|
1814 |
msgid ""
|
1815 |
"If you have a valid license for one of our paid plugins, you can %s in our "
|
1816 |
"premium support forums. Our support team monitors the forums and will "
|
1817 |
"respond to your thread within 24-48 hours (during the week)."
|
1818 |
msgstr ""
|
1819 |
|
1820 |
+
#: src/Tribe/Main.php:697
|
1821 |
msgid "Event Tickets - Legacy"
|
1822 |
msgstr ""
|
1823 |
|
1824 |
+
#: src/Tribe/Main.php:833
|
1825 |
msgid "Welcome to Event Tickets!"
|
1826 |
msgstr ""
|
1827 |
|
1828 |
+
#: src/Tribe/Main.php:986
|
1829 |
msgid "Buy"
|
1830 |
msgstr ""
|
1831 |
|
1832 |
+
#: src/Tribe/Main.php:1065
|
1833 |
msgid ""
|
1834 |
"When Event Tickets and Event Tickets Plus are both activated, Event Tickets "
|
1835 |
"Plus must be running version %1$s or greater. Please %2$smanually update now"
|
2432 |
msgid "List of meta for each ticket to be saved for Attendee Registration"
|
2433 |
msgstr ""
|
2434 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2435 |
#: src/Tribe/REST/V1/Endpoints/Single_Attendee.php:19
|
2436 |
msgid "Returns the data of the attendee with the specified post ID"
|
2437 |
msgstr ""
|
3083 |
msgstr ""
|
3084 |
|
3085 |
#: src/admin-views/attendees-email.php:36
|
3086 |
+
#: src/views/modal/registration-js.php:129
|
3087 |
msgid "or"
|
3088 |
msgstr ""
|
3089 |
|
3117 |
msgid "Search attendees"
|
3118 |
msgstr ""
|
3119 |
|
3120 |
+
#: src/admin-views/commerce/gateways/paypal/signup-link.php:25
|
3121 |
+
msgid "Connect Automatically with <i>PayPal</i>"
|
3122 |
+
msgstr ""
|
3123 |
+
|
3124 |
+
#: src/admin-views/commerce/metabox/capacity.php:16
|
3125 |
+
#: src/admin-views/editor/list-row.php:99
|
3126 |
+
#: src/admin-views/rsvp-metabox-capacity.php:10
|
3127 |
+
#: src/admin-views/tpp-metabox-capacity.php:16
|
3128 |
+
msgid "Capacity:"
|
3129 |
+
msgstr ""
|
3130 |
+
|
3131 |
+
#: src/admin-views/commerce/metabox/capacity.php:25
|
3132 |
+
#: src/admin-views/rsvp-metabox-capacity.php:19
|
3133 |
+
#: src/admin-views/tpp-metabox-capacity.php:25
|
3134 |
+
msgid "Leave blank for unlimited"
|
3135 |
+
msgstr ""
|
3136 |
+
|
3137 |
+
#: src/admin-views/commerce/metabox/sku.php:23
|
3138 |
+
#: src/admin-views/tpp-metabox-sku.php:20
|
3139 |
+
msgid "SKU:"
|
3140 |
+
msgstr ""
|
3141 |
+
|
3142 |
+
#: src/admin-views/commerce/metabox/sku.php:36
|
3143 |
+
#: src/admin-views/tpp-metabox-sku.php:33
|
3144 |
+
msgid "A unique identifying code for each %s type you're selling"
|
3145 |
+
msgstr ""
|
3146 |
+
|
3147 |
#: src/admin-views/editor/button-view-orders.php:46
|
3148 |
msgid "View Orders"
|
3149 |
msgstr ""
|
3229 |
msgid "%s Type:"
|
3230 |
msgstr ""
|
3231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
3232 |
#: src/admin-views/editor/list-row.php:104
|
3233 |
msgid "Available:"
|
3234 |
msgstr ""
|
3625 |
"statuses:"
|
3626 |
msgstr ""
|
3627 |
|
3628 |
+
#: src/admin-views/payments/tickets-commerce.php:25
|
3629 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/connect-with-paypal.php:62
|
3630 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:27
|
3631 |
+
msgid "Disconnect"
|
3632 |
+
msgstr ""
|
3633 |
+
|
3634 |
+
#: src/admin-views/payments/tickets-commerce.php:26
|
3635 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:28
|
3636 |
+
msgid "Refresh Access Token"
|
3637 |
+
msgstr ""
|
3638 |
+
|
3639 |
+
#: src/admin-views/payments/tickets-commerce.php:27
|
3640 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:29
|
3641 |
+
msgid "Refresh User Info"
|
3642 |
+
msgstr ""
|
3643 |
+
|
3644 |
+
#: src/admin-views/payments/tickets-commerce.php:28
|
3645 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:31
|
3646 |
+
msgid "PayPal Status: Connected"
|
3647 |
+
msgstr ""
|
3648 |
+
|
3649 |
+
#: src/admin-views/payments/tickets-commerce.php:29
|
3650 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:32
|
3651 |
+
msgid "Connected as: %1$s"
|
3652 |
+
msgstr ""
|
3653 |
+
|
3654 |
+
#: src/admin-views/payments/tickets-commerce.php:32
|
3655 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:35
|
3656 |
+
msgid "Accept online payments with PayPal!"
|
3657 |
+
msgstr ""
|
3658 |
+
|
3659 |
+
#: src/admin-views/payments/tickets-commerce.php:33
|
3660 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:37
|
3661 |
+
msgid ""
|
3662 |
+
"Start selling tickets to your events today with PayPal. Attendees can "
|
3663 |
+
"purchase tickets directly on your site using debt or credit cards with no "
|
3664 |
+
"additional fees."
|
3665 |
+
msgstr ""
|
3666 |
+
|
3667 |
+
#: src/admin-views/payments/tickets-commerce.php:41
|
3668 |
+
msgid "Credit and debit card payments"
|
3669 |
+
msgstr ""
|
3670 |
+
|
3671 |
+
#: src/admin-views/payments/tickets-commerce.php:42
|
3672 |
+
msgid "Easy, no API key connection"
|
3673 |
+
msgstr ""
|
3674 |
+
|
3675 |
+
#: src/admin-views/payments/tickets-commerce.php:43
|
3676 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:52
|
3677 |
+
msgid "Accept payments from around the world"
|
3678 |
+
msgstr ""
|
3679 |
+
|
3680 |
+
#: src/admin-views/payments/tickets-commerce.php:44
|
3681 |
+
msgid "Support 3D Secure Payments"
|
3682 |
+
msgstr ""
|
3683 |
+
|
3684 |
+
#: src/admin-views/payments/tickets-commerce.php:57
|
3685 |
+
msgid "Enable TicketsCommerce"
|
3686 |
+
msgstr ""
|
3687 |
+
|
3688 |
+
#: src/admin-views/payments/tickets-commerce.php:61
|
3689 |
+
msgid ""
|
3690 |
+
"TicketsCommerce allows you to accept payments for tickets with Event Tickets "
|
3691 |
+
"and Event Tickets Plus. Configure payments through PayPal, allowing users to "
|
3692 |
+
"pay with credit card or their PayPal account. Learn More about payment "
|
3693 |
+
"processing with TicketsCommerce."
|
3694 |
+
msgstr ""
|
3695 |
+
|
3696 |
#: src/admin-views/privacy.php:16
|
3697 |
msgid "Hello,"
|
3698 |
msgstr ""
|
3828 |
"to these external services. These services may be located abroad."
|
3829 |
msgstr ""
|
3830 |
|
|
|
|
|
|
|
|
|
|
|
3831 |
#: src/admin-views/rsvp-metabox-not-going.php:17
|
3832 |
msgid "Can't Go:"
|
3833 |
msgstr ""
|
3921 |
msgid "Connected for payments as"
|
3922 |
msgstr ""
|
3923 |
|
|
|
|
|
|
|
|
|
3924 |
#: src/admin-views/settings/tickets-commerce/paypal-commerce/connect-with-paypal.php:68
|
3925 |
msgid "APIs Connected:"
|
3926 |
msgstr ""
|
3927 |
|
|
|
|
|
|
|
|
|
3928 |
#: src/admin-views/settings/tickets-commerce/paypal-commerce/connect-with-paypal.php:71
|
3929 |
msgid "Refunds"
|
3930 |
msgstr ""
|
3931 |
|
3932 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:43
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3933 |
msgid "PayPal Logo Image"
|
3934 |
msgstr ""
|
3935 |
|
3936 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:46
|
3937 |
msgid "Credit and Debit Card payments"
|
3938 |
msgstr ""
|
3939 |
|
3940 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:49
|
3941 |
msgid "Easy no-API key connection"
|
3942 |
msgstr ""
|
3943 |
|
3944 |
+
#: src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php:55
|
|
|
|
|
|
|
|
|
3945 |
msgid "Supports 3D Secure payments"
|
3946 |
msgstr ""
|
3947 |
|
3958 |
msgid "Click to hide history"
|
3959 |
msgstr ""
|
3960 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3961 |
#: src/admin-views/tpp-orders.php:32
|
3962 |
msgid "Orders Report"
|
3963 |
msgstr ""
|
3990 |
"%3$s"
|
3991 |
msgstr ""
|
3992 |
|
3993 |
+
#: src/admin-views/tribe-commerce-settings.php:40
|
3994 |
+
msgid "these instructions"
|
3995 |
+
msgstr ""
|
3996 |
+
|
3997 |
#: src/admin-views/tribe-commerce-settings.php:41
|
3998 |
msgctxt "tickets fields settings PayPal setup"
|
3999 |
msgid ""
|
4002 |
"set up, follow %2$s"
|
4003 |
msgstr ""
|
4004 |
|
4005 |
+
#: src/admin-views/tribe-commerce-settings.php:45
|
4006 |
+
msgid ""
|
4007 |
+
"Have you entered this site's address in the Notification URL field in IPN "
|
4008 |
+
"Settings?"
|
4009 |
+
msgstr ""
|
4010 |
+
|
4011 |
+
#: src/admin-views/tribe-commerce-settings.php:47
|
4012 |
+
msgid "Your site address is: %s"
|
4013 |
+
msgstr ""
|
4014 |
+
|
4015 |
#: src/admin-views/tribe-commerce-settings.php:55
|
4016 |
msgid "Tribe Commerce"
|
4017 |
msgstr ""
|
4028 |
msgid "Configure PayPal:"
|
4029 |
msgstr ""
|
4030 |
|
4031 |
+
#: src/admin-views/tribe-commerce-settings.php:83
|
4032 |
+
msgid "PayPal email to receive payments:"
|
4033 |
+
msgstr ""
|
4034 |
+
|
4035 |
+
#: src/admin-views/tribe-commerce-settings.php:91
|
4036 |
+
msgid ""
|
4037 |
+
"Have you enabled instant payment notifications (IPN) in your PayPal "
|
4038 |
+
"account's Selling Tools?"
|
4039 |
+
msgstr ""
|
4040 |
+
|
4041 |
+
#: src/admin-views/tribe-commerce-settings.php:94
|
4042 |
+
#: src/admin-views/tribe-commerce-settings.php:106
|
4043 |
+
msgid "No"
|
4044 |
+
msgstr ""
|
4045 |
+
|
4046 |
+
#: src/admin-views/tribe-commerce-settings.php:117
|
4047 |
+
msgid "PayPal configuration status:"
|
4048 |
+
msgstr ""
|
4049 |
+
|
4050 |
+
#: src/admin-views/tribe-commerce-settings.php:120
|
4051 |
+
msgid ""
|
4052 |
+
"For help creating and configuring your account, call PayPal at "
|
4053 |
+
"1-844-720-4038 (USA)"
|
4054 |
+
msgstr ""
|
4055 |
+
|
4056 |
#: src/admin-views/tribe-commerce-settings.php:129
|
4057 |
msgid "PayPal Sandbox"
|
4058 |
msgstr ""
|
4092 |
"empty to use the default WordPress site email address."
|
4093 |
msgstr ""
|
4094 |
|
4095 |
+
#: src/admin-views/tribe-commerce-settings.php:209
|
4096 |
+
msgid ""
|
4097 |
+
"You can see and manage your IPN Notifications history from the IPN "
|
4098 |
+
"Notifications settings area (%s)."
|
4099 |
+
msgstr ""
|
4100 |
+
|
4101 |
+
#: src/admin-views/tribe-commerce-settings.php:219
|
4102 |
+
msgid "IPN Notify URL"
|
4103 |
+
msgstr ""
|
4104 |
+
|
4105 |
+
#: src/admin-views/tribe-commerce-settings.php:221
|
4106 |
+
msgid ""
|
4107 |
+
"Override the default IPN notify URL with this value. This value must be the "
|
4108 |
+
"same set in PayPal IPN Notifications settings area (%s)."
|
4109 |
+
msgstr ""
|
4110 |
+
|
4111 |
#. Translators: %1$s: dynamic "RSVP" text.
|
4112 |
#: src/admin-views/tribe-options-display.php:28
|
4113 |
msgctxt "title of settings section"
|
4676 |
msgid "One Moment..."
|
4677 |
msgstr ""
|
4678 |
|
4679 |
+
#: src/views/modal/registration-js.php:43 src/views/modal/registration.php:24
|
4680 |
msgid "Attendee Details"
|
4681 |
msgstr ""
|
4682 |
|
4683 |
+
#: src/views/modal/registration-js.php:53
|
4684 |
#: src/views/registration-js/content.php:100
|
4685 |
msgctxt ""
|
4686 |
"Note about missing required fields, %s is the html-wrapped number of tickets."
|
4687 |
msgid "You have %s ticket(s) with a field that requires information."
|
4688 |
msgstr ""
|
4689 |
|
4690 |
+
#: src/views/modal/registration-js.php:100
|
4691 |
#: src/views/registration-js/content.php:196
|
4692 |
msgctxt ""
|
4693 |
"Note that there are more tickets in the cart, %s is the html-wrapped number."
|
4696 |
"information."
|
4697 |
msgstr ""
|
4698 |
|
4699 |
+
#: src/views/modal/registration-js.php:119 src/views/modal/registration.php:36
|
4700 |
#: src/views/registration/content.php:111
|
4701 |
msgid "Save and Checkout"
|
4702 |
msgstr ""
|
4703 |
|
4704 |
+
#: src/views/modal/registration-js.php:127
|
4705 |
msgid "Save and View Cart"
|
4706 |
msgstr ""
|
4707 |
|
4708 |
+
#: src/views/modal/registration-js.php:135
|
4709 |
msgid "Checkout Now"
|
4710 |
msgstr ""
|
4711 |
|
4712 |
+
#: src/views/modal/registration.php:38 src/views/registration/content.php:113
|
4713 |
msgid "Save Attendee Info"
|
4714 |
msgstr ""
|
4715 |
|
5001 |
msgid "Buy now"
|
5002 |
msgstr ""
|
5003 |
|
5004 |
+
#. Translators: %1$s: Opening span for "Quantity:" string; %2$s: Closing span
|
5005 |
+
#. for "Quantity:" string; %3$s: Opening span for the quantity; %4$s: The
|
5006 |
+
#. quantity; %5$s: Closing span for the quantity.
|
5007 |
+
#: src/views/v2/commerce/checkout/cart/footer/quantity.php:29
|
5008 |
+
msgid "%1$sQuantity: %2$s%3$s%4$s%5$s"
|
5009 |
+
msgstr ""
|
5010 |
+
|
5011 |
+
#. Translators: %1$s: Opening span for "Total:" string; %2$s: Closing span for
|
5012 |
+
#. "Total:" string; %3$s: Opening span for the total value; %4$s: The total
|
5013 |
+
#. value; %5$s: Closing span for the total value.
|
5014 |
+
#: src/views/v2/commerce/checkout/cart/footer/total.php:29
|
5015 |
+
msgid "%1$sTotal: %2$s%3$s%4$s%5$s"
|
5016 |
+
msgstr ""
|
5017 |
+
|
5018 |
+
#: src/views/v2/commerce/checkout/cart/item/details/toggle.php:36
|
5019 |
+
msgid "Open the ticket description in checkout."
|
5020 |
+
msgstr ""
|
5021 |
+
|
5022 |
+
#: src/views/v2/commerce/checkout/cart/item/details/toggle.php:39
|
5023 |
+
msgctxt "Opens the ticket description"
|
5024 |
+
msgid "More info"
|
5025 |
+
msgstr ""
|
5026 |
+
|
5027 |
+
#: src/views/v2/commerce/checkout/cart/item/details/toggle.php:48
|
5028 |
+
msgid "Close the ticket description in checkout."
|
5029 |
+
msgstr ""
|
5030 |
+
|
5031 |
+
#: src/views/v2/commerce/checkout/cart/item/details/toggle.php:51
|
5032 |
+
msgctxt "Closes the ticket description"
|
5033 |
+
msgid "Less info"
|
5034 |
+
msgstr ""
|
5035 |
+
|
5036 |
+
#: src/views/v2/commerce/checkout/header.php:31
|
5037 |
+
msgid "Purchase Tickets"
|
5038 |
+
msgstr ""
|
5039 |
+
|
5040 |
+
#: src/views/v2/commerce/checkout/header.php:38
|
5041 |
+
msgid "modify attendees"
|
5042 |
+
msgstr ""
|
5043 |
+
|
5044 |
+
#: src/views/v2/commerce/checkout/header.php:42
|
5045 |
+
msgid "back to event"
|
5046 |
+
msgstr ""
|
5047 |
+
|
5048 |
+
#: src/views/v2/commerce/checkout/must-login/login.php:32
|
5049 |
+
msgid "Log in to complete your purchase"
|
5050 |
+
msgstr ""
|
5051 |
+
|
5052 |
+
#: src/views/v2/commerce/checkout/must-login/registration.php:37
|
5053 |
+
msgctxt "or <- create a new account"
|
5054 |
+
msgid "or "
|
5055 |
+
msgstr ""
|
5056 |
+
|
5057 |
+
#: src/views/v2/commerce/checkout/must-login/registration.php:39
|
5058 |
+
msgid "create a new account"
|
5059 |
+
msgstr ""
|
5060 |
+
|
5061 |
#: src/views/v2/rsvp/actions/full.php:22
|
5062 |
msgid "RSVP Closed"
|
5063 |
msgstr ""
|
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
=== Event Tickets ===
|
2 |
|
3 |
-
Contributors: theeventscalendar, brianjessee, camwynsp, paulkim,
|
4 |
Tags: tickets, registration, The Events Calendar, RSVP, ticket sales, attendee management
|
5 |
Requires at least: 4.9.18
|
6 |
Tested up to: 5.8.0
|
7 |
-
Stable tag: 5.1.
|
8 |
Requires PHP: 5.6
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
@@ -178,6 +178,13 @@ Check out our extensive [knowledgebase](https://evnt.is/18wm) for articles on us
|
|
178 |
|
179 |
== Changelog ==
|
180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
= [5.1.8] 2021-08-24 =
|
182 |
|
183 |
* Tweak - Add new event repository schema for finding all events with RSVPs or Tickets.
|
1 |
=== Event Tickets ===
|
2 |
|
3 |
+
Contributors: theeventscalendar, brianjessee, camwynsp, paulkim, aguseo, bordoni, borkweb, GeoffBel, geoffgraham, jentheo, leahkoerper, lucatume, neillmcshea, vicskf, zbtirrell, juanfra
|
4 |
Tags: tickets, registration, The Events Calendar, RSVP, ticket sales, attendee management
|
5 |
Requires at least: 4.9.18
|
6 |
Tested up to: 5.8.0
|
7 |
+
Stable tag: 5.1.9
|
8 |
Requires PHP: 5.6
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
178 |
|
179 |
== Changelog ==
|
180 |
|
181 |
+
= [5.1.9] 2021-08-31 =
|
182 |
+
|
183 |
+
* Fix - Fixed cart calculation inconsistency with WooCommerce when the "Number of decimals" setting was set to `0`. [ETP-324]
|
184 |
+
* Fix - Removed RSVP V2 preview templates and functionality. [ET-1162]
|
185 |
+
* Fix - Updated deprecated hook `block_categories` to use `block_categories_all`. [ET-1156]
|
186 |
+
* Language - 37 new strings added, 162 updated, 6 fuzzied, and 20 obsoleted
|
187 |
+
|
188 |
= [5.1.8] 2021-08-24 =
|
189 |
|
190 |
* Tweak - Add new event repository schema for finding all events with RSVPs or Tickets.
|
src/Tickets/Commerce.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Commerce
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets
|
11 |
+
*/
|
12 |
+
class Commerce {
|
13 |
+
/**
|
14 |
+
* Internal Commerce Provider Identifier for Tickets Commerce.
|
15 |
+
*
|
16 |
+
* @since 5.1.9
|
17 |
+
*
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
const PROVIDER = 'tickets-commerce';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Internal abbreviation for Ticket Commerce.
|
24 |
+
*
|
25 |
+
* @since 5.1.9
|
26 |
+
*
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
const ABBR = 'tc';
|
30 |
+
}
|
src/Tickets/Commerce/Assets.php
CHANGED
@@ -26,13 +26,50 @@ class Assets extends tad_DI52_ServiceProvider {
|
|
26 |
* @since 5.1.6
|
27 |
*/
|
28 |
public function register() {
|
|
|
|
|
|
|
29 |
tribe_asset(
|
30 |
-
|
31 |
'tribe-tickets-admin-commerce-settings',
|
32 |
'admin/tickets-commerce-settings.js',
|
33 |
[ 'jquery' ],
|
34 |
'admin_enqueue_scripts'
|
35 |
);
|
36 |
-
}
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
}
|
26 |
* @since 5.1.6
|
27 |
*/
|
28 |
public function register() {
|
29 |
+
/** @var Tribe__Tickets__Main $tickets_main */
|
30 |
+
$tickets_main = tribe( 'tickets.main' );
|
31 |
+
|
32 |
tribe_asset(
|
33 |
+
$tickets_main,
|
34 |
'tribe-tickets-admin-commerce-settings',
|
35 |
'admin/tickets-commerce-settings.js',
|
36 |
[ 'jquery' ],
|
37 |
'admin_enqueue_scripts'
|
38 |
);
|
|
|
39 |
|
40 |
+
// Tickets Commerce main styles.
|
41 |
+
tribe_asset(
|
42 |
+
$tickets_main,
|
43 |
+
'tribe-tickets-commerce-style',
|
44 |
+
'tickets-commerce.css',
|
45 |
+
[
|
46 |
+
'tribe-common-skeleton-style',
|
47 |
+
'tribe-common-full-style',
|
48 |
+
],
|
49 |
+
null,
|
50 |
+
[
|
51 |
+
'groups' => [
|
52 |
+
'tribe-tickets-commerce',
|
53 |
+
'tribe-tickets-commerce-checkout',
|
54 |
+
],
|
55 |
+
]
|
56 |
+
);
|
57 |
+
|
58 |
+
tribe_asset(
|
59 |
+
$tickets_main,
|
60 |
+
'tribe-tickets-commerce-js',
|
61 |
+
'v2/tickets-commerce.js',
|
62 |
+
[
|
63 |
+
'jquery',
|
64 |
+
'tribe-common',
|
65 |
+
],
|
66 |
+
null,
|
67 |
+
[
|
68 |
+
'groups' => [
|
69 |
+
'tribe-tickets-commerce',
|
70 |
+
'tribe-tickets-commerce-checkout',
|
71 |
+
],
|
72 |
+
]
|
73 |
+
);
|
74 |
+
}
|
75 |
}
|
src/Tickets/Commerce/Attendee.php
ADDED
@@ -0,0 +1,471 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Attendee
|
9 |
+
*
|
10 |
+
* @since 5.1.9
|
11 |
+
*
|
12 |
+
* @package TEC\Tickets\Commerce
|
13 |
+
*/
|
14 |
+
class Attendee {
|
15 |
+
/**
|
16 |
+
* Tickets Commerce Attendee Post Type slug.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
const POSTTYPE = 'tec_tc_attendee';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Which meta holds the Relation ship between an attendee and which user it's registered to.
|
26 |
+
*
|
27 |
+
* @since 5.1.9
|
28 |
+
*
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public static $user_relation_meta_key = '_tribe_tickets_attendee_user_id';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Which meta holds the Relation ship between an attendee and which event it's registered to.
|
35 |
+
*
|
36 |
+
* @since 5.1.9
|
37 |
+
*
|
38 |
+
* @var string
|
39 |
+
*/
|
40 |
+
public static $event_relation_meta_key = '_tec_tickets_commerce_event';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Which meta holds the Relation ship between an attendee and which ticket it was created from.
|
44 |
+
*
|
45 |
+
* @since 5.1.9
|
46 |
+
*
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
public static $ticket_relation_meta_key = '_tec_tickets_commerce_ticket';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Which meta holds the Relation ship between an attendee and which order it belongs to.
|
53 |
+
*
|
54 |
+
* @since 5.1.9
|
55 |
+
*
|
56 |
+
* @var string
|
57 |
+
*/
|
58 |
+
public static $order_relation_meta_key = '_tec_tickets_commerce_order';
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Which meta holds the purchaser name for an attendee.
|
62 |
+
*
|
63 |
+
* @since 5.1.9
|
64 |
+
*
|
65 |
+
* @var string
|
66 |
+
*/
|
67 |
+
public static $purchaser_name_meta_key = '_tec_tickets_commerce_purchaser_name';
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Which meta holds the purchaser email for an attendee.
|
71 |
+
*
|
72 |
+
* @since 5.1.9
|
73 |
+
*
|
74 |
+
* @var string
|
75 |
+
*/
|
76 |
+
public static $purchaser_email_meta_key = '_tec_tickets_commerce_purchaser_email';
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Which meta holds the security code for an attendee.
|
80 |
+
*
|
81 |
+
* @since 5.1.9
|
82 |
+
*
|
83 |
+
* @var string
|
84 |
+
*/
|
85 |
+
public static $security_code_meta_key = '_tec_tickets_commerce_security_code';
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Which meta holds the status value for an attendee.
|
89 |
+
*
|
90 |
+
* @since 5.1.9
|
91 |
+
*
|
92 |
+
* @var string
|
93 |
+
*/
|
94 |
+
public static $status_meta_key = '_tec_tickets_commerce_status';
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Which meta holds the optout value for an attendee.
|
98 |
+
*
|
99 |
+
* @since 5.1.9
|
100 |
+
*
|
101 |
+
* @var string
|
102 |
+
*/
|
103 |
+
public static $optout_meta_key = '_tec_tickets_commerce_optout';
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Which meta holds the checked in status for an attendee.
|
107 |
+
*
|
108 |
+
* @since 5.1.9
|
109 |
+
*
|
110 |
+
* @var string
|
111 |
+
*/
|
112 |
+
public static $checked_in_meta_key = '_tec_tickets_commerce_checked_in';
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Which meta holds the checked in status for an attendee.
|
116 |
+
*
|
117 |
+
* @since 5.1.9
|
118 |
+
*
|
119 |
+
* @var string
|
120 |
+
*/
|
121 |
+
public static $deleted_ticket_meta_key = '_tribe_deleted_product_name';
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Indicates if a ticket for this attendee was sent out via email.
|
125 |
+
*
|
126 |
+
* @since 5.1.9
|
127 |
+
*
|
128 |
+
* @var string
|
129 |
+
*/
|
130 |
+
public static $ticket_sent_meta_key = '_tec_tickets_commerce_attendee_ticket_sent';
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Meta key holding an indication if this attendee was subscribed.
|
134 |
+
*
|
135 |
+
* @since 5.1.9
|
136 |
+
*
|
137 |
+
* @var string
|
138 |
+
*/
|
139 |
+
public static $subscribed_meta_key = '_tribe_tickets_subscribed';
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Meta key holding the first name for the attendee. (not purchaser)
|
143 |
+
*
|
144 |
+
* @since 5.1.9
|
145 |
+
*
|
146 |
+
* @var string
|
147 |
+
*/
|
148 |
+
public static $first_name_meta_key = '_tec_tickets_commerce_first_name';
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Meta key holding the last name for the attendee. (not purchaser)
|
152 |
+
*
|
153 |
+
* @since 5.1.9
|
154 |
+
*
|
155 |
+
* @var string
|
156 |
+
*/
|
157 |
+
public static $last_name_meta_key = '_tec_tickets_commerce_last_name';
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Meta key holding the email for the attendee. (not purchaser)
|
161 |
+
*
|
162 |
+
* @since 5.1.9
|
163 |
+
*
|
164 |
+
* @var string
|
165 |
+
*/
|
166 |
+
public static $email_meta_key = '_tec_tickets_commerce_email';
|
167 |
+
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Register this Class post type into WP.
|
171 |
+
*
|
172 |
+
* @since 5.1.9
|
173 |
+
*/
|
174 |
+
public function register_post_type() {
|
175 |
+
$post_type_args = [
|
176 |
+
'label' => __( 'Attendees', 'event-tickets' ),
|
177 |
+
'public' => false,
|
178 |
+
'show_ui' => false,
|
179 |
+
'show_in_menu' => false,
|
180 |
+
'query_var' => false,
|
181 |
+
'rewrite' => false,
|
182 |
+
'capability_type' => 'post',
|
183 |
+
'has_archive' => false,
|
184 |
+
'hierarchical' => false,
|
185 |
+
];
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Filter the arguments that craft the attendee post type.
|
189 |
+
*
|
190 |
+
* @see register_post_type
|
191 |
+
*
|
192 |
+
* @since 5.1.9
|
193 |
+
*
|
194 |
+
* @param array $post_type_args Post type arguments, passed to register_post_type()
|
195 |
+
*/
|
196 |
+
$post_type_args = apply_filters( 'tec_tickets_commerce_attendee_post_type_args', $post_type_args );
|
197 |
+
|
198 |
+
register_post_type( static::POSTTYPE, $post_type_args );
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* If the post that was moved to the trash was an PayPal Ticket attendee post type, redirect to
|
203 |
+
* the Attendees Report rather than the PayPal Ticket attendees post list (because that's kind of
|
204 |
+
* confusing)
|
205 |
+
*
|
206 |
+
* @since 5.1.9
|
207 |
+
*
|
208 |
+
* @param int $post_id WP_Post ID
|
209 |
+
*/
|
210 |
+
public function maybe_redirect_to_attendees_report( $post_id ) {
|
211 |
+
$post = get_post( $post_id );
|
212 |
+
|
213 |
+
if ( static::POSTTYPE !== $post->post_type ) {
|
214 |
+
return;
|
215 |
+
}
|
216 |
+
|
217 |
+
$args = array(
|
218 |
+
'post_type' => 'tribe_events',
|
219 |
+
'page' => \Tribe__Tickets__Tickets_Handler::$attendees_slug,
|
220 |
+
'event_id' => get_post_meta( $post_id, static::$event_relation_meta_key, true ),
|
221 |
+
);
|
222 |
+
|
223 |
+
$url = add_query_arg( $args, admin_url( 'edit.php' ) );
|
224 |
+
$url = esc_url_raw( $url );
|
225 |
+
|
226 |
+
wp_redirect( $url );
|
227 |
+
tribe_exit();
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Update the Ticket Commerce values for this user.
|
232 |
+
*
|
233 |
+
* Note that, within this method, $order_id refers to the attendee or ticket ID
|
234 |
+
* (it does not refer to an "order" in the sense of a transaction that may include
|
235 |
+
* multiple tickets, as is the case in some other methods for instance).
|
236 |
+
*
|
237 |
+
* @todo Adjust to the Ticket Commerce data.
|
238 |
+
*
|
239 |
+
* @since 5.1.9
|
240 |
+
*
|
241 |
+
* @param array $attendee_data Information that we are trying to save.
|
242 |
+
* @param int $attendee_id The attendee ID.
|
243 |
+
* @param int $post_id The event/post ID.
|
244 |
+
*/
|
245 |
+
public function update_attendee_data( $attendee_data, $attendee_id, $post_id ) {
|
246 |
+
// Bail if the user is not logged in.
|
247 |
+
if ( ! is_user_logged_in() ) {
|
248 |
+
return;
|
249 |
+
}
|
250 |
+
|
251 |
+
$user_id = get_current_user_id();
|
252 |
+
|
253 |
+
$ticket_attendees = $this->tickets_view->get_post_ticket_attendees( $post_id, $user_id );
|
254 |
+
$ticket_attendee_ids = wp_list_pluck( $ticket_attendees, 'attendee_id' );
|
255 |
+
|
256 |
+
// This makes sure we don't save attendees for attendees that are not from this current user and event.
|
257 |
+
if ( ! in_array( $attendee_id, $ticket_attendee_ids, true ) ) {
|
258 |
+
return;
|
259 |
+
}
|
260 |
+
|
261 |
+
$attendee_data_to_save = [];
|
262 |
+
|
263 |
+
// Only update full name if set.
|
264 |
+
if ( ! empty( $attendee_data['full_name'] ) ) {
|
265 |
+
$attendee_data_to_save['full_name'] = sanitize_text_field( $attendee_data['full_name'] );
|
266 |
+
}
|
267 |
+
|
268 |
+
// Only update email if set.
|
269 |
+
if ( ! empty( $attendee_data['email'] ) ) {
|
270 |
+
$attendee_data['email'] = sanitize_email( $attendee_data['email'] );
|
271 |
+
|
272 |
+
// Only update email if valid.
|
273 |
+
if ( is_email( $attendee_data['email'] ) ) {
|
274 |
+
$attendee_data_to_save['email'] = $attendee_data['email'];
|
275 |
+
}
|
276 |
+
}
|
277 |
+
|
278 |
+
// Only update optout if set.
|
279 |
+
if ( isset( $attendee_data['optout'] ) ) {
|
280 |
+
$attendee_data_to_save['optout'] = (int) tribe_is_truthy( $attendee_data['optout'] );
|
281 |
+
}
|
282 |
+
|
283 |
+
// Only update if there's data to set.
|
284 |
+
if ( empty( $attendee_data_to_save ) ) {
|
285 |
+
return;
|
286 |
+
}
|
287 |
+
|
288 |
+
tribe( Module::class )->update_attendee( $attendee_id, $attendee_data_to_save );
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Triggers the sending of ticket emails after PayPal Ticket information is updated.
|
293 |
+
*
|
294 |
+
* This is useful if a user initially suggests they will not be attending
|
295 |
+
* an event (in which case we do not send tickets out) but where they
|
296 |
+
* incrementally amend the status of one or more of those tickets to
|
297 |
+
* attending, at which point we should send tickets out for any of those
|
298 |
+
* newly attending persons.
|
299 |
+
*
|
300 |
+
* @since 5.1.9
|
301 |
+
*
|
302 |
+
* @param int $event_id
|
303 |
+
*/
|
304 |
+
public function maybe_send_tickets_after_status_change( $event_id ) {
|
305 |
+
$transaction_ids = array();
|
306 |
+
|
307 |
+
foreach ( tribe( Module::class )->get_event_attendees( $event_id ) as $attendee ) {
|
308 |
+
$transaction = get_post_meta( $attendee['attendee_id'], static::$order_relation_meta_key, true );
|
309 |
+
|
310 |
+
if ( ! empty( $transaction ) ) {
|
311 |
+
$transaction_ids[ $transaction ] = $transaction;
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
foreach ( $transaction_ids as $transaction ) {
|
316 |
+
// This method takes care of intelligently sending out emails only when
|
317 |
+
// required, for attendees that have not yet received their tickets
|
318 |
+
tribe( Module::class )->send_tickets_email( $transaction, $event_id );
|
319 |
+
}
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Add our class to the list of classes for the attendee registration form
|
324 |
+
*
|
325 |
+
* @since TBd
|
326 |
+
*
|
327 |
+
* @param array $classes existing array of classes
|
328 |
+
*
|
329 |
+
* @return array $classes with our class added
|
330 |
+
*/
|
331 |
+
public function registration_form_class( $classes ) {
|
332 |
+
$classes[ static::POSTTYPE ] = \TEC\Tickets\Commerce::ABBR;
|
333 |
+
|
334 |
+
return $classes;
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Filter the provider object to return this class if tickets are for this provider.
|
339 |
+
*
|
340 |
+
* @since 5.1.9
|
341 |
+
*
|
342 |
+
* @param object $provider_obj
|
343 |
+
* @param string $provider
|
344 |
+
*
|
345 |
+
* @return object
|
346 |
+
*/
|
347 |
+
public function registration_cart_provider( $provider_obj, $provider ) {
|
348 |
+
$options = [
|
349 |
+
\TEC\Tickets\Commerce::ABBR,
|
350 |
+
static::POSTTYPE,
|
351 |
+
\TEC\Tickets\Commerce::PROVIDER,
|
352 |
+
static::class,
|
353 |
+
];
|
354 |
+
|
355 |
+
if ( in_array( $provider, $options, true ) ) {
|
356 |
+
return tribe( Module::class );
|
357 |
+
}
|
358 |
+
|
359 |
+
return $provider_obj;
|
360 |
+
}
|
361 |
+
|
362 |
+
/**
|
363 |
+
* Whether a specific attendee is valid toward inventory decrease or not.
|
364 |
+
*
|
365 |
+
* By default only attendees generated as part of a Completed order will count toward
|
366 |
+
* an inventory decrease but, if the option to reserve stock for Pending Orders is activated,
|
367 |
+
* then those attendees generated as part of a Pending Order will, for a limited time after the
|
368 |
+
* order creation, cause the inventory to be decreased.
|
369 |
+
*
|
370 |
+
* @todo TribeCommerceLegacy: Move this method a Flag action.
|
371 |
+
*
|
372 |
+
* @since 5.1.9
|
373 |
+
*
|
374 |
+
* @param array $attendee
|
375 |
+
*
|
376 |
+
* @return bool
|
377 |
+
*/
|
378 |
+
public function decreases_inventory( $attendee ) {
|
379 |
+
$order_status = \Tribe__Utils__Array::get( $attendee, 'order_status', 'undefined' );
|
380 |
+
$order_id = \Tribe__Utils__Array::get( $attendee, 'order_id', false );
|
381 |
+
$attendee_id = \Tribe__Utils__Array::get( $attendee, 'attendee_id', false );
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Whether the pending Order stock reserve logic should be ignored completely or not.
|
385 |
+
*
|
386 |
+
* If set to `true` then the behaviour chosen in the Settings will apply, if `false`
|
387 |
+
* only Completed tickets will count to decrease the inventory. This is useful when
|
388 |
+
*
|
389 |
+
* @todo TribeCommerceLegacy: Move this method a Flag action.
|
390 |
+
*
|
391 |
+
* @since 5.1.9
|
392 |
+
*
|
393 |
+
* @param bool $ignore_pending
|
394 |
+
* @param array $attendee An array of data defining the current Attendee
|
395 |
+
*/
|
396 |
+
$ignore_pending = apply_filters( 'tec_tickets_commerce_pending_stock_ignore', false );
|
397 |
+
|
398 |
+
$purchase_time = false;
|
399 |
+
$order = false;
|
400 |
+
|
401 |
+
if (
|
402 |
+
'on-pending' === tribe_get_option( 'ticket-paypal-stock-handling', 'on-complete' )
|
403 |
+
&& ! $ignore_pending
|
404 |
+
&& Order_Statuses::$pending === $order_status
|
405 |
+
&& false !== $order_id
|
406 |
+
) {
|
407 |
+
$purchase_time = \Tribe__Utils__Array::get( $attendee, 'purchase_time', false );
|
408 |
+
|
409 |
+
$order = \Tribe__Tickets__Commerce__PayPal__Order::from_attendee_id(
|
410 |
+
$attendee_id,
|
411 |
+
[
|
412 |
+
// Get no meta fields.
|
413 |
+
]
|
414 |
+
);
|
415 |
+
|
416 |
+
if ( false !== $order ) {
|
417 |
+
$purchase_time = $order->get_creation_date();
|
418 |
+
}
|
419 |
+
}
|
420 |
+
|
421 |
+
if ( $purchase_time ) {
|
422 |
+
$date = \Tribe__Date_Utils::build_date_object( $purchase_time );
|
423 |
+
|
424 |
+
$date->setTimezone( new \DateTimeZone( 'UTC' ) );
|
425 |
+
|
426 |
+
$order_creation_timestamp = $date->getTimestamp();
|
427 |
+
|
428 |
+
/**
|
429 |
+
* Filters the amount of time a part of the stock will be reserved by a pending Order.
|
430 |
+
*
|
431 |
+
* The time applies from the Order creation time.
|
432 |
+
* In the unlikely scenario that an Order goes from Completed to Pending then, if the
|
433 |
+
* reservation time allows it, a part of the stock will be reserved for it.
|
434 |
+
*
|
435 |
+
* @since 4.7
|
436 |
+
*
|
437 |
+
* @param int $pending_stock_reservation_time The amount of seconds, from the Order creation time,
|
438 |
+
* part of the stock will be reserved for the Order;
|
439 |
+
* defaults to 30 minutes.
|
440 |
+
* @param array $attendee An array of data defining the current Attendee
|
441 |
+
* @param \Tribe__Tickets__Commerce__PayPal__Order $order The object representing the Order that generated
|
442 |
+
* the Attendee
|
443 |
+
*/
|
444 |
+
$pending_stock_reservation_time = (int) apply_filters( 'tec_tickets_commerce_pending_stock_reserve_time', 30 * 60, $attendee, $order );
|
445 |
+
|
446 |
+
return time() <= ( $order_creation_timestamp + $pending_stock_reservation_time );
|
447 |
+
}
|
448 |
+
|
449 |
+
return Completed::SLUG === $order_status;
|
450 |
+
}
|
451 |
+
|
452 |
+
/**
|
453 |
+
* Get attendee data for attendee.
|
454 |
+
*
|
455 |
+
* @since 5.1.9
|
456 |
+
*/
|
457 |
+
public function get_attendee() {
|
458 |
+
/**
|
459 |
+
* @todo Determine if this meta piece can be moved into the ET+ codebase.
|
460 |
+
*/
|
461 |
+
$meta = '';
|
462 |
+
if ( class_exists( 'Tribe__Tickets_Plus__Meta', false ) ) {
|
463 |
+
$meta = get_post_meta( $attendee->ID, \Tribe__Tickets_Plus__Meta::META_KEY, true );
|
464 |
+
|
465 |
+
// Process Meta to include value, slug, and label
|
466 |
+
if ( ! empty( $meta ) ) {
|
467 |
+
$meta = tribe( Module::class )->process_attendee_meta( $attendee['product_id'], $meta );
|
468 |
+
}
|
469 |
+
}
|
470 |
+
}
|
471 |
+
}
|
src/Tickets/Commerce/Cart.php
ADDED
@@ -0,0 +1,660 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce;
|
6 |
+
use TEC\Tickets\Commerce\Utils\Price;
|
7 |
+
use \Tribe__Utils__Array as Arr;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class Cart
|
11 |
+
*
|
12 |
+
* @since 5.1.9
|
13 |
+
*
|
14 |
+
* @package TEC\Tickets\Commerce
|
15 |
+
*/
|
16 |
+
class Cart {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Which URL param we use to identify a given page as the cart.
|
20 |
+
* Keep in mind this is not the only way, please use `is_current_page()` to determine that.
|
21 |
+
*
|
22 |
+
* @since 5.1.9
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
public static $url_query_arg = 'tec-tc-cart';
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Which URL param we use to tell the checkout page to set a cookie, since you cannot set a cookie on a 302
|
30 |
+
* redirect.
|
31 |
+
*
|
32 |
+
* @since 5.1.9
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
public static $cookie_query_arg = 'tec-tc-cookie';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Redirect mode string, which will be used to determine which kind of cart the repository might be.
|
40 |
+
*
|
41 |
+
* @since 5.1.9
|
42 |
+
*
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
const REDIRECT_MODE = 'redirect';
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Which URL param we use to identify a given page as the cart.
|
49 |
+
* Keep in mind this is not the only way, please use `is_current_page()` to determine that.
|
50 |
+
*
|
51 |
+
* @since 5.1.9
|
52 |
+
*
|
53 |
+
* @var string[]
|
54 |
+
*/
|
55 |
+
protected $available_modes = [ self::REDIRECT_MODE ];
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Which cookie we will store the cart hash.
|
59 |
+
*
|
60 |
+
* @since 5.1.9
|
61 |
+
*
|
62 |
+
* @var string
|
63 |
+
*/
|
64 |
+
public static $cart_hash_cookie_name = 'tec-tickets-commerce-cart';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Which invoice number we are using here.
|
68 |
+
*
|
69 |
+
* @since 5.1.9
|
70 |
+
*
|
71 |
+
* @var string
|
72 |
+
*/
|
73 |
+
protected $cart_hash;
|
74 |
+
|
75 |
+
/**
|
76 |
+
* From the current active cart repository we fetch it's mode.
|
77 |
+
*
|
78 |
+
* @since 5.1.9
|
79 |
+
*
|
80 |
+
* @return string
|
81 |
+
*/
|
82 |
+
public function get_mode() {
|
83 |
+
return $this->get_repository()->get_mode();
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Gets the list of available modes we can use for the cart.
|
88 |
+
*
|
89 |
+
* @since 5.1.9
|
90 |
+
*
|
91 |
+
* @return string[]
|
92 |
+
*/
|
93 |
+
public function get_available_modes() {
|
94 |
+
return $this->available_modes;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* If a given string is a valid and available mode.
|
99 |
+
*
|
100 |
+
* @since 5.1.9
|
101 |
+
*
|
102 |
+
* @param string $mode Which mode we are testing.
|
103 |
+
*
|
104 |
+
* @return bool
|
105 |
+
*/
|
106 |
+
public function is_available_mode( $mode ) {
|
107 |
+
return in_array( $mode, $this->get_available_modes(), true );
|
108 |
+
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* If the current page is the cart page or not.
|
113 |
+
*
|
114 |
+
* @since 5.1.9
|
115 |
+
*
|
116 |
+
* @return bool
|
117 |
+
*/
|
118 |
+
public function is_current_page() {
|
119 |
+
$cart_mode = tribe_get_request_var( static::$url_query_arg, false );
|
120 |
+
|
121 |
+
if ( ! $this->is_available_mode( $cart_mode ) ) {
|
122 |
+
return false;
|
123 |
+
}
|
124 |
+
|
125 |
+
// When the current cart doesn't use this mode we fail the page check.
|
126 |
+
if ( $this->get_mode() !== $cart_mode ) {
|
127 |
+
return false;
|
128 |
+
}
|
129 |
+
|
130 |
+
return true;
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Returns the name of the transient used by the cart.
|
135 |
+
*
|
136 |
+
* @since 5.1.9
|
137 |
+
*
|
138 |
+
* @param string $id
|
139 |
+
*
|
140 |
+
* @return string
|
141 |
+
*/
|
142 |
+
public static function get_transient_name( $id ) {
|
143 |
+
return Commerce::ABBR . '-cart-' . md5( $id );
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Returns the name of the transient used by the cart for invoice numbers
|
148 |
+
*
|
149 |
+
* @since 5.1.9
|
150 |
+
*
|
151 |
+
* @param string $id
|
152 |
+
*
|
153 |
+
* @return string
|
154 |
+
*/
|
155 |
+
public static function get_invoice_transient_name( $id ) {
|
156 |
+
return Commerce::ABBR . '-invoice-' . md5( $id );
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Determine the Current cart Transient Key based on invoice number.
|
161 |
+
*
|
162 |
+
* @since 5.1.9
|
163 |
+
*
|
164 |
+
* @return string
|
165 |
+
*/
|
166 |
+
public function get_current_cart_transient() {
|
167 |
+
$cart_hash = $this->get_cart_hash();
|
168 |
+
|
169 |
+
return static::get_transient_name( $cart_hash );
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Determine the Current cart URL.
|
174 |
+
*
|
175 |
+
* @since 5.1.9
|
176 |
+
*
|
177 |
+
* @return string
|
178 |
+
*/
|
179 |
+
public function get_url() {
|
180 |
+
$url = home_url( '/' );
|
181 |
+
|
182 |
+
$url = add_query_arg( [ static::$url_query_arg => $this->get_mode() ], $url );
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Allows modifications to the cart url for Tickets Commerce.
|
186 |
+
*
|
187 |
+
* @since 5.1.9
|
188 |
+
*
|
189 |
+
* @param string $url URL for the cart.
|
190 |
+
*/
|
191 |
+
return (string) apply_filters( 'tec_tickets_commerce_cart_url', $url );
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Reads the cart hash from the cookies.
|
196 |
+
*
|
197 |
+
* @since 5.1.9
|
198 |
+
*
|
199 |
+
* @return string|bool The cart hash or `false` if not found.
|
200 |
+
*/
|
201 |
+
public function get_cart_hash( $generate = false ) {
|
202 |
+
$cart_hash_length = 12;
|
203 |
+
|
204 |
+
$cart_hash = $this->cart_hash;
|
205 |
+
|
206 |
+
if (
|
207 |
+
! empty( $_COOKIE[ static::$cart_hash_cookie_name ] )
|
208 |
+
&& strlen( $_COOKIE[ static::$cart_hash_cookie_name ] ) === $cart_hash_length
|
209 |
+
) {
|
210 |
+
$cart_hash = $_COOKIE[ static::$cart_hash_cookie_name ];
|
211 |
+
|
212 |
+
$cart_hash_transient = get_transient( static::get_transient_name( $cart_hash ) );
|
213 |
+
|
214 |
+
if ( empty( $cart_hash_transient ) ) {
|
215 |
+
$cart_hash = false;
|
216 |
+
}
|
217 |
+
}
|
218 |
+
|
219 |
+
if ( empty( $cart_hash ) && $generate ) {
|
220 |
+
$cart_hash = wp_generate_password( $cart_hash_length, false );
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Filters the cart hash used for the Cart.
|
225 |
+
*
|
226 |
+
* @since 5.1.9
|
227 |
+
*
|
228 |
+
* @param string $cart_hash Invoice number.
|
229 |
+
*/
|
230 |
+
$this->cart_hash = apply_filters( 'tec_tickets_commerce_cart_hash', $cart_hash );
|
231 |
+
|
232 |
+
return $this->cart_hash;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Clear the cart.
|
237 |
+
*
|
238 |
+
* @since 5.1.9
|
239 |
+
*
|
240 |
+
* @return false
|
241 |
+
*/
|
242 |
+
public function clear_cart() {
|
243 |
+
$is_empty = empty( $_COOKIE[ static::$cart_hash_cookie_name ] );
|
244 |
+
$this->set_cart_hash_cookie( null );
|
245 |
+
|
246 |
+
if ( $is_empty ) {
|
247 |
+
return false;
|
248 |
+
}
|
249 |
+
|
250 |
+
$cart_hash = $_COOKIE[ static::$cart_hash_cookie_name ];
|
251 |
+
unset( $_COOKIE[ static::$cart_hash_cookie_name ] );
|
252 |
+
|
253 |
+
return delete_transient( static::get_transient_name( $cart_hash ) );
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Sets the cart hash cookie or resets the cookie.
|
258 |
+
*
|
259 |
+
* @since 5.1.9
|
260 |
+
*
|
261 |
+
* @parem string $value Value used for the cookie or empty to purge the cookie.
|
262 |
+
*
|
263 |
+
* @return boolean
|
264 |
+
*/
|
265 |
+
public function set_cart_hash_cookie( $value = '' ) {
|
266 |
+
if ( headers_sent() ) {
|
267 |
+
return false;
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Filters the life span of the Cart Cookie.
|
272 |
+
*
|
273 |
+
* @since 5.1.9
|
274 |
+
*
|
275 |
+
* @param int $expires The expiry time, as passed to setcookie().
|
276 |
+
*/
|
277 |
+
$expire = apply_filters( 'tec_tickets_commerce_cart_expiration', time() + 1 * HOUR_IN_SECONDS );
|
278 |
+
$referer = wp_get_referer();
|
279 |
+
|
280 |
+
if ( $referer ) {
|
281 |
+
$secure = ( 'https' === parse_url( $referer, PHP_URL_SCHEME ) );
|
282 |
+
} else {
|
283 |
+
$secure = false;
|
284 |
+
}
|
285 |
+
|
286 |
+
// When null means we are deleting.
|
287 |
+
if ( null === $value ) {
|
288 |
+
$expire = 1;
|
289 |
+
}
|
290 |
+
|
291 |
+
$is_cookie_set = setcookie( static::$cart_hash_cookie_name, $value, $expire, COOKIEPATH ?: '/', COOKIE_DOMAIN, $secure );
|
292 |
+
|
293 |
+
// Overwrite local variable so we can use it right away.
|
294 |
+
$_COOKIE[ static::$cart_hash_cookie_name ] = $value;
|
295 |
+
|
296 |
+
return $is_cookie_set;
|
297 |
+
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Gets the current instance of cart handling that we are using.
|
301 |
+
*
|
302 |
+
* @since 5.1.9
|
303 |
+
*
|
304 |
+
* @return Commerce\Cart\Cart_Interface
|
305 |
+
*/
|
306 |
+
public function get_repository() {
|
307 |
+
$default_cart = tribe( Cart\Unmanaged_Cart::class );
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Filters the cart repository, by default we use Unmanaged Cart.
|
311 |
+
*
|
312 |
+
* @since 5.1.9
|
313 |
+
*
|
314 |
+
* @param Cart\Cart_Interface $cart Instance of the cart repository managing the cart.
|
315 |
+
*/
|
316 |
+
return apply_filters( 'tec_tickets_commerce_cart_repository', $default_cart );
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Get the tickets currently in the cart for a given provider.
|
321 |
+
*
|
322 |
+
* @since 5.1.9
|
323 |
+
*
|
324 |
+
* @param bool $full_item_params Determines all the item params, including event_id, sub_total, and obj.
|
325 |
+
*
|
326 |
+
* @return array List of items.
|
327 |
+
*/
|
328 |
+
public function get_items_in_cart( $full_item_params = false ) {
|
329 |
+
$cart = $this->get_repository();
|
330 |
+
|
331 |
+
$items = $cart->get_items();
|
332 |
+
|
333 |
+
// When Items is empty in any capacity return an empty array.
|
334 |
+
if ( empty( $items ) ) {
|
335 |
+
return [];
|
336 |
+
}
|
337 |
+
|
338 |
+
if ( $full_item_params ) {
|
339 |
+
$items = array_map( static function ( $item ) {
|
340 |
+
$item['obj'] = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
|
341 |
+
$item['event_id'] = $item['obj']->get_event_id();
|
342 |
+
$item['sub_total'] = Price::sub_total( $item['obj']->price, $item['quantity'] );
|
343 |
+
|
344 |
+
return $item;
|
345 |
+
}, $items );
|
346 |
+
}
|
347 |
+
|
348 |
+
return $items;
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Handles the process of adding a ticket product to the cart.
|
353 |
+
*
|
354 |
+
* If the cart contains a line item for the product, this will replace the previous quantity.
|
355 |
+
* If the quantity is zero and the cart contains a line item for the product, this will remove it.
|
356 |
+
*
|
357 |
+
* @since 5.1.9
|
358 |
+
*
|
359 |
+
* @param int $ticket_id Ticket ID.
|
360 |
+
* @param int $quantity Ticket quantity to add.
|
361 |
+
* @param array $extra_data Extra data to send to the cart item.
|
362 |
+
*/
|
363 |
+
public function add_ticket( $ticket_id, $quantity = 1, array $extra_data = [] ) {
|
364 |
+
$cart = $this->get_repository();
|
365 |
+
|
366 |
+
// Enforces that the min to add is 1.
|
367 |
+
$quantity = max( 1, (int) $quantity );
|
368 |
+
|
369 |
+
// Add to / update quantity in cart.
|
370 |
+
$cart->add_item( $ticket_id, $quantity, $extra_data );
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Handles the process of adding a ticket product to the cart.
|
375 |
+
*
|
376 |
+
* If the cart contains a line item for the product, this will replace the previous quantity.
|
377 |
+
* If the quantity is zero and the cart contains a line item for the product, this will remove it.
|
378 |
+
*
|
379 |
+
* @since 5.1.9
|
380 |
+
*
|
381 |
+
* @param int $ticket_id Ticket ID.
|
382 |
+
* @param int $quantity Ticket quantity to remove.
|
383 |
+
*/
|
384 |
+
public function remove_ticket( $ticket_id, $quantity = 1 ) {
|
385 |
+
$cart = $this->get_repository();
|
386 |
+
|
387 |
+
// Enforces that the min to remove is 1.
|
388 |
+
$quantity = max( 1, (int) $quantity );
|
389 |
+
|
390 |
+
$cart->remove_item( $ticket_id, $quantity );
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* If product cache parameter is found, delete saved products from temporary cart.
|
395 |
+
*
|
396 |
+
* @filter wp_loaded 0
|
397 |
+
*
|
398 |
+
* @since 5.1.9
|
399 |
+
*/
|
400 |
+
public function maybe_delete_expired_products() {
|
401 |
+
$delete = tribe_get_request_var( 'clear_product_cache', null );
|
402 |
+
|
403 |
+
if ( empty( $delete ) ) {
|
404 |
+
return;
|
405 |
+
}
|
406 |
+
|
407 |
+
$transient_key = $this->get_current_cart_transient();
|
408 |
+
|
409 |
+
// Bail if we have no data key.
|
410 |
+
if ( false === $transient_key ) {
|
411 |
+
return;
|
412 |
+
}
|
413 |
+
|
414 |
+
$transient = get_transient( $transient_key );
|
415 |
+
|
416 |
+
// Bail if we have no data to delete.
|
417 |
+
if ( empty( $transient ) ) {
|
418 |
+
return;
|
419 |
+
}
|
420 |
+
|
421 |
+
// Bail if ET+ is not in place.
|
422 |
+
if ( ! class_exists( 'Tribe__Tickets_Plus__Meta__Storage' ) ) {
|
423 |
+
return;
|
424 |
+
}
|
425 |
+
$storage = new \Tribe__Tickets_Plus__Meta__Storage();
|
426 |
+
|
427 |
+
foreach ( $transient as $ticket_id => $data ) {
|
428 |
+
$storage->delete_cookie( $ticket_id );
|
429 |
+
}
|
430 |
+
}
|
431 |
+
|
432 |
+
/**
|
433 |
+
* Prepare the data for cart processing.
|
434 |
+
*
|
435 |
+
* Note that most of the data that is processed here is legacy, so you will see very weird and wonky naming.
|
436 |
+
* Make sure when you are making modifications you consider:
|
437 |
+
* - Event Tickets without ET+ additional data
|
438 |
+
* - Event Ticket Plus IAC
|
439 |
+
* - Event Tickets Plus Attendee Registration
|
440 |
+
*
|
441 |
+
* @since 5.1.9
|
442 |
+
*
|
443 |
+
* @param array $request_data Request Data to be prepared.
|
444 |
+
*
|
445 |
+
* @return array
|
446 |
+
*/
|
447 |
+
public function prepare_data( $request_data ) {
|
448 |
+
/**
|
449 |
+
* Filters the Cart data before sending to the prepare method.
|
450 |
+
*
|
451 |
+
* @since 5.1.9
|
452 |
+
*
|
453 |
+
* @param array $request_data The cart data before processing.
|
454 |
+
*/
|
455 |
+
$request_data = apply_filters( 'tec_tickets_commerce_cart_pre_prepare_data', $request_data );
|
456 |
+
|
457 |
+
if ( empty( $request_data['tribe_tickets_ar_data'] ) ) {
|
458 |
+
return [];
|
459 |
+
}
|
460 |
+
|
461 |
+
/** @var \Tribe__Tickets__Tickets_Handler $handler */
|
462 |
+
$handler = tribe( 'tickets.handler' );
|
463 |
+
|
464 |
+
$raw_data = $request_data['tribe_tickets_ar_data'];
|
465 |
+
|
466 |
+
// Attempt to JSON decode data if needed.
|
467 |
+
if ( ! is_array( $raw_data ) ) {
|
468 |
+
$raw_data = stripslashes( $raw_data );
|
469 |
+
$raw_data = json_decode( $raw_data, true );
|
470 |
+
}
|
471 |
+
|
472 |
+
$raw_data = array_merge( $request_data, $raw_data );
|
473 |
+
|
474 |
+
$data = [];
|
475 |
+
$data['post_id'] = absint( Arr::get( $raw_data, 'tribe_tickets_post_id' ) );
|
476 |
+
$data['provider'] = sanitize_text_field( Arr::get( $raw_data, 'tribe_tickets_provider', Module::class ) );
|
477 |
+
$data['tickets'] = Arr::get( $raw_data, 'tribe_tickets_tickets' );
|
478 |
+
$data['meta'] = Arr::get( $raw_data, 'tribe_tickets_meta', [] );
|
479 |
+
$tickets_meta = Arr::get( $raw_data, 'tribe_tickets', [] );
|
480 |
+
|
481 |
+
$default_ticket = [
|
482 |
+
'ticket_id' => 0,
|
483 |
+
'quantity' => 0,
|
484 |
+
'optout' => false,
|
485 |
+
'iac' => 'none',
|
486 |
+
'extra' => [],
|
487 |
+
];
|
488 |
+
|
489 |
+
/**
|
490 |
+
* @todo Determine if this should be moved into the Ticket Controller.
|
491 |
+
*/
|
492 |
+
$data['tickets'] = array_map( static function ( $ticket ) use ( $default_ticket, $handler, $tickets_meta ) {
|
493 |
+
if ( empty( $ticket['quantity'] ) ) {
|
494 |
+
return false;
|
495 |
+
}
|
496 |
+
|
497 |
+
$ticket = array_merge( $default_ticket, $ticket );
|
498 |
+
|
499 |
+
$ticket['quantity'] = (int) $ticket['quantity'];
|
500 |
+
|
501 |
+
if ( $ticket['quantity'] < 0 ) {
|
502 |
+
return false;
|
503 |
+
}
|
504 |
+
|
505 |
+
if ( ! empty( $tickets_meta[ $ticket['ticket_id'] ]['attendees'] ) ) {
|
506 |
+
$ticket['extra']['attendees'] = $tickets_meta[ $ticket['ticket_id'] ]['attendees'];
|
507 |
+
}
|
508 |
+
|
509 |
+
$ticket['extra']['optout'] = tribe_is_truthy( $ticket['optout'] );
|
510 |
+
unset( $ticket['optout'] );
|
511 |
+
|
512 |
+
$ticket['extra']['iac'] = sanitize_text_field( $ticket['iac'] );
|
513 |
+
unset( $ticket['iac'] );
|
514 |
+
|
515 |
+
$ticket['obj'] = \Tribe__Tickets__Tickets::load_ticket_object( $ticket['ticket_id'] );
|
516 |
+
|
517 |
+
if ( ! $handler->is_ticket_readable( $ticket['ticket_id'] ) ) {
|
518 |
+
return false;
|
519 |
+
}
|
520 |
+
|
521 |
+
return $ticket;
|
522 |
+
}, $data['tickets'] );
|
523 |
+
|
524 |
+
// Remove empty items.
|
525 |
+
$data['tickets'] = array_filter( $data['tickets'] );
|
526 |
+
|
527 |
+
/**
|
528 |
+
* Filters the Meta on the Data before processing.
|
529 |
+
*
|
530 |
+
* @since 5.1.9
|
531 |
+
*
|
532 |
+
* @param array $meta Meta information on the cart.
|
533 |
+
* @param array $data Data used for the cart.w
|
534 |
+
*/
|
535 |
+
$data['meta'] = apply_filters( 'tec_tickets_commerce_cart_prepare_data_meta', $data['meta'], $data );
|
536 |
+
|
537 |
+
/**
|
538 |
+
* Filters the Cart data before sending to to the Cart Repository.
|
539 |
+
*
|
540 |
+
* @since 5.1.9
|
541 |
+
*
|
542 |
+
* @param array $data The cart data after processing.
|
543 |
+
*/
|
544 |
+
return apply_filters( 'tec_tickets_commerce_cart_prepare_data', $data );
|
545 |
+
}
|
546 |
+
|
547 |
+
/**
|
548 |
+
* Prepares the data from the Tickets form.
|
549 |
+
*
|
550 |
+
* @since 5.1.9
|
551 |
+
*
|
552 |
+
* @return bool
|
553 |
+
*/
|
554 |
+
public function parse_request() {
|
555 |
+
// When it's not the current page we just bail.
|
556 |
+
if ( ! $this->is_current_page() ) {
|
557 |
+
return false;
|
558 |
+
}
|
559 |
+
|
560 |
+
$data = $this->prepare_data( $_POST );
|
561 |
+
|
562 |
+
/**
|
563 |
+
* Hook to inject behavior before cart is processed, if you need to change the data that will be used, you
|
564 |
+
* should look into `tec_tickets_commerce_cart_prepare_data`.
|
565 |
+
*
|
566 |
+
* @since 5.1.9
|
567 |
+
*
|
568 |
+
* @param array $data Data used to process the cart.
|
569 |
+
*/
|
570 |
+
do_action( 'tec_tickets_commerce_cart_before_process', $data );
|
571 |
+
|
572 |
+
$processed = $this->process( $data );
|
573 |
+
|
574 |
+
/**
|
575 |
+
* Hook to inject behavior after cart is processed.
|
576 |
+
*
|
577 |
+
* @since 5.1.9
|
578 |
+
*
|
579 |
+
* @param array $data Data used to process the cart.
|
580 |
+
* @param bool $processed Whether or not we processed the data.
|
581 |
+
*/
|
582 |
+
do_action( 'tec_tickets_commerce_cart_after_process', $data, $processed );
|
583 |
+
|
584 |
+
if ( static::REDIRECT_MODE === $this->get_mode() ) {
|
585 |
+
$redirect_url = tribe( Checkout::class )->get_url();
|
586 |
+
|
587 |
+
if ( ! $_COOKIE[ $this->get_cart_hash() ] ) {
|
588 |
+
$redirect_url = add_query_arg( [ static::$cookie_query_arg => $this->get_cart_hash() ], $redirect_url );
|
589 |
+
}
|
590 |
+
|
591 |
+
/**
|
592 |
+
* Which url it redirects after the processing of the cart.
|
593 |
+
*
|
594 |
+
* @since 5.1.9
|
595 |
+
*
|
596 |
+
* @param string $redirect_url Which url we will direct after processing the cart. Defaults to Checkout page.
|
597 |
+
* @param array $data Data that we just processed on the cart.
|
598 |
+
*/
|
599 |
+
$redirect_url = apply_filters( 'tec_tickets_commerce_cart_to_checkout_redirect_url', $redirect_url, $data );
|
600 |
+
|
601 |
+
if ( null !== $redirect_url ) {
|
602 |
+
wp_safe_redirect( $redirect_url );
|
603 |
+
tribe_exit();
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
return true;
|
608 |
+
}
|
609 |
+
|
610 |
+
/**
|
611 |
+
* Process a given cart data into this cart instance.
|
612 |
+
*
|
613 |
+
* @since 5.1.9
|
614 |
+
*
|
615 |
+
* @param array $data
|
616 |
+
*
|
617 |
+
* @return array|boolean Boolean true when it was a success or an array of errors.
|
618 |
+
*/
|
619 |
+
public function process( array $data = [] ) {
|
620 |
+
if ( empty( $data ) ) {
|
621 |
+
return false;
|
622 |
+
}
|
623 |
+
|
624 |
+
/** @var \Tribe__Tickets__REST__V1__Messages $messages */
|
625 |
+
$messages = tribe( 'tickets.rest-v1.messages' );
|
626 |
+
|
627 |
+
// Get the number of available tickets.
|
628 |
+
/** @var \Tribe__Tickets__Tickets_Handler $tickets_handler */
|
629 |
+
$tickets_handler = tribe( 'tickets.handler' );
|
630 |
+
|
631 |
+
$errors = [];
|
632 |
+
|
633 |
+
foreach ( $data['tickets'] as $ticket ) {
|
634 |
+
$available = $tickets_handler->get_ticket_max_purchase( $ticket['ticket_id'] );
|
635 |
+
|
636 |
+
// Bail if ticket does not have enough available capacity.
|
637 |
+
if ( ( - 1 !== $available && $available < $ticket['quantity'] ) || ! $ticket['obj']->date_in_range() ) {
|
638 |
+
$error_code = 'ticket-capacity-not-available';
|
639 |
+
|
640 |
+
$errors[] = new \WP_Error( $error_code, sprintf( $messages->get_message( $error_code ), $ticket['obj']->name ), [
|
641 |
+
'ticket' => $ticket,
|
642 |
+
'max_available' => $available,
|
643 |
+
] );
|
644 |
+
continue;
|
645 |
+
}
|
646 |
+
|
647 |
+
$this->add_ticket( $ticket['ticket_id'], $ticket['quantity'], $ticket['extra'] );
|
648 |
+
}
|
649 |
+
|
650 |
+
// Saved added items to the cart.
|
651 |
+
$this->get_repository()->save();
|
652 |
+
|
653 |
+
if ( ! empty( $errors ) ) {
|
654 |
+
return $errors;
|
655 |
+
}
|
656 |
+
|
657 |
+
return true;
|
658 |
+
}
|
659 |
+
|
660 |
+
}
|
src/Tickets/Commerce/Cart/Cart_Interface.php
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Cart;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Interface Cart_Interface
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce\Cart
|
11 |
+
*/
|
12 |
+
interface Cart_Interface {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Sets the cart id.
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*
|
19 |
+
* @param string $id
|
20 |
+
*/
|
21 |
+
public function set_id( $id );
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Gets the Cart mode based.
|
25 |
+
*
|
26 |
+
* @since 5.1.9
|
27 |
+
*
|
28 |
+
* @return string
|
29 |
+
*/
|
30 |
+
public function get_mode();
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Gets the cart items from the cart.
|
34 |
+
*
|
35 |
+
* This method should include any persistence by the cart implementation.
|
36 |
+
*
|
37 |
+
* @since 5.1.9
|
38 |
+
*
|
39 |
+
* @return array
|
40 |
+
*/
|
41 |
+
public function get_items();
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Saves the cart.
|
45 |
+
*
|
46 |
+
* This method should include any persistence, request and redirection required
|
47 |
+
* by the cart implementation.
|
48 |
+
*
|
49 |
+
* @since 5.1.9
|
50 |
+
*/
|
51 |
+
public function save();
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Clears the cart of its contents and persists its new state.
|
55 |
+
*
|
56 |
+
* This method should include any persistence, request and redirection required
|
57 |
+
* by the cart implementation.
|
58 |
+
*/
|
59 |
+
public function clear();
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Whether a cart exists meeting the specified criteria.
|
63 |
+
*
|
64 |
+
* @since 5.1.9
|
65 |
+
*
|
66 |
+
* @param array $criteria
|
67 |
+
*/
|
68 |
+
public function exists( array $criteria = [] );
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Whether the cart contains items or not.
|
72 |
+
*
|
73 |
+
* @since 5.1.9
|
74 |
+
*
|
75 |
+
* @return bool|int The number of products in the cart (regardless of the products quantity) or `false`
|
76 |
+
*
|
77 |
+
*/
|
78 |
+
public function has_items();
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Whether an item is in the cart or not.
|
82 |
+
*
|
83 |
+
* @since 5.1.9
|
84 |
+
*
|
85 |
+
* @param string $item_id
|
86 |
+
*
|
87 |
+
* @return bool|int Either the quantity in the cart for the item or `false`.
|
88 |
+
*/
|
89 |
+
public function has_item( $item_id );
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Adds a specified quantity of the item to the cart.
|
93 |
+
*
|
94 |
+
* @since 5.1.9
|
95 |
+
*
|
96 |
+
* @param int|string $item_id The item ID.
|
97 |
+
* @param int $quantity The quantity to remove.
|
98 |
+
* @param array $extra_data Extra data to save to the item.
|
99 |
+
*/
|
100 |
+
public function add_item( $item_id, $quantity, array $extra_data = [] );
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Determines if this instance of the cart has a public page.
|
104 |
+
*
|
105 |
+
* @since 5.1.9
|
106 |
+
*
|
107 |
+
* @return bool
|
108 |
+
*/
|
109 |
+
public function has_public_page();
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Removes an item from the cart.
|
113 |
+
*
|
114 |
+
* @since 5.1.9
|
115 |
+
*
|
116 |
+
* @param int|string $item_id The item ID.
|
117 |
+
* @param null|int $quantity The quantity to remove.
|
118 |
+
*/
|
119 |
+
public function remove_item( $item_id, $quantity = null );
|
120 |
+
}
|
src/Tickets/Commerce/Cart/Unmanaged_Cart.php
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Cart;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Unmanaged_Cart
|
9 |
+
*
|
10 |
+
* Models a transitional, not managed, cart implementation; cart management functionality
|
11 |
+
* is offloaded to PayPal.
|
12 |
+
*
|
13 |
+
* @since 5.1.9
|
14 |
+
*/
|
15 |
+
class Unmanaged_Cart implements Cart_Interface {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string The Cart hash for this cart.
|
19 |
+
*/
|
20 |
+
protected $cart_hash;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var array|null The list of items, null if not retrieved from transient yet.
|
24 |
+
*/
|
25 |
+
protected $items = null;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* {@inheritDoc}
|
29 |
+
*/
|
30 |
+
public function has_public_page() {
|
31 |
+
return false;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* {@inheritDoc}
|
36 |
+
*/
|
37 |
+
public function get_mode() {
|
38 |
+
return \TEC\Tickets\Commerce\Cart::REDIRECT_MODE;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* {@inheritdoc}
|
43 |
+
*/
|
44 |
+
public function set_id( $id ) {
|
45 |
+
$this->cart_hash = $id;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* {@inheritdoc}
|
50 |
+
*/
|
51 |
+
public function save() {
|
52 |
+
$cart_hash = tribe( Commerce\Cart::class )->get_cart_hash( true );
|
53 |
+
|
54 |
+
if ( false === $cart_hash ) {
|
55 |
+
return false;
|
56 |
+
}
|
57 |
+
|
58 |
+
if ( ! $this->has_items() ) {
|
59 |
+
$this->clear();
|
60 |
+
|
61 |
+
return;
|
62 |
+
}
|
63 |
+
|
64 |
+
set_transient( Commerce\Cart::get_transient_name( $cart_hash ), $this->items, DAY_IN_SECONDS );
|
65 |
+
tribe( Commerce\Cart::class )->set_cart_hash_cookie( $cart_hash );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* {@inheritdoc}
|
70 |
+
*/
|
71 |
+
public function get_items() {
|
72 |
+
if ( null !== $this->items ) {
|
73 |
+
return $this->items;
|
74 |
+
}
|
75 |
+
|
76 |
+
if ( ! $this->exists() ) {
|
77 |
+
return false;
|
78 |
+
}
|
79 |
+
|
80 |
+
$cart_hash = tribe( Commerce\Cart::class )->get_cart_hash();
|
81 |
+
|
82 |
+
$items = get_transient( Commerce\Cart::get_transient_name( $cart_hash ) );
|
83 |
+
|
84 |
+
if ( is_array( $items ) && ! empty( $items ) ) {
|
85 |
+
$this->items = $items;
|
86 |
+
}
|
87 |
+
|
88 |
+
return $this->items;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* {@inheritdoc}
|
93 |
+
*/
|
94 |
+
public function clear() {
|
95 |
+
$cart_hash = tribe( Commerce\Cart::class )->get_cart_hash();
|
96 |
+
|
97 |
+
if ( false === $cart_hash ) {
|
98 |
+
return false;
|
99 |
+
}
|
100 |
+
|
101 |
+
delete_transient( Commerce\Cart::get_transient_name( $cart_hash ) );
|
102 |
+
tribe( Commerce\Cart::class )->set_cart_hash_cookie( $cart_hash );
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* {@inheritdoc}
|
107 |
+
*/
|
108 |
+
public function exists( array $criteria = [] ) {
|
109 |
+
$cart_hash = tribe( Commerce\Cart::class )->get_cart_hash();
|
110 |
+
|
111 |
+
if ( false === $cart_hash ) {
|
112 |
+
return false;
|
113 |
+
}
|
114 |
+
|
115 |
+
return (bool) get_transient( Commerce\Cart::get_transient_name( $cart_hash ) );
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* {@inheritdoc}
|
120 |
+
*/
|
121 |
+
public function has_items() {
|
122 |
+
$items = $this->get_items();
|
123 |
+
|
124 |
+
return count( $items );
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* {@inheritdoc}
|
129 |
+
*/
|
130 |
+
public function has_item( $item_id ) {
|
131 |
+
$items = $this->get_items();
|
132 |
+
|
133 |
+
return ! empty( $items[ $item_id ] ) ? (int) $items[ $item_id ]['quantity'] : false;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* {@inheritdoc}
|
138 |
+
*/
|
139 |
+
public function add_item( $item_id, $quantity, array $extra_data = [] ) {
|
140 |
+
$current_quantity = $this->has_item( $item_id );
|
141 |
+
|
142 |
+
$new_quantity = (int) $quantity;
|
143 |
+
|
144 |
+
if ( 0 < $current_quantity ) {
|
145 |
+
$new_quantity += (int) $current_quantity;
|
146 |
+
}
|
147 |
+
|
148 |
+
$new_quantity = max( $new_quantity, 0 );
|
149 |
+
|
150 |
+
if ( 0 < $new_quantity ) {
|
151 |
+
$item['ticket_id'] = $item_id;
|
152 |
+
$item['quantity'] = $new_quantity;
|
153 |
+
|
154 |
+
$item['extra'] = $extra_data;
|
155 |
+
|
156 |
+
$this->items[ $item_id ] = $item;
|
157 |
+
} else {
|
158 |
+
$this->remove_item( $item_id );
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* {@inheritdoc}
|
164 |
+
*/
|
165 |
+
public function remove_item( $item_id, $quantity = null ) {
|
166 |
+
if ( null !== $quantity ) {
|
167 |
+
$this->add_item( $item_id, - abs( (int) $quantity ) );
|
168 |
+
|
169 |
+
return;
|
170 |
+
}
|
171 |
+
|
172 |
+
if ( $this->has_item( $item_id ) ) {
|
173 |
+
unset( $this->items[ $item_id ] );
|
174 |
+
}
|
175 |
+
}
|
176 |
+
}
|
src/Tickets/Commerce/Checkout.php
ADDED
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Checkout
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce
|
11 |
+
*/
|
12 |
+
class Checkout {
|
13 |
+
/**
|
14 |
+
* Get the Checkout page ID.
|
15 |
+
*
|
16 |
+
* @since 5.1.9
|
17 |
+
*
|
18 |
+
*
|
19 |
+
* @return int|null
|
20 |
+
*/
|
21 |
+
public function get_page_id() {
|
22 |
+
$checkout_page = (int) tribe_get_option( Settings::$option_checkout_page );
|
23 |
+
|
24 |
+
if ( empty( $checkout_page ) ) {
|
25 |
+
return null;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Allows filtering of the Page ID for the Checkout page.
|
30 |
+
*
|
31 |
+
* @since 5.1.9
|
32 |
+
*
|
33 |
+
* @param int|null $checkout_page Which page is used in the settings.
|
34 |
+
*/
|
35 |
+
return apply_filters( 'tec_tickets_commerce_checkout_page_id', $checkout_page );
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Determine the Current checkout URL.
|
40 |
+
*
|
41 |
+
* @since 5.1.9
|
42 |
+
*
|
43 |
+
* @return string
|
44 |
+
*/
|
45 |
+
public function get_url() {
|
46 |
+
$url = home_url( '/' );
|
47 |
+
$checkout_page = $this->get_page_id();
|
48 |
+
|
49 |
+
if ( is_numeric( $checkout_page ) ) {
|
50 |
+
$checkout_page = get_post( $checkout_page );
|
51 |
+
}
|
52 |
+
|
53 |
+
// Only modify the URL in case we have a checkout page setup in the settings.
|
54 |
+
if ( $checkout_page instanceof \WP_Post ) {
|
55 |
+
$url = get_the_permalink( $checkout_page );
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Allows modifications to the checkout url for Tickets Commerce.
|
60 |
+
*
|
61 |
+
* @since 5.1.9
|
62 |
+
*
|
63 |
+
* @param string $url URL for the cart.
|
64 |
+
*/
|
65 |
+
return (string) apply_filters( 'tec_tickets_commerce_checkout_url', $url );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Determines if the current page is the Checkout page.
|
70 |
+
*
|
71 |
+
* @since 5.1.9
|
72 |
+
*
|
73 |
+
*
|
74 |
+
* @return bool
|
75 |
+
*/
|
76 |
+
public function is_current_page() {
|
77 |
+
if ( is_admin() ) {
|
78 |
+
return false;
|
79 |
+
}
|
80 |
+
|
81 |
+
$current_page = get_queried_object_id();
|
82 |
+
$is_current_page = $this->get_page_id() === $current_page;
|
83 |
+
|
84 |
+
/**
|
85 |
+
* @todo determine hte usage of tribe_ticket_redirect_to
|
86 |
+
* $redirect = tribe_get_request_var( 'tribe_tickets_redirect_to', null );
|
87 |
+
*/
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Allows modifications to the conditional of if we are in the checkout page.
|
91 |
+
*
|
92 |
+
* @since 5.1.9
|
93 |
+
*
|
94 |
+
* @param bool $is_current_page Are we in the current page for checkout.
|
95 |
+
*/
|
96 |
+
return tribe_is_truthy( apply_filters( 'tec_tickets_commerce_checkout_is_current_page', $is_current_page ) );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* If there is any data or request management or parsing that needs to happen on the Checkout page here is where
|
101 |
+
* we do it.
|
102 |
+
*
|
103 |
+
* @since 5.1.9
|
104 |
+
*/
|
105 |
+
public function parse_request() {
|
106 |
+
if ( ! $this->is_current_page() ) {
|
107 |
+
return;
|
108 |
+
}
|
109 |
+
|
110 |
+
// In case the ID is passed we set the cookie for usage.
|
111 |
+
$cookie_param = tribe_get_request_var( Cart::$cookie_query_arg, false );
|
112 |
+
if ( $cookie_param ) {
|
113 |
+
tribe( Cart::class )->set_cart_hash_cookie( $cookie_param );
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Get the login URL.
|
119 |
+
*
|
120 |
+
* @since 5.1.9
|
121 |
+
*
|
122 |
+
* @return string
|
123 |
+
*/
|
124 |
+
public function get_login_url() {
|
125 |
+
$login_url = get_site_url( null, 'wp-login.php' );
|
126 |
+
|
127 |
+
$login_url = add_query_arg( 'redirect_to', $this->get_url(), $login_url );
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Provides an opportunity to modify the login URL used within frontend
|
131 |
+
* checkout (typically when they need to login before they can proceed).
|
132 |
+
*
|
133 |
+
* @since 5.1.9
|
134 |
+
*
|
135 |
+
* @param string $login_url
|
136 |
+
*/
|
137 |
+
return apply_filters( 'tec_tickets_commerce_checkout_login_url', $login_url );
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Get the registration URL.
|
142 |
+
*
|
143 |
+
* @since 5.1.9
|
144 |
+
*
|
145 |
+
* @return string
|
146 |
+
*/
|
147 |
+
public function get_registration_url() {
|
148 |
+
$registration_url = wp_registration_url();
|
149 |
+
|
150 |
+
$registration_url = add_query_arg( 'redirect_to', $this->get_url(), $registration_url );
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Provides an opportunity to modify the registration URL used within frontend
|
154 |
+
* checkout (typically when they need to login before they can proceed).
|
155 |
+
*
|
156 |
+
* @since 5.1.9
|
157 |
+
*
|
158 |
+
* @param string $login_url
|
159 |
+
*/
|
160 |
+
return apply_filters( 'tec_tickets_commerce_checkout_registration_url', $registration_url );
|
161 |
+
}
|
162 |
+
}
|
src/Tickets/Commerce/Communication/Email.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Communications;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Email
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce\Communications
|
11 |
+
*/
|
12 |
+
class Email {
|
13 |
+
/**
|
14 |
+
* Sends ticket email
|
15 |
+
*
|
16 |
+
* @since 4.7.6 added $post_id parameter
|
17 |
+
*
|
18 |
+
* @param string $order_id Order post ID
|
19 |
+
* @param int $post_id Parent post ID (optional)
|
20 |
+
*/
|
21 |
+
public function send_tickets_email( $order_id, $post_id = null ) {
|
22 |
+
$all_attendees = $this->get_attendees_by_order_id( $order_id );
|
23 |
+
|
24 |
+
$to_send = array();
|
25 |
+
|
26 |
+
if ( empty( $all_attendees ) ) {
|
27 |
+
return;
|
28 |
+
}
|
29 |
+
|
30 |
+
// Look at each attendee and check if a ticket was sent: in each case where a ticket
|
31 |
+
// has not yet been sent we should a) send the ticket out by email and b) record the
|
32 |
+
// fact it was sent
|
33 |
+
foreach ( $all_attendees as $single_attendee ) {
|
34 |
+
// Only add those attendees/tickets that haven't already been sent
|
35 |
+
if ( ! empty( $single_attendee['ticket_sent'] ) ) {
|
36 |
+
continue;
|
37 |
+
}
|
38 |
+
|
39 |
+
$to_send[] = $single_attendee;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Controls the list of tickets which will be emailed out.
|
44 |
+
*
|
45 |
+
* @since 4.7
|
46 |
+
* @since 4.7.6 added new parameter $post_id
|
47 |
+
*
|
48 |
+
* @param array $to_send list of tickets to be sent out by email
|
49 |
+
* @param array $all_attendees list of all attendees/tickets, including those already sent out
|
50 |
+
* @param int $post_id
|
51 |
+
* @param string $order_id
|
52 |
+
*
|
53 |
+
*/
|
54 |
+
$to_send = (array) apply_filters( 'tribe_tickets_tpp_tickets_to_send', $to_send, $all_attendees, $post_id, $order_id );
|
55 |
+
|
56 |
+
if ( empty( $to_send ) ) {
|
57 |
+
return;
|
58 |
+
}
|
59 |
+
|
60 |
+
$send_args = [
|
61 |
+
'post_id' => $post_id,
|
62 |
+
'order_id' => $order_id,
|
63 |
+
'send_purchaser_all' => true,
|
64 |
+
];
|
65 |
+
|
66 |
+
// Send the emails.
|
67 |
+
$this->send_tickets_email_for_attendees( $to_send, $send_args );
|
68 |
+
}
|
69 |
+
}
|
src/Tickets/Commerce/Currency.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Currency
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce
|
11 |
+
*/
|
12 |
+
class Currency {
|
13 |
+
|
14 |
+
}
|
src/Tickets/Commerce/Editor/Metabox.php
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Editor;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Module;
|
6 |
+
use Tribe__Tickets__Main as Tickets_Plugin;
|
7 |
+
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class Metabox.
|
11 |
+
*
|
12 |
+
* @since 5.1.9
|
13 |
+
*
|
14 |
+
* @package TEC\Tickets\Commerce\Editor
|
15 |
+
*/
|
16 |
+
class Metabox {
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Add the sku field in the admin's new/edit ticket metabox
|
21 |
+
*
|
22 |
+
* @since 4.7
|
23 |
+
*
|
24 |
+
* @param $post_id int id of the event post
|
25 |
+
* @param int $ticket_id (null) id of the ticket
|
26 |
+
*
|
27 |
+
* @return void
|
28 |
+
*/
|
29 |
+
public function do_metabox_sku_options( $post_id, $ticket_id = null ) {
|
30 |
+
$sku = '';
|
31 |
+
|
32 |
+
/** @var \Tribe__Tickets__Tickets_Handler $tickets_handler */
|
33 |
+
$tickets_handler = tribe( 'tickets.handler' );
|
34 |
+
$provider_obj = tribe( Module::class );
|
35 |
+
|
36 |
+
$is_correct_provider = $tickets_handler->is_correct_provider( $post_id, $provider_obj );
|
37 |
+
|
38 |
+
if ( ! empty( $ticket_id ) ) {
|
39 |
+
$ticket = tribe( Module::class )->get_ticket( $post_id, $ticket_id );
|
40 |
+
$is_correct_provider = $tickets_handler->is_correct_provider( $ticket_id, $provider_obj );
|
41 |
+
|
42 |
+
if ( ! empty( $ticket ) ) {
|
43 |
+
$sku = get_post_meta( $ticket_id, '_sku', true );
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
// Bail when we are not dealing with this provider
|
48 |
+
if ( ! $is_correct_provider ) {
|
49 |
+
return;
|
50 |
+
}
|
51 |
+
|
52 |
+
$path = Tickets_Plugin::instance()->plugin_path;
|
53 |
+
|
54 |
+
include $path . 'src/admin-views/commerce/metabox/sku.php';
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Renders the advanced fields in the new/edit ticket form.
|
59 |
+
* Using the method, providers can add as many fields as
|
60 |
+
* they want, specific to their implementation.
|
61 |
+
*
|
62 |
+
* @since 5.1.9
|
63 |
+
*
|
64 |
+
* @param int $post_id
|
65 |
+
* @param int $ticket_id
|
66 |
+
*/
|
67 |
+
public function include_metabox_advanced_options( $post_id, $ticket_id ) {
|
68 |
+
$provider = __CLASS__;
|
69 |
+
|
70 |
+
echo '<div id="' . sanitize_html_class( $provider ) . '_advanced" class="tribe-dependent" data-depends="#' . sanitize_html_class( $provider ) . '_radio" data-condition-is-checked>';
|
71 |
+
|
72 |
+
if ( ! tribe_is_frontend() ) {
|
73 |
+
$this->do_metabox_sku_options( $post_id, $ticket_id );
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Allows for the insertion of additional content into the ticket edit form - advanced section
|
78 |
+
*
|
79 |
+
* @since 4.6
|
80 |
+
*
|
81 |
+
* @param int Post ID
|
82 |
+
* @param string the provider class name
|
83 |
+
* @param int $ticket_id The ticket ID.
|
84 |
+
*/
|
85 |
+
do_action( 'tribe_events_tickets_metabox_edit_ajax_advanced', $post_id, $provider, $ticket_id );
|
86 |
+
|
87 |
+
echo '</div>';
|
88 |
+
}
|
89 |
+
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Renders the advanced fields in the new/edit ticket form.
|
93 |
+
* Using the method, providers can add as many fields as
|
94 |
+
* they want, specific to their implementation.
|
95 |
+
*
|
96 |
+
* @since 4.7
|
97 |
+
*
|
98 |
+
* @param int $post_id
|
99 |
+
* @param int $ticket_id
|
100 |
+
*
|
101 |
+
* @return mixed
|
102 |
+
*/
|
103 |
+
public function do_metabox_capacity_options( $post_id, $ticket_id ) {
|
104 |
+
/** @var \Tribe__Tickets__Tickets_Handler $tickets_handler */
|
105 |
+
$tickets_handler = tribe( 'tickets.handler' );
|
106 |
+
$provider = tribe( Module::class );
|
107 |
+
|
108 |
+
$is_correct_provider = $tickets_handler->is_correct_provider( $post_id, $provider );
|
109 |
+
|
110 |
+
$url = '';
|
111 |
+
$stock = '';
|
112 |
+
$global_stock_mode = $tickets_handler->get_default_capacity_mode();
|
113 |
+
$global_stock_cap = 0;
|
114 |
+
$ticket_capacity = null;
|
115 |
+
$post_capacity = null;
|
116 |
+
|
117 |
+
$stock_object = new \Tribe__Tickets__Global_Stock( $post_id );
|
118 |
+
|
119 |
+
if ( $stock_object->is_enabled() ) {
|
120 |
+
$post_capacity = tribe_tickets_get_capacity( $post_id );
|
121 |
+
}
|
122 |
+
|
123 |
+
if ( ! empty( $ticket_id ) ) {
|
124 |
+
$ticket = tribe( Module::class )->get_ticket( $post_id, $ticket_id );
|
125 |
+
$is_correct_provider = $tickets_handler->is_correct_provider( $ticket_id, $provider );
|
126 |
+
|
127 |
+
if ( ! empty( $ticket ) ) {
|
128 |
+
$stock = $ticket->managing_stock() ? $ticket->stock() : '';
|
129 |
+
$ticket_capacity = tribe_tickets_get_capacity( $ticket->ID );
|
130 |
+
$global_stock_mode = ( method_exists( $ticket, 'global_stock_mode' ) ) ? $ticket->global_stock_mode() : '';
|
131 |
+
$global_stock_cap = ( method_exists( $ticket, 'global_stock_cap' ) ) ? $ticket->global_stock_cap() : 0;
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
// Bail when we are not dealing with this provider
|
136 |
+
if ( ! $is_correct_provider ) {
|
137 |
+
return;
|
138 |
+
}
|
139 |
+
|
140 |
+
$file = \Tribe__Tickets__Main::instance()->plugin_path . 'src/admin-views/commerce/metabox/capacity.php';
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Filters the absolute path to the file containing the metabox capacity HTML.
|
144 |
+
*
|
145 |
+
* @since 4.7
|
146 |
+
*
|
147 |
+
* @param string $file The absolute path to the file containing the metabox capacity HTML
|
148 |
+
* @param int|string $ticket_capacity
|
149 |
+
* @param int|string $post_capacity
|
150 |
+
*/
|
151 |
+
$file = apply_filters( 'tribe_tickets_tc_metabox_capacity_file', $file, $ticket_capacity, $post_capacity );
|
152 |
+
|
153 |
+
if ( file_exists( $file ) ) {
|
154 |
+
include $file;
|
155 |
+
}
|
156 |
+
}
|
157 |
+
}
|
src/Tickets/Commerce/Flag_Actions/Decrease_Stock.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Flag_Actions;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Order;
|
6 |
+
use TEC\Tickets\Commerce\Status\Status_Interface;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Decrease_Stock
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Flag_Actions
|
14 |
+
*/
|
15 |
+
class Decrease_Stock extends Flag_Action_Abstract {
|
16 |
+
/**
|
17 |
+
* {@inheritDoc}
|
18 |
+
*/
|
19 |
+
protected $flags = [
|
20 |
+
'decrease_stock',
|
21 |
+
];
|
22 |
+
|
23 |
+
/**
|
24 |
+
* {@inheritDoc}
|
25 |
+
*/
|
26 |
+
protected $post_types = [
|
27 |
+
Order::POSTTYPE
|
28 |
+
];
|
29 |
+
|
30 |
+
/**
|
31 |
+
* {@inheritDoc}
|
32 |
+
*/
|
33 |
+
public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
|
34 |
+
$i = true;
|
35 |
+
}
|
36 |
+
}
|
src/Tickets/Commerce/Flag_Actions/Flag_Action_Abstract.php
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Flag_Actions;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Status\Status_Interface;
|
6 |
+
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Flag Action Abstract.
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Flag_Actions
|
14 |
+
*/
|
15 |
+
abstract class Flag_Action_Abstract implements Flag_Action_Interface {
|
16 |
+
/**
|
17 |
+
* When will this particular flag wil be triggered
|
18 |
+
*
|
19 |
+
* @since 5.1.9
|
20 |
+
*
|
21 |
+
* @var int
|
22 |
+
*/
|
23 |
+
protected $priority = 10;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Which flags are associated and will trigger this action.
|
27 |
+
*
|
28 |
+
* @since 5.1.9
|
29 |
+
*
|
30 |
+
* @var string[]
|
31 |
+
*/
|
32 |
+
protected $flags = [];
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Which Post Types we check for this flag action.
|
36 |
+
*
|
37 |
+
* @since 5.1.9
|
38 |
+
*
|
39 |
+
* @var string[]
|
40 |
+
*/
|
41 |
+
protected $post_types;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* {@inheritDoc}
|
45 |
+
*/
|
46 |
+
public function get_flags() {
|
47 |
+
return $this->flags;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* {@inheritDoc}
|
52 |
+
*/
|
53 |
+
public function get_priority() {
|
54 |
+
return $this->priority;
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* {@inheritDoc}
|
59 |
+
*/
|
60 |
+
public function get_post_types() {
|
61 |
+
return $this->post_types;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* {@inheritDoc}
|
66 |
+
*/
|
67 |
+
public function should_trigger( Status_Interface $new_status, $old_status, $post ) {
|
68 |
+
if ( ! $this->has_flags( $new_status ) ) {
|
69 |
+
return false;
|
70 |
+
}
|
71 |
+
|
72 |
+
if ( ! $this->is_correct_post_type( $post ) ) {
|
73 |
+
return false;
|
74 |
+
}
|
75 |
+
|
76 |
+
return true;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* {@inheritDoc}
|
81 |
+
*/
|
82 |
+
public function has_flags( Status_Interface $status ) {
|
83 |
+
return $status->has_flags( $this->get_flags() );
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* {@inheritDoc}
|
88 |
+
*/
|
89 |
+
public function is_correct_post_type( \WP_Post $post ) {
|
90 |
+
return in_array( $post->post_type, $this->get_post_types(), true );
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* {@inheritDoc}
|
95 |
+
*/
|
96 |
+
public function maybe_handle( Status_Interface $new_status, $old_status, $post ) {
|
97 |
+
if ( ! $this->should_trigger( $new_status, $old_status, $post ) ) {
|
98 |
+
return;
|
99 |
+
}
|
100 |
+
/**
|
101 |
+
* @todo For now Flag actions are only for order, so we use `tec_tc_get_order()` but if in the future we add any
|
102 |
+
* other post types to the mix we will need to provide a way to pass the post via a formatting method.
|
103 |
+
*/
|
104 |
+
$post = tec_tc_get_order( $post );
|
105 |
+
|
106 |
+
$this->handle( $new_status, $old_status, $post );
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* {@inheritDoc}
|
111 |
+
*/
|
112 |
+
public function hook() {
|
113 |
+
foreach ( $this->get_flags() as $flag ) {
|
114 |
+
add_action( "tec_tickets_commerce_order_status_flag_{$flag}", [ $this, 'maybe_handle' ], $this->get_priority(), 3 );
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* {@inheritDoc}
|
120 |
+
*/
|
121 |
+
abstract public function handle( Status_Interface $new_status, $old_status, \WP_Post $post );
|
122 |
+
}
|
src/Tickets/Commerce/Flag_Actions/Flag_Action_Handler.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Flag_Actions;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Flag_Action_Handler
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce\Flag_Actions
|
11 |
+
*/
|
12 |
+
class Flag_Action_Handler extends \tad_DI52_ServiceProvider {
|
13 |
+
/**
|
14 |
+
* Flag Actions registered.
|
15 |
+
*
|
16 |
+
* @since 5.1.9
|
17 |
+
*
|
18 |
+
* @var Flag_Action_Interface[]
|
19 |
+
*/
|
20 |
+
protected $flag_actions = [];
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Which classes we will load for order flag actions by default.
|
24 |
+
*
|
25 |
+
* @since 5.1.9
|
26 |
+
*
|
27 |
+
* @var string[]
|
28 |
+
*/
|
29 |
+
protected $default_flag_actions = [
|
30 |
+
Generate_Attendees::class,
|
31 |
+
Increase_Stock::class,
|
32 |
+
Decrease_Stock::class,
|
33 |
+
];
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Gets the flag actions registered.
|
37 |
+
*
|
38 |
+
* @since 5.1.9
|
39 |
+
*
|
40 |
+
* @return Flag_Action_Interface[]
|
41 |
+
*/
|
42 |
+
public function get_all() {
|
43 |
+
return $this->flag_actions;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Sets up all the Flag Action instances for the Classes registered in $default_flag_actions.
|
48 |
+
*
|
49 |
+
* @since 5.1.9
|
50 |
+
*/
|
51 |
+
public function register() {
|
52 |
+
foreach ( $this->default_flag_actions as $flag_action_class ) {
|
53 |
+
// Spawn the new instance.
|
54 |
+
$flag_action = new $flag_action_class;
|
55 |
+
|
56 |
+
// Register as a singleton for internal ease of use.
|
57 |
+
$this->container->singleton( $flag_action_class, $flag_action );
|
58 |
+
|
59 |
+
// Collect this particular status instance in this class.
|
60 |
+
$this->register_flag_action( $flag_action );
|
61 |
+
}
|
62 |
+
|
63 |
+
$this->container->singleton( static::class, $this );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Register a given flag action into the Handler, and hook the handling to WP.
|
68 |
+
*
|
69 |
+
* @since 5.1.9
|
70 |
+
*
|
71 |
+
* @param Flag_Action_Interface $flag_action Which flag action we are registering.
|
72 |
+
*/
|
73 |
+
public function register_flag_action( Flag_Action_Interface $flag_action ) {
|
74 |
+
$this->flag_actions[] = $flag_action;
|
75 |
+
$flag_action->hook();
|
76 |
+
}
|
77 |
+
}
|
src/Tickets/Commerce/Flag_Actions/Flag_Action_Interface.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace TEC\Tickets\Commerce\Flag_Actions;
|
3 |
+
|
4 |
+
use TEC\Tickets\Commerce\Status\Status_Interface;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Class Flag Action Interface.
|
8 |
+
*
|
9 |
+
* @since 5.1.9
|
10 |
+
*
|
11 |
+
* @package TEC\Tickets\Commerce\Flag_Actions
|
12 |
+
*/
|
13 |
+
interface Flag_Action_Interface {
|
14 |
+
/**
|
15 |
+
* Gets the flags that we could trigger this flag action for.
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*
|
19 |
+
* @return string[]
|
20 |
+
*/
|
21 |
+
public function get_flags();
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Gets the post types that we could trigger this flag action for.
|
25 |
+
*
|
26 |
+
* @since 5.1.9
|
27 |
+
*
|
28 |
+
* @return string[]
|
29 |
+
*/
|
30 |
+
public function get_post_types();
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Which priority we will hook this particular flag action.
|
34 |
+
*
|
35 |
+
* @since 5.1.9
|
36 |
+
*
|
37 |
+
* @return int
|
38 |
+
*/
|
39 |
+
public function get_priority();
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Determines if a transition of status will trigger this flag action.
|
43 |
+
*
|
44 |
+
* @since 5.1.9
|
45 |
+
*
|
46 |
+
* @param Status_Interface $new_status New post status.
|
47 |
+
* @param Status_Interface|null $old_status Old post status.
|
48 |
+
* @param \WP_Post $post Post object.
|
49 |
+
*
|
50 |
+
* @return bool
|
51 |
+
*/
|
52 |
+
public function should_trigger( Status_Interface $new_status, $old_status, $post );
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Determines if a given status has the correct action flag to trigger.
|
56 |
+
*
|
57 |
+
* @since 5.1.9
|
58 |
+
*
|
59 |
+
* @param Status_Interface $status
|
60 |
+
*
|
61 |
+
* @return bool
|
62 |
+
*/
|
63 |
+
public function has_flags( Status_Interface $status );
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Determines if a given post object is the correct post type to trigger this flag action
|
67 |
+
*
|
68 |
+
* @since 5.1.9
|
69 |
+
*
|
70 |
+
* @param \WP_Post $post
|
71 |
+
*
|
72 |
+
* @return bool
|
73 |
+
*/
|
74 |
+
public function is_correct_post_type( \WP_Post $post );
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Handles the action flag execution.
|
78 |
+
*
|
79 |
+
* @since 5.1.9
|
80 |
+
*
|
81 |
+
* @param Status_Interface $new_status New post status.
|
82 |
+
* @param Status_Interface|null $old_status Old post status.
|
83 |
+
* @param \WP_Post $post Post object.
|
84 |
+
*/
|
85 |
+
public function handle( Status_Interface $new_status, $old_status, \WP_Post $post );
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Triggers the handle method if should_trigger method is true.
|
89 |
+
*
|
90 |
+
* @since 5.1.9
|
91 |
+
*
|
92 |
+
* @param Status_Interface $new_status New post status.
|
93 |
+
* @param Status_Interface|null $old_status Old post status.
|
94 |
+
* @param \WP_Post $post Post object.
|
95 |
+
*/
|
96 |
+
public function maybe_handle( Status_Interface $new_status, $old_status, $post );
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Handles the hooking of a given flag action to the correct actions in WP.
|
100 |
+
*
|
101 |
+
* @since 5.1.9
|
102 |
+
*/
|
103 |
+
public function hook();
|
104 |
+
}
|
src/Tickets/Commerce/Flag_Actions/Generate_Attendees.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Flag_Actions;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Order;
|
6 |
+
use TEC\Tickets\Commerce\Status\Status_Interface;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Attendee_Generation
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Flag_Actions
|
14 |
+
*/
|
15 |
+
class Generate_Attendees extends Flag_Action_Abstract {
|
16 |
+
/**
|
17 |
+
* {@inheritDoc}
|
18 |
+
*/
|
19 |
+
protected $flags = [
|
20 |
+
'generate_attendees',
|
21 |
+
];
|
22 |
+
|
23 |
+
/**
|
24 |
+
* {@inheritDoc}
|
25 |
+
*/
|
26 |
+
protected $post_types = [
|
27 |
+
Order::POSTTYPE
|
28 |
+
];
|
29 |
+
|
30 |
+
/**
|
31 |
+
* {@inheritDoc}
|
32 |
+
*/
|
33 |
+
public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
|
34 |
+
$i = true;
|
35 |
+
}
|
36 |
+
}
|
src/Tickets/Commerce/Flag_Actions/Increase_Stock.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Flag_Actions;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Order;
|
6 |
+
use TEC\Tickets\Commerce\Status\Status_Interface;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Increase_Stock
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Flag_Actions
|
14 |
+
*/
|
15 |
+
class Increase_Stock extends Flag_Action_Abstract {
|
16 |
+
/**
|
17 |
+
* {@inheritDoc}
|
18 |
+
*/
|
19 |
+
protected $flags = [
|
20 |
+
'increase_stock',
|
21 |
+
];
|
22 |
+
|
23 |
+
/**
|
24 |
+
* {@inheritDoc}
|
25 |
+
*/
|
26 |
+
protected $post_types = [
|
27 |
+
Order::POSTTYPE
|
28 |
+
];
|
29 |
+
|
30 |
+
/**
|
31 |
+
* {@inheritDoc}
|
32 |
+
*/
|
33 |
+
public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
|
34 |
+
$i = true;
|
35 |
+
}
|
36 |
+
}
|
src/Tickets/Commerce/Gateways/Abstract_Gateway.php
CHANGED
@@ -8,7 +8,7 @@
|
|
8 |
|
9 |
namespace TEC\Tickets\Commerce\Gateways;
|
10 |
|
11 |
-
use
|
12 |
|
13 |
/**
|
14 |
* The gateway related functionality.
|
@@ -33,15 +33,18 @@ abstract class Abstract_Gateway implements Interface_Gateway {
|
|
33 |
return static::$key;
|
34 |
}
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
/**
|
37 |
* @inheritDoc
|
38 |
*/
|
39 |
public function register_gateway( array $gateways ) {
|
40 |
-
$gateways[ static::get_key() ] =
|
41 |
-
'label' => static::get_label(),
|
42 |
-
'class' => static::class,
|
43 |
-
'object' => $this,
|
44 |
-
];
|
45 |
|
46 |
return $gateways;
|
47 |
}
|
8 |
|
9 |
namespace TEC\Tickets\Commerce\Gateways;
|
10 |
|
11 |
+
use TEC\Tickets\Commerce;
|
12 |
|
13 |
/**
|
14 |
* The gateway related functionality.
|
33 |
return static::$key;
|
34 |
}
|
35 |
|
36 |
+
/**
|
37 |
+
* @inheritDoc
|
38 |
+
*/
|
39 |
+
public static function get_provider_key() {
|
40 |
+
return Commerce::PROVIDER . '-' . static::get_key();
|
41 |
+
}
|
42 |
+
|
43 |
/**
|
44 |
* @inheritDoc
|
45 |
*/
|
46 |
public function register_gateway( array $gateways ) {
|
47 |
+
$gateways[ static::get_key() ] = $this;
|
|
|
|
|
|
|
|
|
48 |
|
49 |
return $gateways;
|
50 |
}
|
src/Tickets/Commerce/Gateways/Interface_Gateway.php
CHANGED
@@ -15,10 +15,19 @@ interface Interface_Gateway {
|
|
15 |
*
|
16 |
* @since 5.1.6
|
17 |
*
|
18 |
-
* @return
|
19 |
*/
|
20 |
public static function get_key();
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
/**
|
23 |
* Get's the label for this Commerce Gateway.
|
24 |
*
|
@@ -53,7 +62,7 @@ interface Interface_Gateway {
|
|
53 |
*
|
54 |
* @param array $gateways The list of registered Tickets Commerce gateways.
|
55 |
*
|
56 |
-
* @return
|
57 |
*/
|
58 |
public function register_gateway( array $gateways );
|
59 |
}
|
15 |
*
|
16 |
* @since 5.1.6
|
17 |
*
|
18 |
+
* @return string What is the Key used.
|
19 |
*/
|
20 |
public static function get_key();
|
21 |
|
22 |
+
/**
|
23 |
+
* Get's the provider key for this Commerce Gateway.
|
24 |
+
*
|
25 |
+
* @since 5.1.9
|
26 |
+
*
|
27 |
+
* @return string What is the ORM Provider Key used.
|
28 |
+
*/
|
29 |
+
public static function get_provider_key();
|
30 |
+
|
31 |
/**
|
32 |
* Get's the label for this Commerce Gateway.
|
33 |
*
|
62 |
*
|
63 |
* @param array $gateways The list of registered Tickets Commerce gateways.
|
64 |
*
|
65 |
+
* @return Abstract_Gateway[] The list of registered Tickets Commerce gateways.
|
66 |
*/
|
67 |
public function register_gateway( array $gateways );
|
68 |
}
|
src/Tickets/Commerce/Gateways/Legacy/Gateway.php
DELETED
@@ -1,106 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
*
|
4 |
-
* @todo This file is not being used currently but we need to remove this before we launch Tickets Commerce.
|
5 |
-
*
|
6 |
-
* @since 5.1.6
|
7 |
-
*
|
8 |
-
* @package TEC\Tickets\Commerce\Gateways\Legacy
|
9 |
-
*/
|
10 |
-
|
11 |
-
namespace TEC\Tickets\Commerce\Gateways\Legacy;
|
12 |
-
|
13 |
-
use TEC\Tickets\Commerce\Gateways\Abstract_Gateway;
|
14 |
-
use TEC\Tickets\Commerce\Gateways\Manager;
|
15 |
-
use Tribe__Tickets__Commerce__PayPal__Main as PayPal_Main;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* The PayPal Standard (Legacy) specific functionality.
|
19 |
-
*
|
20 |
-
* This class will contain everything we can pull out from Tribe__Tickets__Commerce__PayPal__Main that is
|
21 |
-
* PayPal Standard (Legacy) specific. Anything we can do to split off the logic into this class would be helpful for
|
22 |
-
* long term maintenance and reducing mess between the various Tickets Commerce gateways developed.
|
23 |
-
*
|
24 |
-
* @since 5.1.6
|
25 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal_Legacy
|
26 |
-
*/
|
27 |
-
class Gateway extends Abstract_Gateway {
|
28 |
-
|
29 |
-
/**
|
30 |
-
* @inheritDoc
|
31 |
-
*/
|
32 |
-
protected static $key = 'paypal-legacy';
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @inheritDoc
|
36 |
-
*/
|
37 |
-
public static function get_label() {
|
38 |
-
return __( 'PayPal Standard (Legacy)', 'event-tickets' );
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* @inheritDoc
|
43 |
-
*/
|
44 |
-
public static function is_active() {
|
45 |
-
// If this gateway shouldn't be shown, then don't change the active status.
|
46 |
-
if ( ! static::should_show() ) {
|
47 |
-
return false;
|
48 |
-
}
|
49 |
-
|
50 |
-
/** @var \Tribe__Tickets__Commerce__PayPal__Gateway $gateway */
|
51 |
-
$gateway = tribe( 'tickets.commerce.paypal.gateway' );
|
52 |
-
|
53 |
-
/** @var \Tribe__Tickets__Commerce__PayPal__Handler__Interface $handler */
|
54 |
-
$handler = $gateway->build_handler();
|
55 |
-
|
56 |
-
// Only mark as active if config status is complete.
|
57 |
-
return 'complete' === $handler->get_config_status();
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* @inheritDoc
|
62 |
-
*/
|
63 |
-
public static function should_show() {
|
64 |
-
/**
|
65 |
-
* @todo for we just dont show legacy for testing purposes.
|
66 |
-
*/
|
67 |
-
if ( ! tribe( Manager::class )->should_show_legacy() ) {
|
68 |
-
return false;
|
69 |
-
}
|
70 |
-
|
71 |
-
// This site installed Event Tickets 5.2+ so it never should show the old option.
|
72 |
-
if ( ! tribe_installed_before( 'Tribe__Tickets__Main', '5.2' ) ) {
|
73 |
-
return false;
|
74 |
-
}
|
75 |
-
|
76 |
-
// @todo Future: Disable gateway if it does not match the current gateway as the next step down the road.
|
77 |
-
/*if ( $this->gateway_key !== tribe_get_option( $commerce->option_gateway ) ) {
|
78 |
-
return false;
|
79 |
-
}*/
|
80 |
-
|
81 |
-
// Tribe Commerce was previously enabled.
|
82 |
-
$paypal_enable = tribe_is_truthy( tribe_get_option( 'ticket-paypal-enable' ) );
|
83 |
-
|
84 |
-
// Tribe Commerce PayPal email was previously set.
|
85 |
-
$paypal_email_is_set = '' !== tribe_get_option( 'ticket-paypal-email' );
|
86 |
-
|
87 |
-
// The gateway should show if it was ever enabled or email was previously set.
|
88 |
-
if ( $paypal_enable || $paypal_email_is_set ) {
|
89 |
-
return true;
|
90 |
-
}
|
91 |
-
|
92 |
-
// Default this gateway to off.
|
93 |
-
return false;
|
94 |
-
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* @inheritDoc
|
98 |
-
*/
|
99 |
-
public function get_settings() {
|
100 |
-
/** @var Settings $settings */
|
101 |
-
$settings = tribe( Settings::class );
|
102 |
-
|
103 |
-
return $settings->get_settings();
|
104 |
-
}
|
105 |
-
|
106 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/Legacy/Provider.php
DELETED
@@ -1,97 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
*
|
4 |
-
* @todo This file is not being used currently but we need to remove this before we launch Tickets Commerce.
|
5 |
-
*
|
6 |
-
* @since 5.1.6
|
7 |
-
*
|
8 |
-
* @package TEC\Tickets\Commerce\Gateways\Legacy
|
9 |
-
*/
|
10 |
-
|
11 |
-
namespace TEC\Tickets\Commerce\Gateways\Legacy;
|
12 |
-
|
13 |
-
use tad_DI52_ServiceProvider;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Service provider for the Tickets Commerce: PayPal Standard (Legacy) gateway.
|
17 |
-
*
|
18 |
-
* @since 5.1.6
|
19 |
-
* @package Tribe\Tickets\Commerce\Tickets_Commerce\Gateways\PayPal_Legacy
|
20 |
-
*/
|
21 |
-
class Provider extends tad_DI52_ServiceProvider {
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Register the provider singletons.
|
25 |
-
*
|
26 |
-
* @since 5.1.6
|
27 |
-
*/
|
28 |
-
public function register() {
|
29 |
-
/**
|
30 |
-
* Allow filtering whether the PayPal Legacy classes should be registered.
|
31 |
-
*
|
32 |
-
* @since 5.1.6
|
33 |
-
*
|
34 |
-
* @param bool $should_register Whether the PayPal Legacy classes should be registered.
|
35 |
-
*/
|
36 |
-
$should_register = apply_filters( 'tribe_tickets_commerce_gateways_paypal_legacy_should_register', true );
|
37 |
-
|
38 |
-
// Check whether we should continue registering the gateway classes.
|
39 |
-
if ( false === $should_register ) {
|
40 |
-
return;
|
41 |
-
}
|
42 |
-
|
43 |
-
$this->container->singleton( Gateway::class );
|
44 |
-
$this->container->singleton( Settings::class );
|
45 |
-
|
46 |
-
// @todo Determine what is still needed for PayPal Commerce to function.
|
47 |
-
|
48 |
-
tribe_singleton( 'tickets.commerce.paypal.gateway', 'Tribe__Tickets__Commerce__PayPal__Gateway', [ 'build_handler' ] );
|
49 |
-
tribe_singleton( 'tickets.commerce.paypal.notices', 'Tribe__Tickets__Commerce__PayPal__Notices' );
|
50 |
-
tribe_singleton( 'tickets.commerce.paypal.endpoints', 'Tribe__Tickets__Commerce__PayPal__Endpoints', [ 'hook' ] );
|
51 |
-
tribe_singleton( 'tickets.commerce.paypal.endpoints.templates.success', 'Tribe__Tickets__Commerce__PayPal__Endpoints__Success_Template' );
|
52 |
-
tribe_singleton( 'tickets.commerce.paypal.orders.tabbed-view', 'Tribe__Tickets__Commerce__Orders_Tabbed_View' );
|
53 |
-
tribe_singleton( 'tickets.commerce.paypal.orders.report', 'Tribe__Tickets__Commerce__PayPal__Orders__Report' );
|
54 |
-
tribe_singleton( 'tickets.commerce.paypal.orders.sales', 'Tribe__Tickets__Commerce__PayPal__Orders__Sales' );
|
55 |
-
tribe_singleton( 'tickets.commerce.paypal.screen-options', 'Tribe__Tickets__Commerce__PayPal__Screen_Options', [ 'hook' ] );
|
56 |
-
tribe_singleton( 'tickets.commerce.paypal.stati', 'Tribe__Tickets__Commerce__PayPal__Stati' );
|
57 |
-
tribe_singleton( 'tickets.commerce.paypal.currency', 'Tribe__Tickets__Commerce__Currency', [ 'hook' ] );
|
58 |
-
tribe_singleton( 'tickets.commerce.paypal.links', 'Tribe__Tickets__Commerce__PayPal__Links' );
|
59 |
-
tribe_singleton( 'tickets.commerce.paypal.oversell.policies', 'Tribe__Tickets__Commerce__PayPal__Oversell__Policies' );
|
60 |
-
tribe_singleton( 'tickets.commerce.paypal.oversell.request', 'Tribe__Tickets__Commerce__PayPal__Oversell__Request' );
|
61 |
-
tribe_singleton( 'tickets.commerce.paypal.frontend.tickets-form', 'Tribe__Tickets__Commerce__PayPal__Frontend__Tickets_Form' );
|
62 |
-
tribe_register( 'tickets.commerce.paypal.cart', 'Tribe__Tickets__Commerce__PayPal__Cart__Unmanaged' );
|
63 |
-
|
64 |
-
tribe()->tag( [
|
65 |
-
'tickets.commerce.paypal.shortcodes.tpp-success' => 'Tribe__Tickets__Commerce__PayPal__Shortcodes__Success',
|
66 |
-
], 'tpp-shortcodes' );
|
67 |
-
|
68 |
-
$this->hooks();
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Add actions and filters.
|
73 |
-
*
|
74 |
-
* @since 5.1.6
|
75 |
-
*/
|
76 |
-
protected function hooks() {
|
77 |
-
add_filter( 'tec_tickets_commerce_gateways', [ $this, 'filter_add_gateway' ], 10, 2 );
|
78 |
-
|
79 |
-
add_action( 'init', tribe_callback( 'tickets.commerce.paypal.orders.report', 'hook' ) );
|
80 |
-
|
81 |
-
// @todo The add_shortcode stuff should be in an init action.
|
82 |
-
/** @var \Tribe__Tickets__Commerce__PayPal__Shortcodes__Interface $shortcode */
|
83 |
-
foreach ( tribe()->tagged( 'tpp-shortcodes' ) as $shortcode ) {
|
84 |
-
add_shortcode( $shortcode->tag(), [ $shortcode, 'render' ] );
|
85 |
-
}
|
86 |
-
|
87 |
-
tribe( 'tickets.commerce.paypal.gateway' );
|
88 |
-
tribe( 'tickets.commerce.paypal.orders.report' );
|
89 |
-
tribe( 'tickets.commerce.paypal.screen-options' );
|
90 |
-
tribe( 'tickets.commerce.paypal.endpoints' );
|
91 |
-
tribe( 'tickets.commerce.paypal.currency' );
|
92 |
-
}
|
93 |
-
|
94 |
-
public function filter_add_gateway( array $gateways = [] ) {
|
95 |
-
return $this->container->make( Gateway::class )->register_gateway( $gateways );
|
96 |
-
}
|
97 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/Legacy/Settings.php
DELETED
@@ -1,201 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
*
|
4 |
-
* @todo This file is not being used currently but we need to remove this before we launch Tickets Commerce.
|
5 |
-
*
|
6 |
-
* @since 5.1.6
|
7 |
-
*
|
8 |
-
* @package TEC\Tickets\Commerce\Gateways\Legacy
|
9 |
-
*/
|
10 |
-
|
11 |
-
namespace TEC\Tickets\Commerce\Gateways\Legacy;
|
12 |
-
|
13 |
-
use TEC\Tickets\Commerce\Abstract_Settings;
|
14 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models\MerchantDetail;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* The PayPal Standard (Legacy) specific settings.
|
18 |
-
*
|
19 |
-
* This class will contain all of the settings handling and admin settings config implementation from
|
20 |
-
* Tribe__Tickets__Commerce__PayPal__Main that is PayPal Standard (Legacy) specific.
|
21 |
-
*
|
22 |
-
* @since 5.1.6
|
23 |
-
* @package Tribe\Tickets\Commerce\Tickets_Commerce\Gateways\PayPal_Legacy
|
24 |
-
*/
|
25 |
-
class Settings extends Abstract_Settings {
|
26 |
-
|
27 |
-
/**
|
28 |
-
* The option key for email.
|
29 |
-
*
|
30 |
-
* @since 5.1.6
|
31 |
-
*
|
32 |
-
* @var string
|
33 |
-
*/
|
34 |
-
public $option_email = 'ticket-paypal-email';
|
35 |
-
|
36 |
-
/**
|
37 |
-
* The option key for IPN enabled.
|
38 |
-
*
|
39 |
-
* @since 5.1.6
|
40 |
-
*
|
41 |
-
* @var string
|
42 |
-
*/
|
43 |
-
public $option_ipn_enabled = 'ticket-paypal-ipn-enabled';
|
44 |
-
|
45 |
-
/**
|
46 |
-
* The option key for IPN address set.
|
47 |
-
*
|
48 |
-
* @since 5.1.6
|
49 |
-
*
|
50 |
-
* @var string
|
51 |
-
*/
|
52 |
-
public $option_ipn_address_set = 'ticket-paypal-ipn-address-set';
|
53 |
-
|
54 |
-
/**
|
55 |
-
* The option key for IPN notify URL.
|
56 |
-
*
|
57 |
-
* @since 5.1.6
|
58 |
-
*
|
59 |
-
* @var string
|
60 |
-
*/
|
61 |
-
public $option_ipn_notify_url = 'ticket-paypal-notify-url';
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Get the list of settings for the gateway.
|
65 |
-
*
|
66 |
-
* @since 5.1.6
|
67 |
-
*
|
68 |
-
* @return array The list of settings for the gateway.
|
69 |
-
*/
|
70 |
-
public function get_settings() {
|
71 |
-
$home_url = home_url();
|
72 |
-
|
73 |
-
// The KB article URL will change depending on whether ET+ is active or not.
|
74 |
-
$paypal_setup_kb_url = class_exists( 'Tribe__Tickets_Plus__Main' ) ? 'https://evnt.is/19yk' : 'https://evnt.is/19yj';
|
75 |
-
$paypal_setup_kb_link = sprintf(
|
76 |
-
'<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>',
|
77 |
-
esc_url( $paypal_setup_kb_url ),
|
78 |
-
esc_html__( 'these instructions', 'event-tickets' )
|
79 |
-
);
|
80 |
-
$paypal_setup_note = sprintf(
|
81 |
-
// Translators: %1$s: The word "ticket" in lowercase, %2$s: The "these instructions" link.
|
82 |
-
esc_html_x( 'Ie Tickets Commerce to sell %1$s, you must configure your PayPal account to communicate with your WordPress site. If you need help getting set up, follow %2$s', 'tickets fields settings PayPal setup', 'event-tickets' ),
|
83 |
-
esc_html( tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_setup' ) ),
|
84 |
-
$paypal_setup_kb_link
|
85 |
-
);
|
86 |
-
|
87 |
-
$ipn_setup_site_link = sprintf(
|
88 |
-
'<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>',
|
89 |
-
esc_url( $home_url ),
|
90 |
-
esc_html( $home_url )
|
91 |
-
);
|
92 |
-
$ipn_setup_site_address = sprintf(
|
93 |
-
// Translators: %s: The site link.
|
94 |
-
esc_html__( 'Your site address is: %s', 'event-tickets' ),
|
95 |
-
$ipn_setup_site_link
|
96 |
-
);
|
97 |
-
$ipn_setup_line = sprintf(
|
98 |
-
'<span class="clear">%s</span><span class="clear">%s</span>',
|
99 |
-
esc_html__( "Have you entered this site's address in the Notification URL field in IPN Settings?", 'event-tickets' ),
|
100 |
-
$ipn_setup_site_address
|
101 |
-
);
|
102 |
-
|
103 |
-
/** @var \Tribe__Tickets__Commerce__PayPal__Handler__IPN $ipn_handler */
|
104 |
-
$ipn_handler = tribe( 'tickets.commerce.paypal.handler.ipn' );
|
105 |
-
|
106 |
-
$ipn_config_status = sprintf(
|
107 |
-
'<strong>%1$s <span id="paypal-ipn-config-status" data-status="%2$s">%3$s</span></strong><p class="description"><i>%4$s</i></p>',
|
108 |
-
esc_html__( 'PayPal configuration status:', 'event-tickets' ),
|
109 |
-
esc_attr( $ipn_handler->get_config_status( 'slug' ) ),
|
110 |
-
esc_html( $ipn_handler->get_config_status( 'label' ) ),
|
111 |
-
esc_html__( 'For help creating and configuring your account, call PayPal at 1-844-720-4038 (USA)', 'event-tickets' )
|
112 |
-
);
|
113 |
-
|
114 |
-
$settings = [
|
115 |
-
'ticket-paypal-configure' => [
|
116 |
-
'type' => 'wrapped_html',
|
117 |
-
'label' => esc_html__( 'Configure PayPal Legacy:', 'event-tickets' ),
|
118 |
-
'html' => '<p>' . $paypal_setup_note . '</p>',
|
119 |
-
'validation_type' => 'html',
|
120 |
-
],
|
121 |
-
$this->option_email => [
|
122 |
-
'type' => 'email',
|
123 |
-
'label' => esc_html__( 'PayPal email to receive payments:', 'event-tickets' ),
|
124 |
-
'size' => 'large',
|
125 |
-
'default' => '',
|
126 |
-
'validation_type' => 'email',
|
127 |
-
'class' => 'indent light-bordered checkmark checkmark-right checkmark-hide ipn-required',
|
128 |
-
],
|
129 |
-
$this->option_ipn_enabled => [
|
130 |
-
'type' => 'radio',
|
131 |
-
'label' => esc_html__( "Have you enabled instant payment notifications (IPN) in your PayPal account's Selling Tools?", 'event-tickets' ),
|
132 |
-
'options' => [
|
133 |
-
'yes' => __( 'Yes', 'event-tickets' ),
|
134 |
-
'no' => __( 'No', 'event-tickets' ),
|
135 |
-
],
|
136 |
-
'size' => 'large',
|
137 |
-
'default' => 'no',
|
138 |
-
'validation_type' => 'options',
|
139 |
-
'class' => 'indent light-bordered checkmark checkmark-right checkmark-hide ipn-required',
|
140 |
-
],
|
141 |
-
$this->option_ipn_address_set => [
|
142 |
-
'type' => 'radio',
|
143 |
-
'label' => $ipn_setup_line,
|
144 |
-
'options' => [
|
145 |
-
'yes' => __( 'Yes', 'event-tickets' ),
|
146 |
-
'no' => __( 'No', 'event-tickets' ),
|
147 |
-
],
|
148 |
-
'size' => 'large',
|
149 |
-
'default' => 'no',
|
150 |
-
'validation_type' => 'options',
|
151 |
-
'class' => 'indent light-bordered checkmark checkmark-right checkmark-hide ipn-required',
|
152 |
-
],
|
153 |
-
'ticket-paypal-ipn-config-status' => [
|
154 |
-
'type' => 'wrapped_html',
|
155 |
-
'html' => $ipn_config_status,
|
156 |
-
'size' => 'large',
|
157 |
-
'default' => 'no',
|
158 |
-
'validation_type' => 'html',
|
159 |
-
'class' => 'indent light-bordered',
|
160 |
-
],
|
161 |
-
];
|
162 |
-
|
163 |
-
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
164 |
-
/** @var \Tribe__Tickets__Commerce__PayPal__Links $paypal_links */
|
165 |
-
$paypal_links = tribe( 'tickets.commerce.paypal.links' );
|
166 |
-
|
167 |
-
$ipn_notify_note = sprintf(
|
168 |
-
// Translators: %s: The PayPal notification history link.
|
169 |
-
esc_html__( 'You can see and manage your IPN Notifications history from the IPN Notifications settings area (%s).', 'event-tickets' ),
|
170 |
-
// The following string is returned already escaped.
|
171 |
-
$paypal_links->ipn_notification_history( 'tag' )
|
172 |
-
);
|
173 |
-
|
174 |
-
$ipn_notify_url_tooltip = sprintf(
|
175 |
-
// Translators: %s: The PayPal notification settings link.
|
176 |
-
esc_html__( 'Override the default IPN notify URL with this value. This value must be the same set in PayPal IPN Notifications settings area (%s).', 'event-tickets' ),
|
177 |
-
// The following string is returned already escaped.
|
178 |
-
$paypal_links->ipn_notification_settings( 'tag' )
|
179 |
-
);
|
180 |
-
|
181 |
-
$settings['ticket-paypal-notify-history'] = [
|
182 |
-
'type' => 'wrapped_html',
|
183 |
-
'html' => '<p>' . $ipn_notify_note . '</p>',
|
184 |
-
'size' => 'medium',
|
185 |
-
'validation_type' => 'html',
|
186 |
-
'class' => 'indent light-bordered',
|
187 |
-
];
|
188 |
-
|
189 |
-
$settings[ $this->option_ipn_notify_url ] = [
|
190 |
-
'type' => 'text',
|
191 |
-
'label' => esc_html__( 'IPN Notify URL', 'event-tickets' ),
|
192 |
-
'tooltip' => $ipn_notify_url_tooltip,
|
193 |
-
'default' => $home_url,
|
194 |
-
'validation_type' => 'html',
|
195 |
-
];
|
196 |
-
}
|
197 |
-
|
198 |
-
return $settings;
|
199 |
-
}
|
200 |
-
|
201 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/Manager.php
CHANGED
@@ -42,7 +42,7 @@ class Manager {
|
|
42 |
*
|
43 |
* @since 5.1.6
|
44 |
*
|
45 |
-
* @return
|
46 |
*/
|
47 |
public function get_gateways() {
|
48 |
/**
|
@@ -53,7 +53,7 @@ class Manager {
|
|
53 |
*
|
54 |
* @since 5.1.6
|
55 |
*
|
56 |
-
* @param
|
57 |
*/
|
58 |
return (array) apply_filters( 'tec_tickets_commerce_gateways', [] );
|
59 |
}
|
@@ -66,7 +66,7 @@ class Manager {
|
|
66 |
* @return string The current Tickets Commerce gateway.
|
67 |
*/
|
68 |
public function get_current_gateway() {
|
69 |
-
$default =
|
70 |
|
71 |
if ( ! $this->should_show_legacy() ) {
|
72 |
$default = PayPal\Gateway::get_key();
|
@@ -74,4 +74,47 @@ class Manager {
|
|
74 |
|
75 |
return (string) tribe_get_option( static::$option_gateway, $default );
|
76 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
42 |
*
|
43 |
* @since 5.1.6
|
44 |
*
|
45 |
+
* @return Abstract_Gateway[] The list of registered Tickets Commerce gateways.
|
46 |
*/
|
47 |
public function get_gateways() {
|
48 |
/**
|
53 |
*
|
54 |
* @since 5.1.6
|
55 |
*
|
56 |
+
* @param Abstract_Gateway[] $gateways The list of registered Tickets Commerce gateways.
|
57 |
*/
|
58 |
return (array) apply_filters( 'tec_tickets_commerce_gateways', [] );
|
59 |
}
|
66 |
* @return string The current Tickets Commerce gateway.
|
67 |
*/
|
68 |
public function get_current_gateway() {
|
69 |
+
$default = null;
|
70 |
|
71 |
if ( ! $this->should_show_legacy() ) {
|
72 |
$default = PayPal\Gateway::get_key();
|
74 |
|
75 |
return (string) tribe_get_option( static::$option_gateway, $default );
|
76 |
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Get the gateway settings from all gateways.
|
80 |
+
*
|
81 |
+
* @since 5.1.9
|
82 |
+
*
|
83 |
+
* @return array[]
|
84 |
+
*/
|
85 |
+
public function get_gateway_settings() {
|
86 |
+
$gateways = $this->get_gateways();
|
87 |
+
|
88 |
+
$gateway_setting_groups = [];
|
89 |
+
|
90 |
+
// Get all of the gateway settings.
|
91 |
+
foreach ( $gateways as $gateway_key => $gateway ) {
|
92 |
+
if ( ! $gateway::should_show() ) {
|
93 |
+
continue;
|
94 |
+
}
|
95 |
+
|
96 |
+
// Get the gateway settings.
|
97 |
+
$gateway_settings = $gateway->get_settings();
|
98 |
+
|
99 |
+
// If there are no gateway settings, don't show this section at all.
|
100 |
+
if ( empty( $gateway_settings ) ) {
|
101 |
+
continue;
|
102 |
+
}
|
103 |
+
|
104 |
+
$heading = [
|
105 |
+
'tickets-commerce-' . $gateway_key => [
|
106 |
+
'type' => 'wrapped_html',
|
107 |
+
'html' => '<h3 class="event-tickets--admin_settings_subheading">' . $gateway::get_label() . '</h3>',
|
108 |
+
'validation_type' => 'html',
|
109 |
+
],
|
110 |
+
];
|
111 |
+
|
112 |
+
// Add the gateway label to the start of settings.
|
113 |
+
$gateway_setting_groups[] = $heading;
|
114 |
+
|
115 |
+
$gateway_setting_groups[] = $gateway_settings;
|
116 |
+
}
|
117 |
+
|
118 |
+
return array_merge( ...$gateway_setting_groups );
|
119 |
+
}
|
120 |
}
|
src/Tickets/Commerce/Gateways/PayPal/AjaxRequestHandler.php
DELETED
@@ -1,316 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
-
|
5 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models\MerchantDetail;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\PayPalAuth;
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\PayPalOrder;
|
8 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\RefreshToken;
|
9 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\MerchantDetails;
|
10 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\Webhooks;
|
11 |
-
|
12 |
-
// @todo Bring this over.
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Class AjaxRequestHandler
|
16 |
-
*
|
17 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
18 |
-
*
|
19 |
-
* @since 5.1.6
|
20 |
-
*/
|
21 |
-
class AjaxRequestHandler {
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @since 5.1.6
|
25 |
-
*
|
26 |
-
* @var Webhooks
|
27 |
-
*/
|
28 |
-
private $webhooksRepository;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* @since 5.1.6
|
32 |
-
*
|
33 |
-
* @var MerchantDetail
|
34 |
-
*/
|
35 |
-
private $merchantDetails;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* @since 5.1.6
|
39 |
-
*
|
40 |
-
* @var PayPalAuth
|
41 |
-
*/
|
42 |
-
private $payPalAuth;
|
43 |
-
|
44 |
-
/**
|
45 |
-
* @since 5.1.6
|
46 |
-
*
|
47 |
-
* @var MerchantDetails
|
48 |
-
*/
|
49 |
-
private $merchantRepository;
|
50 |
-
|
51 |
-
/**
|
52 |
-
* @since 5.1.6
|
53 |
-
*
|
54 |
-
* @var Connect_Client
|
55 |
-
*/
|
56 |
-
private $refreshToken;
|
57 |
-
|
58 |
-
/**
|
59 |
-
* @since 5.1.6
|
60 |
-
*
|
61 |
-
* @var Settings
|
62 |
-
*/
|
63 |
-
private $settings;
|
64 |
-
|
65 |
-
/**
|
66 |
-
* AjaxRequestHandler constructor.
|
67 |
-
*
|
68 |
-
* @since 5.1.6
|
69 |
-
*
|
70 |
-
* @param Webhooks $webhooksRepository
|
71 |
-
* @param MerchantDetail $merchantDetails
|
72 |
-
* @param MerchantDetails $merchantRepository
|
73 |
-
* @param RefreshToken $refreshToken
|
74 |
-
* @param Settings $settings
|
75 |
-
* @param PayPalAuth $payPalAuth
|
76 |
-
*/
|
77 |
-
public function __construct(
|
78 |
-
Webhooks $webhooksRepository,
|
79 |
-
MerchantDetail $merchantDetails,
|
80 |
-
MerchantDetails $merchantRepository,
|
81 |
-
RefreshToken $refreshToken,
|
82 |
-
Settings $settings,
|
83 |
-
PayPalAuth $payPalAuth
|
84 |
-
) {
|
85 |
-
$this->webhooksRepository = $webhooksRepository;
|
86 |
-
$this->merchantDetails = $merchantDetails;
|
87 |
-
$this->merchantRepository = $merchantRepository;
|
88 |
-
$this->refreshToken = $refreshToken;
|
89 |
-
$this->settings = $settings;
|
90 |
-
$this->payPalAuth = $payPalAuth;
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* give_paypal_commerce_user_onboarded ajax action handler
|
95 |
-
*
|
96 |
-
* @since 5.1.6
|
97 |
-
*/
|
98 |
-
public function onBoardedUserAjaxRequestHandler() {
|
99 |
-
$this->validateAdminRequest();
|
100 |
-
|
101 |
-
$partnerLinkInfo = $this->settings->get_partner_link_details();
|
102 |
-
|
103 |
-
$payPalResponse = $this->payPalAuth->getTokenFromAuthorizationCode(
|
104 |
-
tribe_get_request_var( 'sharedId' ),
|
105 |
-
tribe_get_request_var( 'authCode' ),
|
106 |
-
$partnerLinkInfo['nonce']
|
107 |
-
);
|
108 |
-
|
109 |
-
if ( ! $payPalResponse || array_key_exists( 'error', $payPalResponse ) ) {
|
110 |
-
wp_send_json_error( __( 'Unexpected response from PayPal when onboarding', 'event-tickets' ) );
|
111 |
-
}
|
112 |
-
|
113 |
-
$this->settings->update_access_token( $payPalResponse );
|
114 |
-
|
115 |
-
tribe( RefreshToken::class )->registerCronJobToRefreshToken( $payPalResponse['expires_in'] );
|
116 |
-
|
117 |
-
wp_send_json_success( __( 'PayPal account onboarded', 'event-tickets' ) );
|
118 |
-
}
|
119 |
-
|
120 |
-
/**
|
121 |
-
* give_paypal_commerce_get_partner_url action handler
|
122 |
-
*
|
123 |
-
* @since 5.1.6
|
124 |
-
*/
|
125 |
-
public function onGetPartnerUrlAjaxRequestHandler() {
|
126 |
-
$this->validateAdminRequest();
|
127 |
-
|
128 |
-
$country_code = tribe_get_request_var( 'countryCode' );
|
129 |
-
|
130 |
-
/** @var \Tribe__Languages__Locations $locations */
|
131 |
-
$locations = tribe( 'languages.locations' );
|
132 |
-
$countries = $locations->get_countries();
|
133 |
-
|
134 |
-
// Check for a valid country.
|
135 |
-
if ( empty( $country_code ) || ! isset( $countries[ $country_code ] ) ) {
|
136 |
-
wp_send_json_error( __( 'Must include valid 2-character country code', 'event-tickets' ) );
|
137 |
-
}
|
138 |
-
|
139 |
-
/** @var Tribe__Settings $settings */
|
140 |
-
$settings = tribe( 'settings' );
|
141 |
-
|
142 |
-
// Get link to Tickets Tab.
|
143 |
-
$settings_url = $settings->get_url( [
|
144 |
-
'page' => 'tribe-common',
|
145 |
-
'tab' => 'event-tickets',
|
146 |
-
'tickets-commerce-connected' => '1',
|
147 |
-
] );
|
148 |
-
|
149 |
-
// @todo They ultimately need to get here.
|
150 |
-
// . '#tribe-field-tickets-commerce-paypal-commerce';
|
151 |
-
|
152 |
-
$partner_link_details = $this->payPalAuth->getSellerPartnerLink(
|
153 |
-
// @todo Replace this URL.
|
154 |
-
$settings_url,
|
155 |
-
$country_code
|
156 |
-
);
|
157 |
-
|
158 |
-
if ( ! $partner_link_details ) {
|
159 |
-
wp_send_json_error( __( 'Partner details not found', 'event-tickets' ) );
|
160 |
-
}
|
161 |
-
|
162 |
-
$this->settings->update_account_country( $country_code );
|
163 |
-
$this->settings->update_partner_link_details( $partner_link_details );
|
164 |
-
|
165 |
-
wp_send_json_success( $partner_link_details );
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* give_paypal_commerce_disconnect_account ajax request handler.
|
170 |
-
*
|
171 |
-
* @since 5.1.6
|
172 |
-
*/
|
173 |
-
public function removePayPalAccount() {
|
174 |
-
$this->validateAdminRequest();
|
175 |
-
|
176 |
-
// Remove the webhook from PayPal if there is one
|
177 |
-
if ( $webhookConfig = $this->webhooksRepository->getWebhookConfig() ) {
|
178 |
-
$this->webhooksRepository->deleteWebhook( $this->merchantDetails->accessToken, $webhookConfig->id );
|
179 |
-
$this->webhooksRepository->deleteWebhookConfig();
|
180 |
-
}
|
181 |
-
|
182 |
-
$this->merchantRepository->delete();
|
183 |
-
$this->merchantRepository->deleteAccountErrors();
|
184 |
-
$this->merchantRepository->deleteClientToken();
|
185 |
-
$this->refreshToken->deleteRefreshTokenCronJob();
|
186 |
-
|
187 |
-
wp_send_json_success( __( 'PayPal account disconnected', 'event-tickets' ) );
|
188 |
-
}
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Create order.
|
192 |
-
*
|
193 |
-
* @since 5.1.6
|
194 |
-
* @todo : handle payment create error on frontend.
|
195 |
-
*
|
196 |
-
*/
|
197 |
-
public function createOrder() {
|
198 |
-
// @todo Set up the order with our own custom code.
|
199 |
-
|
200 |
-
$this->validateFrontendRequest();
|
201 |
-
|
202 |
-
$postData = give_clean( $_POST );
|
203 |
-
$formId = absint( tribe_get_request_var( 'give-form-id' ) );
|
204 |
-
|
205 |
-
$data = [
|
206 |
-
'formId' => $formId,
|
207 |
-
'formTitle' => give_payment_gateway_item_title( [ 'post_data' => $postData ], 127 ),
|
208 |
-
'paymentAmount' => isset( $postData['give-amount'] ) ? (float) apply_filters( 'give_payment_total', give_maybe_sanitize_amount( $postData['give-amount'], [ 'currency' => give_get_currency( $formId ) ] ) ) : '0.00',
|
209 |
-
'payer' => [
|
210 |
-
'firstName' => $postData['give_first'],
|
211 |
-
'lastName' => $postData['give_last'],
|
212 |
-
'email' => $postData['give_email'],
|
213 |
-
],
|
214 |
-
'application_context' => [
|
215 |
-
'shipping_preference' => 'NO_SHIPPING',
|
216 |
-
],
|
217 |
-
];
|
218 |
-
|
219 |
-
try {
|
220 |
-
$result = tribe( PayPalOrder::class )->createOrder( $data );
|
221 |
-
|
222 |
-
wp_send_json_success(
|
223 |
-
[
|
224 |
-
'id' => $result,
|
225 |
-
]
|
226 |
-
);
|
227 |
-
} catch ( \Exception $ex ) {
|
228 |
-
wp_send_json_error(
|
229 |
-
[
|
230 |
-
'error' => json_decode( $ex->getMessage(), true ),
|
231 |
-
]
|
232 |
-
);
|
233 |
-
}
|
234 |
-
}
|
235 |
-
|
236 |
-
/**
|
237 |
-
* Approve order.
|
238 |
-
*
|
239 |
-
* @since 5.1.6
|
240 |
-
* @todo : handle payment capture error on frontend.
|
241 |
-
*
|
242 |
-
*/
|
243 |
-
public function approveOrder() {
|
244 |
-
$this->validateFrontendRequest();
|
245 |
-
|
246 |
-
$orderId = absint( tribe_get_request_var( 'order' ) );
|
247 |
-
|
248 |
-
// @todo Handle our own order approval process.
|
249 |
-
|
250 |
-
try {
|
251 |
-
$result = tribe( PayPalOrder::class )->approveOrder( $orderId );
|
252 |
-
|
253 |
-
wp_send_json_success(
|
254 |
-
[
|
255 |
-
'order' => $result,
|
256 |
-
]
|
257 |
-
);
|
258 |
-
} catch ( \Exception $ex ) {
|
259 |
-
wp_send_json_error(
|
260 |
-
[
|
261 |
-
'error' => json_decode( $ex->getMessage(), true ),
|
262 |
-
]
|
263 |
-
);
|
264 |
-
}
|
265 |
-
}
|
266 |
-
|
267 |
-
/**
|
268 |
-
* Return on boarding trouble notice.
|
269 |
-
*
|
270 |
-
* @since 5.1.6
|
271 |
-
*/
|
272 |
-
public function onBoardingTroubleNotice() {
|
273 |
-
$this->validateAdminRequest();
|
274 |
-
|
275 |
-
$actionList = sprintf(
|
276 |
-
'<ol><li>%1$s</li><li>%2$s</li><li>%3$s %4$s</li></ol>',
|
277 |
-
esc_html__( 'Make sure to complete the entire PayPal process. Do not close the window you have finished the process.', 'event-tickets' ),
|
278 |
-
esc_html__( 'The last screen of the PayPal connect process includes a button to be sent back to your site. It is important you click this and do not close the window yourself.', 'event-tickets' ),
|
279 |
-
esc_html__( 'If you’re still having problems connecting:', 'event-tickets' ),
|
280 |
-
$this->settings->get_guidance_html()
|
281 |
-
);
|
282 |
-
|
283 |
-
$standardError = sprintf(
|
284 |
-
'<div id="give-paypal-onboarding-trouble-notice" class="tribe-common-a11y-hidden"><p class="error-message">%1$s</p><p>%2$s</p></div>',
|
285 |
-
esc_html__( 'Having trouble connecting to PayPal?', 'event-tickets' ),
|
286 |
-
$actionList
|
287 |
-
);
|
288 |
-
|
289 |
-
wp_send_json_success( $standardError );
|
290 |
-
}
|
291 |
-
|
292 |
-
/**
|
293 |
-
* Validate admin ajax request.
|
294 |
-
*
|
295 |
-
* @since 5.1.6
|
296 |
-
*/
|
297 |
-
private function validateAdminRequest() {
|
298 |
-
// @todo Add our own capacity check.
|
299 |
-
if ( ! current_user_can( 'manage_options' ) ) {
|
300 |
-
wp_send_json_error( __( 'Access not allowed', 'event-tickets' ), 401 );
|
301 |
-
}
|
302 |
-
}
|
303 |
-
|
304 |
-
/**
|
305 |
-
* Validate frontend ajax request.
|
306 |
-
*
|
307 |
-
* @since 5.1.6
|
308 |
-
*/
|
309 |
-
private function validateFrontendRequest() {
|
310 |
-
$formId = absint( $_POST['give-form-id'] );
|
311 |
-
|
312 |
-
if ( ! $formId || ! give_verify_payment_form_nonce( give_clean( $_POST['give-form-hash'] ), $formId ) ) {
|
313 |
-
wp_die();
|
314 |
-
}
|
315 |
-
}
|
316 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/Ajax_Request_Handler.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Repositories\Order;
|
6 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Repositories\Webhooks;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Ajax_Request_Handler
|
10 |
+
*
|
11 |
+
* @todo This whole file will stop exsiting once we deprecate all Give's code usage.
|
12 |
+
*
|
13 |
+
* @since 5.1.6
|
14 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
15 |
+
*
|
16 |
+
*/
|
17 |
+
class Ajax_Request_Handler {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Return on boarding trouble notice.
|
21 |
+
*
|
22 |
+
* @TODO this method needs to be completely refactored into an admin page action.
|
23 |
+
*
|
24 |
+
* @since 5.1.6
|
25 |
+
*/
|
26 |
+
public function on_boarding_trouble_notice() {
|
27 |
+
|
28 |
+
$action_list = sprintf(
|
29 |
+
'<ol><li>%1$s</li><li>%2$s</li><li>%3$s %4$s</li></ol>',
|
30 |
+
esc_html__( 'Make sure to complete the entire PayPal process. Do not close the window you have finished the process.', 'event-tickets' ),
|
31 |
+
esc_html__( 'The last screen of the PayPal connect process includes a button to be sent back to your site. It is important you click this and do not close the window yourself.', 'event-tickets' ),
|
32 |
+
esc_html__( 'If you’re still having problems connecting:', 'event-tickets' ),
|
33 |
+
$this->settings->get_guidance_html()
|
34 |
+
);
|
35 |
+
|
36 |
+
$standard_error = sprintf(
|
37 |
+
'<div id="give-paypal-onboarding-trouble-notice" class="tribe-common-a11y-hidden"><p class="error-message">%1$s</p><p>%2$s</p></div>',
|
38 |
+
esc_html__( 'Having trouble connecting to PayPal?', 'event-tickets' ),
|
39 |
+
$action_list
|
40 |
+
);
|
41 |
+
|
42 |
+
wp_send_json_success( $standard_error );
|
43 |
+
}
|
44 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Assets.php
CHANGED
@@ -2,17 +2,19 @@
|
|
2 |
/**
|
3 |
* Handles registering and setup for assets on Ticket Commerce.
|
4 |
*
|
5 |
-
* @since
|
6 |
*
|
7 |
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
8 |
*/
|
9 |
|
10 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
11 |
|
|
|
|
|
12 |
/**
|
13 |
* Class Assets.
|
14 |
*
|
15 |
-
* @since
|
16 |
*
|
17 |
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
18 |
*/
|
@@ -24,8 +26,9 @@ class Assets extends \tad_DI52_ServiceProvider {
|
|
24 |
* @since 5.1.6
|
25 |
*/
|
26 |
public function register() {
|
|
|
27 |
tribe_asset(
|
28 |
-
|
29 |
'tribe-tickets-admin-commerce-paypal-commerce-partner-js',
|
30 |
$this->get_partner_js_url(),
|
31 |
[],
|
@@ -64,6 +67,32 @@ class Assets extends \tad_DI52_ServiceProvider {
|
|
64 |
],
|
65 |
]
|
66 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
}
|
68 |
|
69 |
/**
|
@@ -74,12 +103,11 @@ class Assets extends \tad_DI52_ServiceProvider {
|
|
74 |
* @return string
|
75 |
*/
|
76 |
private function get_partner_js_url() {
|
77 |
-
|
78 |
-
$client = tribe( SDK\PayPalClient::class );
|
79 |
|
80 |
return sprintf(
|
81 |
'%1$swebapps/merchantboarding/js/lib/lightbox/partner.js',
|
82 |
-
$client->
|
83 |
);
|
84 |
}
|
85 |
}
|
2 |
/**
|
3 |
* Handles registering and setup for assets on Ticket Commerce.
|
4 |
*
|
5 |
+
* @since 5.1.6
|
6 |
*
|
7 |
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
8 |
*/
|
9 |
|
10 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
11 |
|
12 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\REST\Order_Endpoint;
|
13 |
+
|
14 |
/**
|
15 |
* Class Assets.
|
16 |
*
|
17 |
+
* @since 5.1.6
|
18 |
*
|
19 |
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
20 |
*/
|
26 |
* @since 5.1.6
|
27 |
*/
|
28 |
public function register() {
|
29 |
+
$plugin = \Tribe__Tickets__Main::instance();
|
30 |
tribe_asset(
|
31 |
+
$plugin,
|
32 |
'tribe-tickets-admin-commerce-paypal-commerce-partner-js',
|
33 |
$this->get_partner_js_url(),
|
34 |
[],
|
67 |
],
|
68 |
]
|
69 |
);
|
70 |
+
|
71 |
+
|
72 |
+
tribe_asset(
|
73 |
+
$plugin,
|
74 |
+
'tec-tickets-commerce-gateway-paypal-checkout',
|
75 |
+
'commerce/gateway/paypal/checkout.js',
|
76 |
+
[
|
77 |
+
'jquery',
|
78 |
+
'tribe-common',
|
79 |
+
],
|
80 |
+
null,
|
81 |
+
[
|
82 |
+
'groups' => [
|
83 |
+
'tec-tickets-commerce-gateway-paypal',
|
84 |
+
],
|
85 |
+
'localize' => [
|
86 |
+
'name' => 'tecTicketsCommerceGatewayPayPalCheckout',
|
87 |
+
'data' => static function () {
|
88 |
+
return [
|
89 |
+
'orderEndpoint' => tribe( Order_Endpoint::class )->get_route_url(),
|
90 |
+
];
|
91 |
+
},
|
92 |
+
],
|
93 |
+
]
|
94 |
+
);
|
95 |
+
|
96 |
}
|
97 |
|
98 |
/**
|
103 |
* @return string
|
104 |
*/
|
105 |
private function get_partner_js_url() {
|
106 |
+
$client = tribe( Client::class );
|
|
|
107 |
|
108 |
return sprintf(
|
109 |
'%1$swebapps/merchantboarding/js/lib/lightbox/partner.js',
|
110 |
+
$client->get_home_page_url()
|
111 |
);
|
112 |
}
|
113 |
}
|
src/Tickets/Commerce/Gateways/PayPal/Buttons.php
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
|
5 |
+
use Tribe__Utils__Array as Arr;
|
6 |
+
use TEC\Tickets\Commerce\Module;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Buttons
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
14 |
+
*/
|
15 |
+
class Buttons {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Stores the instance of the template engine that we will use for rendering the elements.
|
19 |
+
*
|
20 |
+
* @since 5.1.9
|
21 |
+
*
|
22 |
+
* @var \Tribe__Template
|
23 |
+
*/
|
24 |
+
protected $template;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Gets the template instance used to setup the rendering of the page.
|
28 |
+
*
|
29 |
+
* @since 5.1.9
|
30 |
+
*
|
31 |
+
* @return \Tribe__Template
|
32 |
+
*/
|
33 |
+
public function get_template() {
|
34 |
+
if ( empty( $this->template ) ) {
|
35 |
+
$this->template = new \Tribe__Template();
|
36 |
+
$this->template->set_template_origin( \Tribe__Tickets__Main::instance() );
|
37 |
+
$this->template->set_template_folder( 'src/views/v2/commerce/gateway/paypal' );
|
38 |
+
$this->template->set_template_context_extract( true );
|
39 |
+
$this->template->set_template_folder_lookup( true );
|
40 |
+
}
|
41 |
+
|
42 |
+
return $this->template;
|
43 |
+
}
|
44 |
+
|
45 |
+
public function get_checkout_script() {
|
46 |
+
$client = tribe( Client::class );
|
47 |
+
$client_token_data = $client->get_client_token();
|
48 |
+
$must_login = ! is_user_logged_in() && tribe( Module::class )->login_required();
|
49 |
+
$template_vars = [
|
50 |
+
'url' => $client->get_js_sdk_url(),
|
51 |
+
'attribution_id' => Gateway::ATTRIBUTION_ID,
|
52 |
+
'client_token' => Arr::get( $client_token_data, 'client_token' ),
|
53 |
+
'client_token_expires_in' => Arr::get( $client_token_data, 'expires_in' ),
|
54 |
+
'must_login' => $must_login,
|
55 |
+
];
|
56 |
+
|
57 |
+
tribe_asset_enqueue( 'tec-tickets-commerce-gateway-paypal-checkout' );
|
58 |
+
|
59 |
+
return $this->get_template()->template( 'checkout-script', $template_vars, false );
|
60 |
+
}
|
61 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Client.php
ADDED
@@ -0,0 +1,498 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
|
5 |
+
use Tribe__Utils__Array as Arr;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Client
|
9 |
+
*
|
10 |
+
* @since 5.1.6
|
11 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
12 |
+
*
|
13 |
+
*/
|
14 |
+
class Client {
|
15 |
+
/**
|
16 |
+
* Get environment base URL.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @return string
|
21 |
+
*/
|
22 |
+
public function get_environment_url() {
|
23 |
+
$merchant = tribe( Merchant::class );
|
24 |
+
|
25 |
+
return $merchant->is_sandbox() ?
|
26 |
+
'https://api.sandbox.paypal.com' :
|
27 |
+
'https://api.paypal.com';
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Safely checks if we have an access token to be used.
|
32 |
+
*
|
33 |
+
* @since 5.1.9
|
34 |
+
*
|
35 |
+
* @return string
|
36 |
+
*/
|
37 |
+
public function get_access_token() {
|
38 |
+
return tribe( Merchant::class )->get_access_token();
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Get REST API endpoint URL for requests.
|
43 |
+
*
|
44 |
+
* @since 5.1.9
|
45 |
+
*
|
46 |
+
*
|
47 |
+
* @param string $endpoint The endpoint path.
|
48 |
+
* @param array $query_args Query args appended to the URL.
|
49 |
+
*
|
50 |
+
* @return string The API URL.
|
51 |
+
*
|
52 |
+
*/
|
53 |
+
public function get_api_url( $endpoint, array $query_args = [] ) {
|
54 |
+
$base_url = $this->get_environment_url();
|
55 |
+
$endpoint = ltrim( $endpoint, '/' );
|
56 |
+
|
57 |
+
return add_query_arg( $query_args, "{$base_url}/{$endpoint}" );
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Fetches the JS SDK url.
|
62 |
+
*
|
63 |
+
* We use something like: https://www.paypal.com/sdk/js?client-id=sb&locale=en_US&components=buttons
|
64 |
+
*
|
65 |
+
* @since 5.1.9
|
66 |
+
*
|
67 |
+
* @param array $query_args Which query args will be added.
|
68 |
+
*
|
69 |
+
* @return string
|
70 |
+
*/
|
71 |
+
public function get_js_sdk_url( array $query_args = [] ) {
|
72 |
+
$url = 'https://www.paypal.com/sdk/js';
|
73 |
+
$merchant = tribe( Merchant::class );
|
74 |
+
$query_args = array_merge( [
|
75 |
+
'client-id' => $merchant->is_sandbox() ? 'sb' : $merchant->get_client_id(),
|
76 |
+
'merchant-id' => $merchant->get_merchant_id_in_paypal(),
|
77 |
+
'components' => 'buttons,hosted-fields',
|
78 |
+
'intent' => 'capture',
|
79 |
+
'currency' => tribe_get_option( \TEC\Tickets\Commerce\Settings::$option_currency_code, 'USD' ),
|
80 |
+
], $query_args );
|
81 |
+
$url = add_query_arg( $query_args, $url );
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Filter the PayPal JS SDK url.
|
85 |
+
*
|
86 |
+
* @since 5.1.9
|
87 |
+
*
|
88 |
+
* @param string $url Which URL we are going to use to load the SDK JS.
|
89 |
+
* @param array $query_args Which URL args will be added to the JS SDK url.
|
90 |
+
*/
|
91 |
+
return apply_filters( 'tec_tickets_commerce_gateway_paypal_js_sdk_url', $url, $query_args );
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Get PayPal homepage url.
|
96 |
+
*
|
97 |
+
* @since 5.1.6
|
98 |
+
*
|
99 |
+
* @return string
|
100 |
+
*/
|
101 |
+
public function get_home_page_url() {
|
102 |
+
$subdomain = tribe( Merchant::class )->is_sandbox() ? 'sandbox.' : '';
|
103 |
+
|
104 |
+
return sprintf(
|
105 |
+
'https://%1$spaypal.com/',
|
106 |
+
$subdomain
|
107 |
+
);
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Send a GET request to the PayPal API.
|
112 |
+
*
|
113 |
+
* @since 5.1.9
|
114 |
+
*
|
115 |
+
* @param string $endpoint
|
116 |
+
* @param array $query_args
|
117 |
+
* @param array $request_arguments
|
118 |
+
*
|
119 |
+
* @return array|null
|
120 |
+
*/
|
121 |
+
public function get( $endpoint, array $query_args = [], array $request_arguments = [] ) {
|
122 |
+
// If the endpoint passed is a full URL dont try to append anything.
|
123 |
+
$url = 0 !== strpos( 'https://', $endpoint )
|
124 |
+
? $this->get_api_url( $endpoint, $query_args )
|
125 |
+
: add_query_arg( $query_args, $endpoint );
|
126 |
+
|
127 |
+
$default_arguments = [
|
128 |
+
'headers' => [
|
129 |
+
'Accept' => 'application/json',
|
130 |
+
'Authorization' => sprintf( 'Bearer %1$s', $this->get_access_token() ),
|
131 |
+
'Content-Type' => 'application/json',
|
132 |
+
]
|
133 |
+
];
|
134 |
+
foreach ( $default_arguments as $key => $default_argument ) {
|
135 |
+
$request_arguments[ $key ] = array_merge( $default_argument, Arr::get( $request_arguments, $key, [] ) );
|
136 |
+
}
|
137 |
+
$response = wp_remote_get( $url, $request_arguments );
|
138 |
+
|
139 |
+
if ( is_wp_error( $response ) ) {
|
140 |
+
tribe( 'logger' )->log_error( sprintf(
|
141 |
+
'[%s] PayPal GET request error: %s',
|
142 |
+
$url,
|
143 |
+
$response->get_error_message()
|
144 |
+
), 'tickets-commerce-paypal' );
|
145 |
+
|
146 |
+
return null;
|
147 |
+
}
|
148 |
+
|
149 |
+
$response_code = wp_remote_retrieve_response_code( $response );
|
150 |
+
|
151 |
+
// When we receive an error code we return the whole response.
|
152 |
+
if ( ! in_array( $response_code, [ 200, 201, 202, 204 ], true ) ) {
|
153 |
+
return $response;
|
154 |
+
}
|
155 |
+
|
156 |
+
$response = wp_remote_retrieve_body( $response );
|
157 |
+
$response = @json_decode( $response, true );
|
158 |
+
|
159 |
+
if ( ! is_array( $response ) ) {
|
160 |
+
tribe( 'logger' )->log_error( sprintf( '[%s] Unexpected PayPal GET response', $url ), 'tickets-commerce-paypal' );
|
161 |
+
|
162 |
+
return null;
|
163 |
+
}
|
164 |
+
|
165 |
+
return $response;
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Send a POST request to the PayPal API.
|
170 |
+
*
|
171 |
+
* @since 5.1.9
|
172 |
+
*
|
173 |
+
* @param string $endpoint
|
174 |
+
* @param array $query_args
|
175 |
+
* @param array $request_arguments
|
176 |
+
*
|
177 |
+
* @return array|null
|
178 |
+
*/
|
179 |
+
public function post( $endpoint, array $query_args = [], array $request_arguments = [] ) {
|
180 |
+
// If the endpoint passed is a full URL dont try to append anything.
|
181 |
+
$url = 0 !== strpos( 'https://', $endpoint )
|
182 |
+
? $this->get_api_url( $endpoint, $query_args )
|
183 |
+
: add_query_arg( $query_args, $endpoint );
|
184 |
+
|
185 |
+
$default_arguments = [
|
186 |
+
'headers' => [
|
187 |
+
'Accept' => 'application/json',
|
188 |
+
'Authorization' => sprintf( 'Bearer %1$s', $this->get_access_token() ),
|
189 |
+
'Content-Type' => 'application/json',
|
190 |
+
],
|
191 |
+
'body' => [],
|
192 |
+
];
|
193 |
+
foreach ( $default_arguments as $key => $default_argument ) {
|
194 |
+
$request_arguments[ $key ] = array_merge( $default_argument, Arr::get( $request_arguments, $key, [] ) );
|
195 |
+
}
|
196 |
+
|
197 |
+
$content_type = Arr::get( $request_arguments, [ 'headers', 'Content-Type' ] );
|
198 |
+
if ( empty( $content_type ) ) {
|
199 |
+
$content_type = Arr::get( $request_arguments, [ 'headers', 'content-type' ] );
|
200 |
+
}
|
201 |
+
|
202 |
+
if (
|
203 |
+
! empty( $request_arguments['body'] )
|
204 |
+
&& 'application/json' === strtolower( $content_type )
|
205 |
+
) {
|
206 |
+
$request_arguments['body'] = wp_json_encode( $request_arguments[ $key ] );
|
207 |
+
}
|
208 |
+
|
209 |
+
$response = wp_remote_post( $url, $request_arguments );
|
210 |
+
|
211 |
+
if ( is_wp_error( $response ) ) {
|
212 |
+
tribe( 'logger' )->log_error( sprintf(
|
213 |
+
'[%s] PayPal POST request error: %s',
|
214 |
+
$url,
|
215 |
+
$response->get_error_message()
|
216 |
+
), 'tickets-commerce-paypal' );
|
217 |
+
|
218 |
+
return null;
|
219 |
+
}
|
220 |
+
|
221 |
+
$response_code = wp_remote_retrieve_response_code( $response );
|
222 |
+
|
223 |
+
// When we receive an error code we return the whole response.
|
224 |
+
if ( ! in_array( $response_code, [ 200, 201, 202, 204 ], true ) ) {
|
225 |
+
return $response;
|
226 |
+
}
|
227 |
+
|
228 |
+
$response = wp_remote_retrieve_body( $response );
|
229 |
+
$response = @json_decode( $response, true );
|
230 |
+
|
231 |
+
if ( ! is_array( $response ) ) {
|
232 |
+
tribe( 'logger' )->log_error( sprintf( '[%s] Unexpected PayPal POST response', $url ), 'tickets-commerce-paypal' );
|
233 |
+
|
234 |
+
return null;
|
235 |
+
}
|
236 |
+
|
237 |
+
return $response;
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Retrieves an Access Token for the Client ID and Secret.
|
242 |
+
*
|
243 |
+
* @since 5.1.9
|
244 |
+
*
|
245 |
+
* @param string $client_id The Client ID.
|
246 |
+
* @param string $client_secret The Client Secret.
|
247 |
+
*
|
248 |
+
* @return array|null The token details response or null if there was a problem.
|
249 |
+
*/
|
250 |
+
public function get_access_token_from_client_credentials( $client_id, $client_secret ) {
|
251 |
+
$auth = base64_encode( "$client_id:$client_secret" );
|
252 |
+
$query_args = [];
|
253 |
+
|
254 |
+
$args = [
|
255 |
+
'headers' => [
|
256 |
+
'Authorization' => sprintf( 'Basic %1$s', $auth ),
|
257 |
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
258 |
+
],
|
259 |
+
'body' => [
|
260 |
+
'grant_type' => 'client_credentials',
|
261 |
+
],
|
262 |
+
];
|
263 |
+
|
264 |
+
return $this->post( 'v1/oauth2/token', $query_args, $args );
|
265 |
+
}
|
266 |
+
|
267 |
+
/**
|
268 |
+
* Retrieves an Access Token from the authorization code.
|
269 |
+
*
|
270 |
+
* @since 5.1.9
|
271 |
+
*
|
272 |
+
* @param string $shared_id Shared ID for merchant.
|
273 |
+
* @param string $auth_code Authorization code from on boarding.
|
274 |
+
* @param string $nonce Seller nonce from on boarding.
|
275 |
+
*
|
276 |
+
* @return array|null The token details response or null if there was a problem.
|
277 |
+
*/
|
278 |
+
public function get_access_token_from_authorization_code( $shared_id, $auth_code, $nonce ) {
|
279 |
+
$auth = base64_encode( $shared_id );
|
280 |
+
$query_args = [];
|
281 |
+
|
282 |
+
$args = [
|
283 |
+
'headers' => [
|
284 |
+
'Authorization' => sprintf( 'Basic %1$s', $auth ),
|
285 |
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
286 |
+
],
|
287 |
+
'body' => [
|
288 |
+
'grant_type' => 'authorization_code',
|
289 |
+
'code' => $auth_code,
|
290 |
+
'code_verifier' => $nonce,
|
291 |
+
],
|
292 |
+
];
|
293 |
+
|
294 |
+
return $this->post( 'v1/oauth2/token', $query_args, $args );
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* Retrieves a Client Token from the stored Access Token.
|
299 |
+
*
|
300 |
+
* @link https://developer.paypal.com/docs/business/checkout/advanced-card-payments/
|
301 |
+
*
|
302 |
+
* @since 5.1.9
|
303 |
+
*
|
304 |
+
* @return array|null The client token details response or null if there was a problem.
|
305 |
+
*/
|
306 |
+
public function get_client_token() {
|
307 |
+
$query_args = [];
|
308 |
+
$args = [
|
309 |
+
'headers' => [
|
310 |
+
'Accept' => 'application/json',
|
311 |
+
'Accept-Language' => 'en_US',
|
312 |
+
'Authorization' => sprintf( 'Bearer %1$s', $this->get_access_token() ),
|
313 |
+
'Content-Type' => 'application/json',
|
314 |
+
],
|
315 |
+
'body' => [],
|
316 |
+
];
|
317 |
+
|
318 |
+
return $this->post( 'v1/identity/generate-token', $query_args, $args );
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Based on a Purchase Unit creates a PayPal order.
|
323 |
+
*
|
324 |
+
* @link https://developer.paypal.com/docs/api/orders/v2/#orders_create
|
325 |
+
* @link https://developer.paypal.com/docs/api/orders/v2/#definition-purchase_unit_request
|
326 |
+
*
|
327 |
+
* @since 5.1.9
|
328 |
+
*
|
329 |
+
* @param array<string,mixed>|array<array> $units {
|
330 |
+
* Purchase unit used to setup the order in PayPal.
|
331 |
+
*
|
332 |
+
* @type string $reference_id Reference ID to PayPal.
|
333 |
+
* @type string $description Description of this Purchase Unit.
|
334 |
+
* @type string $value Value to be payed.
|
335 |
+
* @type string $currency Which currency.
|
336 |
+
* @type string $merchant_id Merchant ID.
|
337 |
+
* @type string $merchant_paypal_id PayPal Merchant ID.
|
338 |
+
* @type string $first_name Payee First Name.
|
339 |
+
* @type string $last_name Payee Last Name.
|
340 |
+
* @type string $email Payee email.
|
341 |
+
* @type string $disbursement_mode (optional) By default 'INSTANT'.
|
342 |
+
* @type string $payer_id (optional) PayPal Payer ID
|
343 |
+
* @type string $tax_id (optional) Tax ID for this purchase Unit.
|
344 |
+
* @type string $tax_id_type (optional) Tax ID for this purchase Unit.
|
345 |
+
*
|
346 |
+
* }
|
347 |
+
* @return array|null
|
348 |
+
*/
|
349 |
+
public function create_order( array $units = [] ) {
|
350 |
+
$merchant = tribe( Merchant::class );
|
351 |
+
$query_args = [];
|
352 |
+
$body = [
|
353 |
+
'intent' => 'CAPTURE',
|
354 |
+
'purchase_units' => [],
|
355 |
+
'application_context' => [
|
356 |
+
'shipping_preference' => 'NO_SHIPPING',
|
357 |
+
'user_action' => 'PAY_NOW',
|
358 |
+
],
|
359 |
+
];
|
360 |
+
|
361 |
+
// Determine if this set of units was just a single unit before looping.
|
362 |
+
if ( ! empty( $units['reference_id'] ) ) {
|
363 |
+
$units = [ $units ];
|
364 |
+
}
|
365 |
+
|
366 |
+
foreach ( $units as $unit ) {
|
367 |
+
/**
|
368 |
+
* @link https://developer.paypal.com/docs/api/orders/v2/#definition-payer
|
369 |
+
*/
|
370 |
+
$purchase_unit = [
|
371 |
+
'reference_id' => Arr::get( $unit, 'reference_id' ),
|
372 |
+
'description' => Arr::get( $unit, 'description' ),
|
373 |
+
'amount' => [
|
374 |
+
'value' => Arr::get( $unit, 'value' ),
|
375 |
+
'currency_code' => Arr::get( $unit, 'currency' ),
|
376 |
+
],
|
377 |
+
'payee' => [
|
378 |
+
'merchant_id' => Arr::get( $unit, 'merchant_paypal_id', $merchant->get_merchant_id_in_paypal() ),
|
379 |
+
],
|
380 |
+
'payer' => [
|
381 |
+
'name' => [
|
382 |
+
'given_name' => Arr::get( $unit, 'first_name' ),
|
383 |
+
'surname' => Arr::get( $unit, 'last_name' ),
|
384 |
+
],
|
385 |
+
'email_address' => Arr::get( $unit, 'email' ),
|
386 |
+
|
387 |
+
],
|
388 |
+
'payment_instruction' => [
|
389 |
+
'disbursement_mode' => Arr::get( $unit, 'disbursement_mode', 'INSTANT' ),
|
390 |
+
],
|
391 |
+
];
|
392 |
+
|
393 |
+
/**
|
394 |
+
* @todo Need to figure out how to get this email address still.
|
395 |
+
*/
|
396 |
+
if ( ! $merchant->is_sandbox() ) {
|
397 |
+
$purchase_unit['payee']['email_address'] = Arr::get( $unit, 'merchant_id', $merchant->get_merchant_id() );
|
398 |
+
}
|
399 |
+
|
400 |
+
if ( ! empty( $unit['tax_id'] ) ) {
|
401 |
+
$purchase_unit['payer']['tax_info']['tax_id'] = Arr::get( $unit, 'tax_id' );
|
402 |
+
}
|
403 |
+
|
404 |
+
if ( ! empty( $unit['tax_id_type'] ) ) {
|
405 |
+
$purchase_unit['payer']['tax_info']['tax_id_type'] = Arr::get( $unit, 'tax_id_type' );
|
406 |
+
}
|
407 |
+
|
408 |
+
/**
|
409 |
+
* @todo We should have some sort of Purchase Unit validation here.
|
410 |
+
*/
|
411 |
+
|
412 |
+
$body['purchase_units'][] = $purchase_unit;
|
413 |
+
}
|
414 |
+
|
415 |
+
$args = [
|
416 |
+
'headers' => [
|
417 |
+
'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
|
418 |
+
'Prefer' => 'return=representation',
|
419 |
+
],
|
420 |
+
'body' => $body,
|
421 |
+
];
|
422 |
+
|
423 |
+
$response = $this->post( '/v2/checkout/orders', $query_args, $args );
|
424 |
+
|
425 |
+
return $response;
|
426 |
+
}
|
427 |
+
|
428 |
+
/**
|
429 |
+
* Captures an order for a given ID in PayPal.
|
430 |
+
*
|
431 |
+
* @since 5.1.9
|
432 |
+
*
|
433 |
+
* @param string $order_id
|
434 |
+
*
|
435 |
+
* @return array|null
|
436 |
+
*/
|
437 |
+
public function capture_order( $order_id ) {
|
438 |
+
$query_args = [];
|
439 |
+
$body = [];
|
440 |
+
$args = [
|
441 |
+
'headers' => [
|
442 |
+
'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
|
443 |
+
'Prefer' => 'return=representation',
|
444 |
+
],
|
445 |
+
'body' => $body,
|
446 |
+
];
|
447 |
+
|
448 |
+
$capture_id = urlencode( $order_id );
|
449 |
+
$url = '/v2/checkout/orders/{order_id}/capture';
|
450 |
+
$url = str_replace( '{order_id}', $order_id, $url );
|
451 |
+
$response = $this->post( $url, $query_args, $args );
|
452 |
+
|
453 |
+
return $response;
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* Gets the profile information from the customer in PayPal.
|
458 |
+
*
|
459 |
+
* @link https://developer.paypal.com/docs/api/identity/v1/#userinfo_get
|
460 |
+
*
|
461 |
+
* @since 5.1.9
|
462 |
+
*
|
463 |
+
* @return array|null
|
464 |
+
*/
|
465 |
+
public function get_user_info() {
|
466 |
+
$query_args = [
|
467 |
+
'schema' => 'paypalv1.1',
|
468 |
+
];
|
469 |
+
$body = [];
|
470 |
+
$args = [];
|
471 |
+
|
472 |
+
$url = '/v1/identity/oauth2/userinfo';
|
473 |
+
$response = $this->get( $url, $query_args, $args );
|
474 |
+
|
475 |
+
return $response;
|
476 |
+
}
|
477 |
+
|
478 |
+
public function refund_payment( $capture_id ) {
|
479 |
+
$query_args = [];
|
480 |
+
$body = [];
|
481 |
+
$args = [
|
482 |
+
'headers' => [
|
483 |
+
'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
|
484 |
+
'Prefer' => 'return=representation',
|
485 |
+
],
|
486 |
+
'body' => $body,
|
487 |
+
];
|
488 |
+
|
489 |
+
$capture_id = urlencode( $capture_id );
|
490 |
+
$url = '/v2/payments/captures/{capture_id}/refund';
|
491 |
+
$url = str_replace( '{capture_id}', $capture_id, $url );
|
492 |
+
$response = $this->post( $url, $query_args, $args );
|
493 |
+
|
494 |
+
return $response;
|
495 |
+
}
|
496 |
+
|
497 |
+
|
498 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Connect_Client.php
DELETED
@@ -1,35 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Class Connect_Client
|
7 |
-
*
|
8 |
-
* @since 5.1.6
|
9 |
-
*
|
10 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
11 |
-
*/
|
12 |
-
class Connect_Client {
|
13 |
-
|
14 |
-
/**
|
15 |
-
* The API URL.
|
16 |
-
*
|
17 |
-
* @since 5.1.6
|
18 |
-
*
|
19 |
-
* @var string
|
20 |
-
*/
|
21 |
-
public $api_url = 'https://whodat.theeventscalendar.com/tickets/paypal/connect';
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Get REST API endpoint URL for requests.
|
25 |
-
*
|
26 |
-
* @since 5.1.6
|
27 |
-
*
|
28 |
-
* @param string $endpoint The endpoint path.
|
29 |
-
*
|
30 |
-
* @return string The API URL.
|
31 |
-
*/
|
32 |
-
public function get_api_url( $endpoint ) {
|
33 |
-
return "{$this->api_url}/{$endpoint}";
|
34 |
-
}
|
35 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/Gateway.php
CHANGED
@@ -3,8 +3,6 @@
|
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
|
5 |
use TEC\Tickets\Commerce\Gateways\Abstract_Gateway;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\MerchantDetails;
|
7 |
-
use Tribe__Tickets__Commerce__PayPal__Main as PayPal_Main;
|
8 |
|
9 |
/**
|
10 |
* Class Gateway
|
@@ -16,7 +14,7 @@ class Gateway extends Abstract_Gateway {
|
|
16 |
/**
|
17 |
* @inheritDoc
|
18 |
*/
|
19 |
-
protected static $key = 'paypal
|
20 |
|
21 |
/**
|
22 |
* PayPal attribution ID for requests.
|
@@ -27,6 +25,17 @@ class Gateway extends Abstract_Gateway {
|
|
27 |
*/
|
28 |
const ATTRIBUTION_ID = 'TheEventsCalendar_SP_PPCP';
|
29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
/**
|
31 |
* @inheritDoc
|
32 |
*/
|
@@ -43,18 +52,7 @@ class Gateway extends Abstract_Gateway {
|
|
43 |
return false;
|
44 |
}
|
45 |
|
46 |
-
|
47 |
-
$merchantDetails = tribe( MerchantDetails::class );
|
48 |
-
|
49 |
-
// Make sure we have details setup.
|
50 |
-
$merchantDetails->getDetails();
|
51 |
-
|
52 |
-
// @todo Confirm this is the correct conditional.
|
53 |
-
if ( $merchantDetails->accountIsConnected() ) {
|
54 |
-
return true;
|
55 |
-
}
|
56 |
-
|
57 |
-
return false;
|
58 |
}
|
59 |
|
60 |
/**
|
@@ -65,10 +63,7 @@ class Gateway extends Abstract_Gateway {
|
|
65 |
* @return array The list of settings for the gateway.
|
66 |
*/
|
67 |
public function get_settings() {
|
68 |
-
|
69 |
-
$settings = tribe( Settings::class );
|
70 |
-
|
71 |
-
return $settings->get_settings();
|
72 |
}
|
73 |
|
74 |
/**
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
|
5 |
use TEC\Tickets\Commerce\Gateways\Abstract_Gateway;
|
|
|
|
|
6 |
|
7 |
/**
|
8 |
* Class Gateway
|
14 |
/**
|
15 |
* @inheritDoc
|
16 |
*/
|
17 |
+
protected static $key = 'paypal';
|
18 |
|
19 |
/**
|
20 |
* PayPal attribution ID for requests.
|
25 |
*/
|
26 |
const ATTRIBUTION_ID = 'TheEventsCalendar_SP_PPCP';
|
27 |
|
28 |
+
/**
|
29 |
+
* PayPal tracking ID version.
|
30 |
+
*
|
31 |
+
* This shouldn't be updated unless we are modifying something on the PayPal user level.
|
32 |
+
*
|
33 |
+
* @since 5.1.9
|
34 |
+
*
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
const VERSION = '1.0.0';
|
38 |
+
|
39 |
/**
|
40 |
* @inheritDoc
|
41 |
*/
|
52 |
return false;
|
53 |
}
|
54 |
|
55 |
+
return tribe( Merchant::class )->account_is_connected();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
57 |
|
58 |
/**
|
63 |
* @return array The list of settings for the gateway.
|
64 |
*/
|
65 |
public function get_settings() {
|
66 |
+
return tribe( Settings::class )->get_settings();
|
|
|
|
|
|
|
67 |
}
|
68 |
|
69 |
/**
|
src/Tickets/Commerce/Gateways/PayPal/Hooks.php
CHANGED
@@ -17,6 +17,9 @@
|
|
17 |
|
18 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
19 |
|
|
|
|
|
|
|
20 |
/**
|
21 |
* Class Hooks.
|
22 |
*
|
@@ -42,60 +45,133 @@ class Hooks extends \tad_DI52_ServiceProvider {
|
|
42 |
* @since 5.1.6
|
43 |
*/
|
44 |
protected function add_actions() {
|
45 |
-
// Settings page: Connect PayPal.
|
46 |
-
add_action( 'wp_ajax_tribe_tickets_paypal_commerce_user_on_boarded', [ $this, 'on_boarded_user_ajax_request_handler' ] );
|
47 |
-
add_action( 'wp_ajax_tribe_tickets_paypal_commerce_get_partner_url', [ $this, 'on_get_partner_url_ajax_request_handler' ] );
|
48 |
-
add_action( 'wp_ajax_tribe_tickets_paypal_commerce_disconnect_account', [ $this, 'remove_paypal_account' ] );
|
49 |
-
add_action( 'wp_ajax_tribe_tickets_paypal_commerce_onboarding_trouble_notice', [ $this, 'on_boarding_trouble_notice' ] );
|
50 |
-
add_action( 'admin_init', [ $this, 'on_boarding_boot' ] );
|
51 |
-
|
52 |
-
// Frontend: PayPal Checkout.
|
53 |
-
add_action( 'wp_ajax_tribe_tickets_paypal_commerce_create_order', [ $this, 'create_order' ] );
|
54 |
-
add_action( 'wp_ajax_nopriv_tribe_tickets_paypal_commerce_create_order', [ $this, 'create_order' ] );
|
55 |
-
add_action( 'wp_ajax_tribe_tickets_paypal_commerce_approve_order', [ $this, 'approve_order' ] );
|
56 |
-
add_action( 'wp_ajax_nopriv_tribe_tickets_paypal_commerce_approve_order', [ $this, 'approve_order' ] );
|
57 |
-
|
58 |
// REST API Endpoint registration.
|
59 |
add_action( 'rest_api_init', [ $this, 'register_endpoints' ] );
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
}
|
61 |
|
62 |
-
/**
|
63 |
* Adds the filters required by each Tickets Commerce component.
|
64 |
*
|
65 |
* @since 5.1.6
|
66 |
*/
|
67 |
protected function add_filters() {
|
68 |
add_filter( 'tec_tickets_commerce_gateways', [ $this, 'filter_add_gateway' ], 10, 2 );
|
|
|
|
|
69 |
}
|
70 |
|
71 |
-
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
-
|
76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
78 |
|
79 |
-
|
80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
}
|
82 |
|
83 |
-
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
}
|
86 |
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
90 |
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
}
|
94 |
|
95 |
-
|
96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
}
|
98 |
|
|
|
|
|
|
|
|
|
|
|
99 |
public function register_endpoints() {
|
100 |
$this->container->make( REST::class )->register_endpoints();
|
101 |
}
|
@@ -112,4 +188,4 @@ class Hooks extends \tad_DI52_ServiceProvider {
|
|
112 |
public function filter_add_gateway( array $gateways = [] ) {
|
113 |
return $this->container->make( Gateway::class )->register_gateway( $gateways );
|
114 |
}
|
115 |
-
}
|
17 |
|
18 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
19 |
|
20 |
+
use TEC\Tickets\Commerce\Module;
|
21 |
+
use TEC\Tickets\Commerce\Shortcodes\Shortcode_Abstract;
|
22 |
+
|
23 |
/**
|
24 |
* Class Hooks.
|
25 |
*
|
45 |
* @since 5.1.6
|
46 |
*/
|
47 |
protected function add_actions() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
// REST API Endpoint registration.
|
49 |
add_action( 'rest_api_init', [ $this, 'register_endpoints' ] );
|
50 |
+
add_action( 'tec_tickets_commerce_admin_process_action:paypal-disconnect', [ $this, 'handle_action_disconnect' ] );
|
51 |
+
add_action( 'tec_tickets_commerce_admin_process_action:paypal-refresh-access-token', [ $this, 'handle_action_refresh_token' ] );
|
52 |
+
add_action( 'tec_tickets_commerce_admin_process_action:paypal-refresh-user-info', [ $this, 'handle_action_refresh_user_info' ] );
|
53 |
+
|
54 |
+
add_action( 'tribe_template_before_include:tickets/v2/commerce/checkout/header', [ $this, 'include_client_js_sdk_script' ], 15, 3 );
|
55 |
+
add_action( 'tribe_template_after_include:tickets/v2/commerce/checkout/footer', [ $this, 'include_payment_buttons' ], 15, 3 );
|
56 |
}
|
57 |
|
58 |
+
/**1
|
59 |
* Adds the filters required by each Tickets Commerce component.
|
60 |
*
|
61 |
* @since 5.1.6
|
62 |
*/
|
63 |
protected function add_filters() {
|
64 |
add_filter( 'tec_tickets_commerce_gateways', [ $this, 'filter_add_gateway' ], 10, 2 );
|
65 |
+
add_filter( 'tec_tickets_commerce_success_shortcode_checkout_page_paypal_template_vars', [ $this, 'include_checkout_page_vars' ], 10, 2 );
|
66 |
+
add_filter( 'tec_tickets_commerce_success_shortcode_success_page_paypal_template_vars', [ $this, 'include_success_page_vars' ], 10, 2 );
|
67 |
}
|
68 |
|
69 |
+
/**
|
70 |
+
* Filters the shortcode template vars for the Checkout page template.
|
71 |
+
*
|
72 |
+
* @since 5.1.9
|
73 |
+
*
|
74 |
+
* @param array $template_vars
|
75 |
+
* @param Shortcode_Abstract $shortcode
|
76 |
+
*
|
77 |
+
* @return array
|
78 |
+
*/
|
79 |
+
public function include_checkout_page_vars( $template_vars, $shortcode ) {
|
80 |
+
$template_vars['merchant'] = tribe( Merchant::class );
|
81 |
+
|
82 |
+
return $template_vars;
|
83 |
}
|
84 |
|
85 |
+
/**
|
86 |
+
* Filters the shortcode template vars for the Checkout page template.
|
87 |
+
*
|
88 |
+
* @since 5.1.9
|
89 |
+
*
|
90 |
+
* @param array $template_vars
|
91 |
+
* @param Shortcode_Abstract $shortcode
|
92 |
+
*
|
93 |
+
* @return array
|
94 |
+
*/
|
95 |
+
public function include_success_page_vars( $template_vars, $shortcode ) {
|
96 |
+
$template_vars['merchant'] = tribe( Merchant::class );
|
97 |
+
|
98 |
+
return $template_vars;
|
99 |
}
|
100 |
|
101 |
+
/**
|
102 |
+
* Include the Client JS SDK script into checkout.
|
103 |
+
*
|
104 |
+
* @since 5.1.9
|
105 |
+
*
|
106 |
+
* @param string $file Which file we are loading.
|
107 |
+
* @param string $name Name of file file
|
108 |
+
* @param \Tribe__Template $template Which Template object is being used.
|
109 |
+
*
|
110 |
+
*/
|
111 |
+
public function include_client_js_sdk_script( $file, $name, $template ) {
|
112 |
+
echo tribe( Buttons::class )->get_checkout_script();
|
113 |
}
|
114 |
|
115 |
+
/**
|
116 |
+
* Include the Client JS SDK script into checkout.
|
117 |
+
*
|
118 |
+
* @since 5.1.9
|
119 |
+
*
|
120 |
+
* @param string $file Which file we are loading.
|
121 |
+
* @param string $name Name of file file
|
122 |
+
* @param \Tribe__Template $template Which Template object is being used.
|
123 |
+
*
|
124 |
+
*/
|
125 |
+
public function include_payment_buttons( $file, $name, $template ) {
|
126 |
+
$must_login = ! is_user_logged_in() && tribe( Module::class )->login_required();
|
127 |
+
|
128 |
+
$template->template( 'gateway/paypal/buttons', [ 'must_login' => $must_login ] );
|
129 |
}
|
130 |
|
131 |
+
/**
|
132 |
+
* Handles the disconnecting of the merchant.
|
133 |
+
*
|
134 |
+
* @todo Display some message when disconnecting.
|
135 |
+
* @since 5.1.9
|
136 |
+
*
|
137 |
+
*/
|
138 |
+
public function handle_action_disconnect() {
|
139 |
+
$this->container->make( Merchant::class )->disconnect();
|
140 |
}
|
141 |
|
142 |
+
/**
|
143 |
+
* Handles the refreshing of the token from PayPal for this merchant.
|
144 |
+
*
|
145 |
+
* @todo Display some message when refreshing token.
|
146 |
+
* @since 5.1.9
|
147 |
+
*
|
148 |
+
*/
|
149 |
+
public function handle_action_refresh_token() {
|
150 |
+
$merchant = $this->container->make( Merchant::class );
|
151 |
+
$token_data = $this->container->make( Client::class )->get_access_token_from_client_credentials( $merchant->get_client_id(), $merchant->get_client_secret() );
|
152 |
+
|
153 |
+
$saved = $merchant->save_access_token_data( $token_data );
|
154 |
}
|
155 |
|
156 |
+
/**
|
157 |
+
* Handles the refreshing of the user info from PayPal for this merchant.
|
158 |
+
*
|
159 |
+
* @todo Display some message when refreshing user info.
|
160 |
+
* @since 5.1.9
|
161 |
+
*
|
162 |
+
*/
|
163 |
+
public function handle_action_refresh_user_info() {
|
164 |
+
$merchant = $this->container->make( Merchant::class );
|
165 |
+
$user_info = $this->container->make( Client::class )->get_user_info();
|
166 |
+
|
167 |
+
$saved = $merchant->save_user_info( $user_info );
|
168 |
}
|
169 |
|
170 |
+
/**
|
171 |
+
* Register the Endpoints from Paypal.
|
172 |
+
*
|
173 |
+
* @since 5.1.9
|
174 |
+
*/
|
175 |
public function register_endpoints() {
|
176 |
$this->container->make( REST::class )->register_endpoints();
|
177 |
}
|
188 |
public function filter_add_gateway( array $gateways = [] ) {
|
189 |
return $this->container->make( Gateway::class )->register_gateway( $gateways );
|
190 |
}
|
191 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Merchant.php
ADDED
@@ -0,0 +1,833 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
|
5 |
+
use Tribe__Utils__Array as Arr;
|
6 |
+
use Tribe__Date_Utils as Dates;
|
7 |
+
use TEC\Tickets\Commerce\Traits\Has_Mode;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class Merchant.
|
11 |
+
*
|
12 |
+
* @since 5.1.9
|
13 |
+
*
|
14 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
15 |
+
*/
|
16 |
+
class Merchant {
|
17 |
+
use Has_Mode;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* All account Props we use for the merchant
|
21 |
+
*
|
22 |
+
* @since 5.1.9
|
23 |
+
*
|
24 |
+
* @var string[]
|
25 |
+
*/
|
26 |
+
protected $account_props = [
|
27 |
+
'signup_hash',
|
28 |
+
'merchant_id',
|
29 |
+
'merchant_id_in_paypal',
|
30 |
+
'client_id',
|
31 |
+
'client_secret',
|
32 |
+
'account_is_ready',
|
33 |
+
'supports_custom_payments',
|
34 |
+
'account_country',
|
35 |
+
'access_token',
|
36 |
+
];
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Determines if the data needs to be saved to the Database
|
40 |
+
*
|
41 |
+
* @since 5.1.9
|
42 |
+
*
|
43 |
+
* @var boolean
|
44 |
+
*/
|
45 |
+
protected $needs_save = false;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* PayPal merchant Id (email address).
|
49 |
+
*
|
50 |
+
* @since 5.1.9
|
51 |
+
*
|
52 |
+
* @var null|string
|
53 |
+
*/
|
54 |
+
protected $merchant_id;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* A Hash used during signup that should be associated with the merchant.
|
58 |
+
*
|
59 |
+
* @since 5.1.9
|
60 |
+
*
|
61 |
+
* @var null|string
|
62 |
+
*/
|
63 |
+
protected $signup_hash;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* PayPal merchant id.
|
67 |
+
*
|
68 |
+
* @since 5.1.9
|
69 |
+
*
|
70 |
+
* @var string
|
71 |
+
*/
|
72 |
+
protected $merchant_id_in_paypal;
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Client id.
|
76 |
+
*
|
77 |
+
* @since 5.1.9
|
78 |
+
*
|
79 |
+
* @var string
|
80 |
+
*/
|
81 |
+
protected $client_id;
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Client Secret.
|
85 |
+
*
|
86 |
+
* @since 5.1.9
|
87 |
+
*
|
88 |
+
* @var string
|
89 |
+
*/
|
90 |
+
protected $client_secret;
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Client token.
|
94 |
+
*
|
95 |
+
* @since 5.1.9
|
96 |
+
*
|
97 |
+
* @var array
|
98 |
+
*/
|
99 |
+
protected $client_token;
|
100 |
+
|
101 |
+
/**
|
102 |
+
* How long till the Client token expires
|
103 |
+
*
|
104 |
+
* @since 5.1.9
|
105 |
+
*
|
106 |
+
* @var int
|
107 |
+
*/
|
108 |
+
protected $client_token_expires_in;
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Access token.
|
112 |
+
*
|
113 |
+
* @since 5.1.9
|
114 |
+
*
|
115 |
+
* @var string
|
116 |
+
*/
|
117 |
+
protected $access_token;
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Whether or not the connected account is ready to process payments.
|
121 |
+
*
|
122 |
+
* @since 5.1.9
|
123 |
+
*
|
124 |
+
* @var bool
|
125 |
+
*/
|
126 |
+
protected $account_is_ready = false;
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Whether or not the account can make custom payments (i.e Advanced Fields & PPCP)
|
130 |
+
*
|
131 |
+
* @since 5.1.9
|
132 |
+
*
|
133 |
+
* @var bool
|
134 |
+
*/
|
135 |
+
protected $supports_custom_payments = false;
|
136 |
+
|
137 |
+
/**
|
138 |
+
* PayPal account account country.
|
139 |
+
*
|
140 |
+
* @since 5.1.9
|
141 |
+
*
|
142 |
+
* @var string
|
143 |
+
*/
|
144 |
+
protected $account_country;
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Fetches the current signup hash.
|
148 |
+
*
|
149 |
+
* @since 5.1.9
|
150 |
+
*
|
151 |
+
* @return string|null
|
152 |
+
*/
|
153 |
+
public function get_signup_hash() {
|
154 |
+
return $this->signup_hash;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Sets the value for signup hash locally, in this instance of the Merchant.
|
159 |
+
*
|
160 |
+
* @since 5.1.9
|
161 |
+
*
|
162 |
+
* @param mixed $value Value used for the signup hash.
|
163 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
164 |
+
*/
|
165 |
+
public function set_signup_hash( $value, $needs_save = true ) {
|
166 |
+
$this->set_value( 'signup_hash', $value, $needs_save );
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Fetches the current Merchant ID.
|
171 |
+
*
|
172 |
+
* @since 5.1.9
|
173 |
+
*
|
174 |
+
* @return string|null
|
175 |
+
*/
|
176 |
+
public function get_merchant_id() {
|
177 |
+
return $this->merchant_id;
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Sets the value for Merchant ID locally, in this instance of the Merchant.
|
182 |
+
*
|
183 |
+
* @since 5.1.9
|
184 |
+
*
|
185 |
+
* @param mixed $value Value used for the Merchant ID.
|
186 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
187 |
+
*/
|
188 |
+
public function set_merchant_id( $value, $needs_save = true ) {
|
189 |
+
$this->set_value( 'merchant_id', $value, $needs_save );
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Gets the value stored for the Merchant ID in PayPal.
|
194 |
+
*
|
195 |
+
* @since 5.1.9
|
196 |
+
*
|
197 |
+
* @return string
|
198 |
+
*/
|
199 |
+
public function get_merchant_id_in_paypal() {
|
200 |
+
return $this->merchant_id_in_paypal;
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Sets the value for Merchant ID in PayPal locally, in this instance of the Merchant.
|
205 |
+
*
|
206 |
+
* @since 5.1.9
|
207 |
+
*
|
208 |
+
* @param mixed $value Value used for the Merchant ID in PayPal.
|
209 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
210 |
+
*/
|
211 |
+
public function set_merchant_id_in_paypal( $value, $needs_save = true ) {
|
212 |
+
$this->set_value( 'merchant_id_in_paypal', $value, $needs_save );
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Gets the value stored for the Client ID.
|
217 |
+
*
|
218 |
+
* @since 5.1.9
|
219 |
+
*
|
220 |
+
* @return string
|
221 |
+
*/
|
222 |
+
public function get_client_id() {
|
223 |
+
return $this->client_id;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Sets the value for Merchant ID locally, in this instance of the Merchant.
|
228 |
+
*
|
229 |
+
* @since 5.1.9
|
230 |
+
*
|
231 |
+
* @param mixed $value Value used for the Merchant ID.
|
232 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
233 |
+
*/
|
234 |
+
public function set_client_id( $value, $needs_save = true ) {
|
235 |
+
$this->client_id = $value;
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Gets the value stored for the Client Secret.
|
240 |
+
*
|
241 |
+
* @since 5.1.9
|
242 |
+
*
|
243 |
+
* @return string
|
244 |
+
*/
|
245 |
+
public function get_client_secret() {
|
246 |
+
return $this->client_secret;
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Sets the value for Client Secret locally, in this instance of the Merchant.
|
251 |
+
*
|
252 |
+
* @since 5.1.9
|
253 |
+
*
|
254 |
+
* @param mixed $value Value used for the Client Secret.
|
255 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
256 |
+
*/
|
257 |
+
public function set_client_secret( $value, $needs_save = true ) {
|
258 |
+
$this->set_value( 'client_secret', $value, $needs_save );
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Gets the value stored for the Access Token.
|
263 |
+
*
|
264 |
+
* @since 5.1.9
|
265 |
+
*
|
266 |
+
* @return string
|
267 |
+
*/
|
268 |
+
public function get_access_token() {
|
269 |
+
return $this->access_token;
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Sets the value for Access Token locally, in this instance of the Merchant.
|
274 |
+
*
|
275 |
+
* @since 5.1.9
|
276 |
+
*
|
277 |
+
* @param mixed $value Value used for the Access Token.
|
278 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
279 |
+
*/
|
280 |
+
public function set_access_token( $value, $needs_save = true ) {
|
281 |
+
$this->set_value( 'access_token', $value, $needs_save );
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Gets the value stored for if the account is ready for usage.
|
286 |
+
*
|
287 |
+
* @since 5.1.9
|
288 |
+
*
|
289 |
+
* @return string
|
290 |
+
*/
|
291 |
+
public function get_account_is_ready() {
|
292 |
+
return $this->account_is_ready;
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Sets the value for if this account is ready for usage locally, in this instance of the Merchant.
|
297 |
+
*
|
298 |
+
* @since 5.1.9
|
299 |
+
*
|
300 |
+
* @param mixed $value Value used for the Account is Ready.
|
301 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
302 |
+
*/
|
303 |
+
public function set_account_is_ready( $value, $needs_save = true ) {
|
304 |
+
$this->set_value( 'account_is_ready', $value, $needs_save );
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Gets the value stored for if this account supports custom payments.
|
309 |
+
*
|
310 |
+
* @since 5.1.9
|
311 |
+
*
|
312 |
+
* @return bool
|
313 |
+
*/
|
314 |
+
public function get_supports_custom_payments() {
|
315 |
+
return $this->supports_custom_payments;
|
316 |
+
}
|
317 |
+
|
318 |
+
/**
|
319 |
+
* Sets the value determining if this supports custom payments locally, in this instance of the Merchant.
|
320 |
+
*
|
321 |
+
* @since 5.1.9
|
322 |
+
*
|
323 |
+
* @param mixed $value Value used for the Support for Custom Payments.
|
324 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
325 |
+
*/
|
326 |
+
public function set_supports_custom_payments( $value, $needs_save = true ) {
|
327 |
+
$this->set_value( 'supports_custom_payments', $value, $needs_save );
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Gets the value stored for the Country Code.
|
332 |
+
*
|
333 |
+
* @since 5.1.9
|
334 |
+
*
|
335 |
+
* @return string
|
336 |
+
*/
|
337 |
+
public function get_account_country() {
|
338 |
+
return $this->account_country;
|
339 |
+
}
|
340 |
+
|
341 |
+
/**
|
342 |
+
* Sets the value for Account Country locally, in this instance of the Merchant.
|
343 |
+
*
|
344 |
+
* @since 5.1.9
|
345 |
+
*
|
346 |
+
* @param mixed $value Value used for the Account Country.
|
347 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
348 |
+
*/
|
349 |
+
public function set_account_country( $value, $needs_save = true ) {
|
350 |
+
$this->set_value( 'account_country', $value, $needs_save );
|
351 |
+
}
|
352 |
+
|
353 |
+
/**
|
354 |
+
* Determines if this instances needs to be saved to the DB.
|
355 |
+
*
|
356 |
+
* @since 5.1.9
|
357 |
+
*
|
358 |
+
* @return bool
|
359 |
+
*/
|
360 |
+
public function needs_save() {
|
361 |
+
return tribe_is_truthy( $this->needs_save );
|
362 |
+
}
|
363 |
+
|
364 |
+
|
365 |
+
/**
|
366 |
+
* Returns the options key for the account in the merchant mode.
|
367 |
+
*
|
368 |
+
* @since 5.1.9
|
369 |
+
*
|
370 |
+
* @return string
|
371 |
+
*/
|
372 |
+
public function get_account_key() {
|
373 |
+
$gateway_key = Gateway::get_key();
|
374 |
+
$merchant_mode = $this->get_mode();
|
375 |
+
|
376 |
+
return "tec_tickets_commerce_{$gateway_key}_{$merchant_mode}_account";
|
377 |
+
}
|
378 |
+
|
379 |
+
/**
|
380 |
+
* Returns the data retrieved from the access token refreshing process.
|
381 |
+
*
|
382 |
+
* @since 5.1.9
|
383 |
+
*
|
384 |
+
* @return string
|
385 |
+
*/
|
386 |
+
public function get_access_token_data_key() {
|
387 |
+
$gateway_key = Gateway::get_key();
|
388 |
+
$merchant_mode = $this->get_mode();
|
389 |
+
|
390 |
+
return "tec_tickets_commerce_{$gateway_key}_{$merchant_mode}_access_token_data";
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Returns the data retrieved from the signup process.
|
395 |
+
*
|
396 |
+
* Uses normal WP options to be saved, instead of the normal tribe_update_option.
|
397 |
+
*
|
398 |
+
* @since 5.1.9
|
399 |
+
*
|
400 |
+
* @return string
|
401 |
+
*/
|
402 |
+
public function get_signup_data_key() {
|
403 |
+
$gateway_key = Gateway::get_key();
|
404 |
+
$merchant_mode = $this->get_mode();
|
405 |
+
|
406 |
+
return "tec_tickets_commerce_{$gateway_key}_{$merchant_mode}_signup_data";
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Returns the options key for the account errors in the merchant mode.
|
411 |
+
*
|
412 |
+
* @since 5.1.9
|
413 |
+
*
|
414 |
+
* @return string
|
415 |
+
*/
|
416 |
+
public function get_account_errors_key() {
|
417 |
+
$gateway_key = Gateway::get_key();
|
418 |
+
$merchant_mode = $this->get_mode();
|
419 |
+
|
420 |
+
return "tec_tickets_commerce_{$gateway_key}_{$merchant_mode}_account_errors";
|
421 |
+
}
|
422 |
+
|
423 |
+
/**
|
424 |
+
* Returns the options key for the account account information.
|
425 |
+
*
|
426 |
+
* @since 5.1.9
|
427 |
+
*
|
428 |
+
* @return string
|
429 |
+
*/
|
430 |
+
public function get_user_info_key() {
|
431 |
+
$gateway_key = Gateway::get_key();
|
432 |
+
$merchant_mode = $this->get_mode();
|
433 |
+
|
434 |
+
return "tec_tickets_commerce_{$gateway_key}_{$merchant_mode}_user_info";
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Handle initial setup for the object singleton.
|
439 |
+
*
|
440 |
+
* @since 5.1.9
|
441 |
+
*/
|
442 |
+
public function init() {
|
443 |
+
$this->set_mode( tribe_tickets_commerce_is_test_mode() ? 'sandbox' : 'live' );
|
444 |
+
$this->from_array( $this->get_details_data(), false );
|
445 |
+
}
|
446 |
+
|
447 |
+
/**
|
448 |
+
* Return array of merchant details.
|
449 |
+
*
|
450 |
+
* @since 5.1.9
|
451 |
+
*
|
452 |
+
* @return array
|
453 |
+
*/
|
454 |
+
public function to_array() {
|
455 |
+
return [
|
456 |
+
'signup_hash' => $this->get_signup_hash(),
|
457 |
+
'merchant_id' => $this->get_merchant_id(),
|
458 |
+
'merchant_id_in_paypal' => $this->get_merchant_id_in_paypal(),
|
459 |
+
'client_id' => $this->get_client_id(),
|
460 |
+
'client_secret' => $this->get_client_secret(),
|
461 |
+
'account_is_ready' => $this->get_account_is_ready(),
|
462 |
+
'supports_custom_payments' => $this->get_supports_custom_payments(),
|
463 |
+
'account_country' => $this->get_account_country(),
|
464 |
+
'access_token' => $this->get_access_token(),
|
465 |
+
];
|
466 |
+
}
|
467 |
+
|
468 |
+
/**
|
469 |
+
* Make Merchant object from array.
|
470 |
+
*
|
471 |
+
* @since 5.1.9
|
472 |
+
*
|
473 |
+
* @param array $data Which values need to .
|
474 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
475 |
+
*
|
476 |
+
* @return boolean
|
477 |
+
*/
|
478 |
+
public function from_array( array $data, $needs_save = true ) {
|
479 |
+
if ( ! $this->validate( $data ) ) {
|
480 |
+
return false;
|
481 |
+
}
|
482 |
+
|
483 |
+
$this->setup_properties( $data, $needs_save );
|
484 |
+
|
485 |
+
return true;
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Saves a given base value into the class props.
|
490 |
+
*
|
491 |
+
* @since 5.1.9
|
492 |
+
*
|
493 |
+
* @param string $key
|
494 |
+
* @param mixed $value
|
495 |
+
* @param bool $needs_save
|
496 |
+
*
|
497 |
+
*/
|
498 |
+
protected function set_value( $key, $value, $needs_save = true ) {
|
499 |
+
$this->{$key} = $value;
|
500 |
+
|
501 |
+
// Determine if we will need to save in the DB.
|
502 |
+
if ( $needs_save ) {
|
503 |
+
$this->needs_save = true;
|
504 |
+
}
|
505 |
+
}
|
506 |
+
|
507 |
+
/**
|
508 |
+
* Setup properties from array.
|
509 |
+
*
|
510 |
+
* @since 5.1.9
|
511 |
+
*
|
512 |
+
* @param array $data Which values need to be saved.
|
513 |
+
* @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
|
514 |
+
*/
|
515 |
+
protected function setup_properties( array $data, $needs_save = true ) {
|
516 |
+
if ( array_key_exists( 'signup_hash', $data ) ) {
|
517 |
+
$this->set_signup_hash( $data['signup_hash'], $needs_save );
|
518 |
+
}
|
519 |
+
if ( array_key_exists( 'merchant_id', $data ) ) {
|
520 |
+
$this->set_merchant_id( $data['merchant_id'], $needs_save );
|
521 |
+
}
|
522 |
+
if ( array_key_exists( 'merchant_id_in_paypal', $data ) ) {
|
523 |
+
$this->set_merchant_id_in_paypal( $data['merchant_id_in_paypal'], $needs_save );
|
524 |
+
}
|
525 |
+
if ( array_key_exists( 'client_id', $data ) ) {
|
526 |
+
$this->set_client_id( $data['client_id'], $needs_save );
|
527 |
+
}
|
528 |
+
if ( array_key_exists( 'client_secret', $data ) ) {
|
529 |
+
$this->set_client_secret( $data['client_secret'], $needs_save );
|
530 |
+
}
|
531 |
+
if ( array_key_exists( 'account_is_ready', $data ) ) {
|
532 |
+
$this->set_account_is_ready( $data['account_is_ready'], $needs_save );
|
533 |
+
}
|
534 |
+
if ( array_key_exists( 'supports_custom_payments', $data ) ) {
|
535 |
+
$this->set_supports_custom_payments( $data['supports_custom_payments'], $needs_save );
|
536 |
+
}
|
537 |
+
if ( array_key_exists( 'account_country', $data ) ) {
|
538 |
+
$this->set_account_country( $data['account_country'], $needs_save );
|
539 |
+
}
|
540 |
+
if ( array_key_exists( 'access_token', $data ) ) {
|
541 |
+
$this->set_access_token( $data['access_token'], $needs_save );
|
542 |
+
}
|
543 |
+
}
|
544 |
+
|
545 |
+
/**
|
546 |
+
* Validate merchant details.
|
547 |
+
*
|
548 |
+
* @since 5.1.6
|
549 |
+
*
|
550 |
+
* @param array $merchant_details
|
551 |
+
*/
|
552 |
+
public function validate( $merchant_details ) {
|
553 |
+
$required = $this->account_props;
|
554 |
+
|
555 |
+
if ( array_diff( $required, array_keys( $merchant_details ) ) ) {
|
556 |
+
return false;
|
557 |
+
}
|
558 |
+
|
559 |
+
return true;
|
560 |
+
}
|
561 |
+
|
562 |
+
/**
|
563 |
+
* Save merchant details.
|
564 |
+
*
|
565 |
+
* @since 5.1.9
|
566 |
+
*
|
567 |
+
* @return bool
|
568 |
+
*/
|
569 |
+
public function save() {
|
570 |
+
if ( false === $this->needs_save() ) {
|
571 |
+
return false;
|
572 |
+
}
|
573 |
+
|
574 |
+
$saved = update_option( $this->get_account_key(), $this->to_array() );
|
575 |
+
|
576 |
+
// If we were able to save, we reset the needs save.
|
577 |
+
if ( $saved ) {
|
578 |
+
$this->needs_save = false;
|
579 |
+
}
|
580 |
+
|
581 |
+
return $saved;
|
582 |
+
}
|
583 |
+
|
584 |
+
/**
|
585 |
+
* Get the merchant details data.
|
586 |
+
*
|
587 |
+
* @since 5.1.9
|
588 |
+
*
|
589 |
+
* @return array
|
590 |
+
*/
|
591 |
+
protected function get_details_data() {
|
592 |
+
return (array) get_option( $this->get_account_key(), [] );
|
593 |
+
}
|
594 |
+
|
595 |
+
/**
|
596 |
+
* Delete merchant account details on the Database.
|
597 |
+
*
|
598 |
+
* @since 5.1.9
|
599 |
+
*
|
600 |
+
* @return bool
|
601 |
+
*/
|
602 |
+
public function delete_data() {
|
603 |
+
$status = update_option( $this->get_account_key(), null );
|
604 |
+
|
605 |
+
if ( $status ) {
|
606 |
+
$data = array_fill_keys( $this->account_props, null );
|
607 |
+
// reset internal values.
|
608 |
+
$this->setup_properties( $data, false );
|
609 |
+
}
|
610 |
+
|
611 |
+
return $status;
|
612 |
+
}
|
613 |
+
|
614 |
+
/**
|
615 |
+
* Returns the account errors if there are any.
|
616 |
+
*
|
617 |
+
* @since 5.1.9
|
618 |
+
*
|
619 |
+
* @return string[]|null
|
620 |
+
*/
|
621 |
+
public function get_account_errors() {
|
622 |
+
return get_option( $this->get_account_errors_key(), null );
|
623 |
+
}
|
624 |
+
|
625 |
+
/**
|
626 |
+
* Saves the account error message.
|
627 |
+
*
|
628 |
+
* @since 5.1.9
|
629 |
+
*
|
630 |
+
* @param string[] $error_message
|
631 |
+
*
|
632 |
+
* @return bool
|
633 |
+
*/
|
634 |
+
public function save_account_errors( $error_message ) {
|
635 |
+
return update_option( $this->get_account_errors_key(), $error_message );
|
636 |
+
}
|
637 |
+
|
638 |
+
/**
|
639 |
+
* Deletes the errors for the account.
|
640 |
+
*
|
641 |
+
* @since 5.1.9
|
642 |
+
*
|
643 |
+
* @return bool
|
644 |
+
*/
|
645 |
+
public function delete_account_errors() {
|
646 |
+
return delete_option( $this->get_account_errors_key() );
|
647 |
+
}
|
648 |
+
|
649 |
+
|
650 |
+
/**
|
651 |
+
* Saves signup data from the transient into a permanent storage.
|
652 |
+
*
|
653 |
+
* @since 5.1.9
|
654 |
+
*
|
655 |
+
* @return array
|
656 |
+
*/
|
657 |
+
public function get_access_token_data() {
|
658 |
+
return get_option( $this->get_access_token_data_key(), [] );
|
659 |
+
}
|
660 |
+
|
661 |
+
/**
|
662 |
+
* Saves the access token data, and adds some extra information for better usage.
|
663 |
+
*
|
664 |
+
* @since 5.1.9
|
665 |
+
*
|
666 |
+
* @param array $token_data
|
667 |
+
*
|
668 |
+
* @return bool
|
669 |
+
*/
|
670 |
+
public function save_access_token_data( array $token_data ) {
|
671 |
+
if ( empty( $token_data['access_token'] ) ) {
|
672 |
+
return false;
|
673 |
+
}
|
674 |
+
|
675 |
+
$this->set_access_token( $token_data['access_token'] );
|
676 |
+
$this->save();
|
677 |
+
|
678 |
+
if ( ! empty( $token_data['expires_in'] ) ) {
|
679 |
+
$expires_in = Dates::interval( 'PT' . $token_data['expires_in'] . 'S' );
|
680 |
+
|
681 |
+
// Store date related data in readable formats.
|
682 |
+
$token_data['token_retrieval_time'] = Dates::build_date_object( 'now' )->format( Dates::DBDATETIMEFORMAT );
|
683 |
+
$token_data['token_expiration_time'] = Dates::build_date_object( 'now' )->add( $expires_in )->format( Dates::DBDATETIMEFORMAT );
|
684 |
+
}
|
685 |
+
|
686 |
+
return update_option( $this->get_access_token_data_key(), $token_data );
|
687 |
+
}
|
688 |
+
|
689 |
+
/**
|
690 |
+
* Delete access token data.
|
691 |
+
*
|
692 |
+
* @since 5.1.9
|
693 |
+
*
|
694 |
+
* @return bool
|
695 |
+
*/
|
696 |
+
public function delete_access_token_data() {
|
697 |
+
return update_option( $this->get_access_token_data_key(), null );
|
698 |
+
}
|
699 |
+
|
700 |
+
/**
|
701 |
+
* Saves signup data from the transient into permanent option.
|
702 |
+
*
|
703 |
+
* @since 5.1.9
|
704 |
+
*
|
705 |
+
* @param array $signup_data
|
706 |
+
*
|
707 |
+
* @return bool
|
708 |
+
*/
|
709 |
+
public function save_signup_data( array $signup_data ) {
|
710 |
+
return update_option( $this->get_signup_data_key(), $signup_data );
|
711 |
+
}
|
712 |
+
|
713 |
+
/**
|
714 |
+
* Saves signup data from the transient into a permanent storage.
|
715 |
+
*
|
716 |
+
* @since 5.1.9
|
717 |
+
*
|
718 |
+
* @return array
|
719 |
+
*/
|
720 |
+
public function get_signup_data() {
|
721 |
+
return get_option( $this->get_signup_data_key(), [] );
|
722 |
+
}
|
723 |
+
|
724 |
+
/**
|
725 |
+
* Deletes signup data from the DB.
|
726 |
+
*
|
727 |
+
* @since 5.1.9
|
728 |
+
*
|
729 |
+
* @return bool
|
730 |
+
*/
|
731 |
+
public function delete_signup_data() {
|
732 |
+
return delete_option( $this->get_signup_data_key() );
|
733 |
+
}
|
734 |
+
|
735 |
+
/**
|
736 |
+
* Saves user info to make sure we have full access later on.
|
737 |
+
*
|
738 |
+
* @since 5.1.9
|
739 |
+
*
|
740 |
+
* @param array $user_info User info from the PayPal API.
|
741 |
+
*
|
742 |
+
* @return bool
|
743 |
+
*/
|
744 |
+
public function save_user_info( array $user_info = [] ) {
|
745 |
+
return update_option( $this->get_user_info_key(), $user_info );
|
746 |
+
}
|
747 |
+
|
748 |
+
/**
|
749 |
+
* Deletes the user info from the DB.
|
750 |
+
*
|
751 |
+
* @since 5.1.9
|
752 |
+
*
|
753 |
+
* @return bool
|
754 |
+
*/
|
755 |
+
public function delete_user_info() {
|
756 |
+
return delete_option( $this->get_user_info_key() );
|
757 |
+
}
|
758 |
+
|
759 |
+
/**
|
760 |
+
* Saves signup data from the transient into
|
761 |
+
*
|
762 |
+
* @since 5.1.9
|
763 |
+
*
|
764 |
+
* @return array
|
765 |
+
*/
|
766 |
+
public function get_user_info() {
|
767 |
+
return get_option( $this->get_user_info_key(), [] );
|
768 |
+
}
|
769 |
+
|
770 |
+
/**
|
771 |
+
* Returns whether or not the account has been connected
|
772 |
+
*
|
773 |
+
* @since 5.1.9
|
774 |
+
*
|
775 |
+
* @return bool
|
776 |
+
*/
|
777 |
+
public function account_is_connected() {
|
778 |
+
return tribe_is_truthy( $this->merchant_id_in_paypal );
|
779 |
+
}
|
780 |
+
|
781 |
+
/**
|
782 |
+
* Disconnects the merchant completely.
|
783 |
+
*
|
784 |
+
* @since 5.1.9
|
785 |
+
*
|
786 |
+
* @return bool
|
787 |
+
*/
|
788 |
+
public function disconnect() {
|
789 |
+
$statuses = [
|
790 |
+
$this->delete_data(),
|
791 |
+
$this->delete_access_token_data(),
|
792 |
+
$this->delete_signup_data(),
|
793 |
+
$this->delete_user_info(),
|
794 |
+
$this->delete_account_errors(),
|
795 |
+
];
|
796 |
+
|
797 |
+
return in_array( false, $statuses, true );
|
798 |
+
}
|
799 |
+
|
800 |
+
/**
|
801 |
+
* Determines if the Merchant is active.
|
802 |
+
*
|
803 |
+
* @since 5.1.9
|
804 |
+
*
|
805 |
+
* @return bool
|
806 |
+
*/
|
807 |
+
public function is_active( $recheck = false ) {
|
808 |
+
$saved_merchant_id = $this->get_merchant_id_in_paypal();
|
809 |
+
|
810 |
+
if ( ! $saved_merchant_id ) {
|
811 |
+
return false;
|
812 |
+
}
|
813 |
+
|
814 |
+
if ( ! $recheck && true === $this->get_account_is_ready() ) {
|
815 |
+
return true;
|
816 |
+
}
|
817 |
+
|
818 |
+
$seller_status = tribe( WhoDat::class )->get_seller_status( $saved_merchant_id );
|
819 |
+
|
820 |
+
$payments_receivable = Arr::get( $seller_status, 'payments_receivable' );
|
821 |
+
$paypal_product_name = Arr::get( $seller_status, [ 'products', 0, 'name' ] );
|
822 |
+
$paypal_product_status = Arr::get( $seller_status, [ 'products', 0, 'status' ] );
|
823 |
+
|
824 |
+
$is_active = ( true === $payments_receivable && 'EXPRESS_CHECKOUT' === $paypal_product_name && 'ACTIVE' === $paypal_product_status );
|
825 |
+
|
826 |
+
if ( $is_active ) {
|
827 |
+
$this->set_account_is_ready( true );
|
828 |
+
$this->save();
|
829 |
+
}
|
830 |
+
|
831 |
+
return $is_active;
|
832 |
+
}
|
833 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/{SDK/Models/PayPalOrder.php → Models/PayPal_Order.php}
RENAMED
@@ -1,18 +1,18 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\
|
4 |
|
5 |
use InvalidArgumentException;
|
6 |
use stdClass;
|
7 |
|
8 |
/**
|
9 |
-
* Class
|
10 |
*
|
11 |
-
* @since
|
12 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
13 |
*
|
14 |
*/
|
15 |
-
class
|
16 |
|
17 |
/**
|
18 |
* Order Id.
|
@@ -48,7 +48,7 @@ class PayPalOrder {
|
|
48 |
*
|
49 |
* @var string
|
50 |
*/
|
51 |
-
public $
|
52 |
|
53 |
/**
|
54 |
* Order update time.
|
@@ -57,7 +57,7 @@ class PayPalOrder {
|
|
57 |
*
|
58 |
* @var string
|
59 |
*/
|
60 |
-
public $
|
61 |
|
62 |
/**
|
63 |
* PayPal Order action links.
|
@@ -84,14 +84,14 @@ class PayPalOrder {
|
|
84 |
*
|
85 |
* @var stdClass
|
86 |
*/
|
87 |
-
private $
|
88 |
|
89 |
/**
|
90 |
* Payment details for order.
|
91 |
*
|
92 |
* @since 5.1.6
|
93 |
*
|
94 |
-
* @var
|
95 |
*/
|
96 |
public $payment;
|
97 |
|
@@ -102,28 +102,25 @@ class PayPalOrder {
|
|
102 |
*
|
103 |
* @param $array
|
104 |
*
|
105 |
-
* @return
|
106 |
*/
|
107 |
-
public static function
|
108 |
-
/* @var
|
109 |
$order = tribe( __CLASS__ );
|
110 |
|
111 |
$order->validate( $array );
|
112 |
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
foreach ( $array as $itemName => $value ) {
|
117 |
-
if ( 'purchaseUnits' === $itemName ) {
|
118 |
$value = current( $value );
|
119 |
|
120 |
-
$order->
|
121 |
-
$order->payment
|
122 |
|
123 |
continue;
|
124 |
}
|
125 |
|
126 |
-
$order->{$
|
127 |
}
|
128 |
|
129 |
return $order;
|
@@ -134,9 +131,10 @@ class PayPalOrder {
|
|
134 |
*
|
135 |
* @since 5.1.6
|
136 |
*
|
|
|
|
|
137 |
* @param array $array
|
138 |
*
|
139 |
-
* @throws InvalidArgumentException
|
140 |
*/
|
141 |
private function validate( $array ) {
|
142 |
$required = [
|
1 |
<?php
|
2 |
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\Models;
|
4 |
|
5 |
use InvalidArgumentException;
|
6 |
use stdClass;
|
7 |
|
8 |
/**
|
9 |
+
* Class Order
|
10 |
*
|
11 |
+
* @since 5.1.6
|
12 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal\Models
|
13 |
*
|
14 |
*/
|
15 |
+
class PayPal_Order {
|
16 |
|
17 |
/**
|
18 |
* Order Id.
|
48 |
*
|
49 |
* @var string
|
50 |
*/
|
51 |
+
public $create_time;
|
52 |
|
53 |
/**
|
54 |
* Order update time.
|
57 |
*
|
58 |
* @var string
|
59 |
*/
|
60 |
+
public $update_time;
|
61 |
|
62 |
/**
|
63 |
* PayPal Order action links.
|
84 |
*
|
85 |
* @var stdClass
|
86 |
*/
|
87 |
+
private $purchase_unit;
|
88 |
|
89 |
/**
|
90 |
* Payment details for order.
|
91 |
*
|
92 |
* @since 5.1.6
|
93 |
*
|
94 |
+
* @var PayPal_Payment
|
95 |
*/
|
96 |
public $payment;
|
97 |
|
102 |
*
|
103 |
* @param $array
|
104 |
*
|
105 |
+
* @return PayPal_Order
|
106 |
*/
|
107 |
+
public static function from_array( $array ) {
|
108 |
+
/* @var PayPal_Order $order */
|
109 |
$order = tribe( __CLASS__ );
|
110 |
|
111 |
$order->validate( $array );
|
112 |
|
113 |
+
foreach ( $array as $item_name => $value ) {
|
114 |
+
if ( 'purchase_units' === $item_name ) {
|
|
|
|
|
|
|
115 |
$value = current( $value );
|
116 |
|
117 |
+
$order->purchase_unit = $value;
|
118 |
+
$order->payment = PayPal_Payment::from_array( (array) current( $order->purchase_unit->payments->captures ) );
|
119 |
|
120 |
continue;
|
121 |
}
|
122 |
|
123 |
+
$order->{$item_name} = $value;
|
124 |
}
|
125 |
|
126 |
return $order;
|
131 |
*
|
132 |
* @since 5.1.6
|
133 |
*
|
134 |
+
* @throws InvalidArgumentException
|
135 |
+
*
|
136 |
* @param array $array
|
137 |
*
|
|
|
138 |
*/
|
139 |
private function validate( $array ) {
|
140 |
$required = [
|
src/Tickets/Commerce/Gateways/PayPal/{SDK/Models/PayPalPayment.php → Models/PayPal_Payment.php}
RENAMED
@@ -1,17 +1,17 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\
|
4 |
|
5 |
use InvalidArgumentException;
|
6 |
|
7 |
/**
|
8 |
-
* Class
|
9 |
*
|
10 |
-
* @since
|
11 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
12 |
*
|
13 |
*/
|
14 |
-
class
|
15 |
|
16 |
/**
|
17 |
* Payment Id.
|
@@ -47,7 +47,7 @@ class PayPalPayment {
|
|
47 |
*
|
48 |
* @var string
|
49 |
*/
|
50 |
-
public $
|
51 |
|
52 |
/**
|
53 |
* Payment update time.
|
@@ -56,7 +56,7 @@ class PayPalPayment {
|
|
56 |
*
|
57 |
* @var string
|
58 |
*/
|
59 |
-
public $
|
60 |
|
61 |
/**
|
62 |
* PayPal Payment action links.
|
@@ -77,10 +77,10 @@ class PayPalPayment {
|
|
77 |
*
|
78 |
* @param $array
|
79 |
*
|
80 |
-
* @return
|
81 |
*/
|
82 |
-
public static function
|
83 |
-
/* @var
|
84 |
$payment = tribe( __CLASS__ );
|
85 |
|
86 |
$payment->validate( $array );
|
@@ -88,8 +88,8 @@ class PayPalPayment {
|
|
88 |
// @todo Replace this with a new method somewhere else.
|
89 |
$array = ArrayDataSet::camelCaseKeys( $array );
|
90 |
|
91 |
-
foreach ( $array as $
|
92 |
-
$payment->{$
|
93 |
}
|
94 |
|
95 |
return $payment;
|
@@ -100,9 +100,10 @@ class PayPalPayment {
|
|
100 |
*
|
101 |
* @since 5.1.6
|
102 |
*
|
|
|
|
|
103 |
* @param array $array
|
104 |
*
|
105 |
-
* @throws InvalidArgumentException
|
106 |
*/
|
107 |
private function validate( $array ) {
|
108 |
$required = [ 'id', 'amount', 'status', 'create_time', 'update_time', 'links' ];
|
1 |
<?php
|
2 |
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\Models;
|
4 |
|
5 |
use InvalidArgumentException;
|
6 |
|
7 |
/**
|
8 |
+
* Class PayPal_Payment
|
9 |
*
|
10 |
+
* @since 5.1.6
|
11 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal\Models
|
12 |
*
|
13 |
*/
|
14 |
+
class PayPal_Payment {
|
15 |
|
16 |
/**
|
17 |
* Payment Id.
|
47 |
*
|
48 |
* @var string
|
49 |
*/
|
50 |
+
public $create_time;
|
51 |
|
52 |
/**
|
53 |
* Payment update time.
|
56 |
*
|
57 |
* @var string
|
58 |
*/
|
59 |
+
public $update_time;
|
60 |
|
61 |
/**
|
62 |
* PayPal Payment action links.
|
77 |
*
|
78 |
* @param $array
|
79 |
*
|
80 |
+
* @return PayPal_Payment
|
81 |
*/
|
82 |
+
public static function from_array( $array ) {
|
83 |
+
/* @var PayPal_Payment $payment */
|
84 |
$payment = tribe( __CLASS__ );
|
85 |
|
86 |
$payment->validate( $array );
|
88 |
// @todo Replace this with a new method somewhere else.
|
89 |
$array = ArrayDataSet::camelCaseKeys( $array );
|
90 |
|
91 |
+
foreach ( $array as $item_name => $value ) {
|
92 |
+
$payment->{$item_name} = $value;
|
93 |
}
|
94 |
|
95 |
return $payment;
|
100 |
*
|
101 |
* @since 5.1.6
|
102 |
*
|
103 |
+
* @throws InvalidArgumentException
|
104 |
+
*
|
105 |
* @param array $array
|
106 |
*
|
|
|
107 |
*/
|
108 |
private function validate( $array ) {
|
109 |
$required = [ 'id', 'amount', 'status', 'create_time', 'update_time', 'links' ];
|
src/Tickets/Commerce/Gateways/PayPal/Models/Webhook_Config.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\Models;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Webhook_Config.
|
7 |
+
*
|
8 |
+
* @since 5.1.6
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal\Models
|
11 |
+
*/
|
12 |
+
class Webhook_Config {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @since 5.1.6
|
16 |
+
*
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
public $id;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @since 5.1.6
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
public $return_url;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @since 5.1.6
|
30 |
+
*
|
31 |
+
* @var string[]
|
32 |
+
*/
|
33 |
+
public $events;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Webhook_Config constructor.
|
37 |
+
*
|
38 |
+
* @since 5.1.6
|
39 |
+
*
|
40 |
+
* @param string $id
|
41 |
+
* @param string $return_url
|
42 |
+
* @param string[] $events
|
43 |
+
*/
|
44 |
+
public function __construct( $id, $return_url, $events ) {
|
45 |
+
$this->id = $id;
|
46 |
+
$this->return_url = $return_url;
|
47 |
+
$this->events = $events;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Generates an instance from serialized data
|
52 |
+
*
|
53 |
+
* @since 5.1.6
|
54 |
+
*
|
55 |
+
* @param array $data
|
56 |
+
*
|
57 |
+
* @return Webhook_Config
|
58 |
+
*/
|
59 |
+
public static function from_array( array $data ) {
|
60 |
+
return new self( $data['id'], $data['return_url'], $data['events'] );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Generates an array for serialization
|
65 |
+
*
|
66 |
+
* @since 5.1.6
|
67 |
+
*
|
68 |
+
* @return array
|
69 |
+
*/
|
70 |
+
public function to_array() {
|
71 |
+
return [
|
72 |
+
'id' => $this->id,
|
73 |
+
'return_url' => $this->return_url,
|
74 |
+
'events' => $this->events,
|
75 |
+
];
|
76 |
+
}
|
77 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php
ADDED
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
|
5 |
+
use Exception;
|
6 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Repositories\Webhooks;
|
7 |
+
use Tribe__Settings;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class On_Boarding_Redirect_Handler
|
11 |
+
*
|
12 |
+
* @todo This whole file will stop exsiting once we deprecate all Give's code usage.
|
13 |
+
*
|
14 |
+
* @since 5.1.6
|
15 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
16 |
+
*
|
17 |
+
*/
|
18 |
+
class On_Boarding_Redirect_Handler {
|
19 |
+
/**
|
20 |
+
* Sets up the webhook for the connected account
|
21 |
+
*
|
22 |
+
* @since 5.1.6
|
23 |
+
*/
|
24 |
+
private function set_up_webhook() {
|
25 |
+
if ( ! is_ssl() ) {
|
26 |
+
return;
|
27 |
+
}
|
28 |
+
|
29 |
+
try {
|
30 |
+
$webhook_config = $this->webhooks_repository->create_webhook( $this->merchant->get_access_token() );
|
31 |
+
|
32 |
+
$this->webhooks_repository->save_webhook_config( $webhook_config );
|
33 |
+
} catch ( Exception $ex ) {
|
34 |
+
tribe( 'logger' )->log_error( $ex->getMessage(), 'tickets-commerce-paypal-commerce' );
|
35 |
+
|
36 |
+
$errors = [];
|
37 |
+
|
38 |
+
$errors[] = esc_html__( 'There was a problem with creating webhook on PayPal. A gateway error log also added to get details information about PayPal response.', 'event-tickets' );
|
39 |
+
|
40 |
+
// Log error messages.
|
41 |
+
array_map( static function ( $error_message ) {
|
42 |
+
$error_message = is_array( $error_message ) ? $error_message['message'] . ' ' . $error_message['value'] : $error_message;
|
43 |
+
tribe( 'logger' )->log_error( $error_message, 'tickets-commerce-paypal-commerce' );
|
44 |
+
}, $errors );
|
45 |
+
|
46 |
+
$this->merchant->save_account_errors( $errors );
|
47 |
+
$this->redirect_when_on_boarding_fail();
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Validate rest api credential.
|
53 |
+
*
|
54 |
+
* @since 5.1.6
|
55 |
+
*
|
56 |
+
* @param array $array
|
57 |
+
*
|
58 |
+
*/
|
59 |
+
private function did_we_get_valid_seller_rest_api_credentials( $array ) {
|
60 |
+
$required = [ 'client_id', 'client_secret' ];
|
61 |
+
$array = array_filter( $array ); // Remove empty values.
|
62 |
+
|
63 |
+
$errors = [];
|
64 |
+
|
65 |
+
if ( array_diff( $required, array_keys( $array ) ) ) {
|
66 |
+
$errors[] = [
|
67 |
+
'type' => 'json',
|
68 |
+
'message' => esc_html__( 'PayPal client access token API request response is:', 'event-tickets' ),
|
69 |
+
'value' => wp_json_encode( $this->settings->get_access_token() ),
|
70 |
+
];
|
71 |
+
|
72 |
+
$errors[] = [
|
73 |
+
'type' => 'json',
|
74 |
+
'message' => esc_html__( 'PayPal client rest API credentials API request response is:', 'event-tickets' ),
|
75 |
+
'value' => wp_json_encode( $array ),
|
76 |
+
];
|
77 |
+
|
78 |
+
$errors[] = esc_html__( 'There was a problem with PayPal client rest API request and we could not find valid client id and secret.', 'event-tickets' );
|
79 |
+
|
80 |
+
// Log error messages.
|
81 |
+
array_map( static function ( $error_message ) {
|
82 |
+
$error_message = is_array( $error_message ) ? $error_message['message'] . ' ' . $error_message['value'] : $error_message;
|
83 |
+
tribe( 'logger' )->log_error( $error_message, 'tickets-commerce-paypal-commerce' );
|
84 |
+
}, $errors );
|
85 |
+
|
86 |
+
$this->merchant->save_account_errors( $errors );
|
87 |
+
//$this->redirect_when_on_boarding_fail();
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Validate seller on Boarding status.
|
93 |
+
*
|
94 |
+
* @since 5.1.6
|
95 |
+
*
|
96 |
+
* @param string $merchant_id
|
97 |
+
* @param string $access_token
|
98 |
+
* @param bool $uses_custom_payments
|
99 |
+
*
|
100 |
+
* @return bool|string[]
|
101 |
+
*/
|
102 |
+
private function is_admin_successfully_on_boarded( $merchant_id, $access_token, $uses_custom_payments ) {
|
103 |
+
$on_boarded_data = (array) tribe( WhoDat::class )->get_seller_on_boarding_details_from_paypal( $merchant_id, $access_token );
|
104 |
+
$on_boarded_data = array_filter( $on_boarded_data ); // Remove empty values.
|
105 |
+
$error_messages[] = [
|
106 |
+
'type' => 'json',
|
107 |
+
'message' => esc_html__( 'PayPal merchant status check API request response is:', 'event-tickets' ),
|
108 |
+
'value' => wp_json_encode( $on_boarded_data ),
|
109 |
+
];
|
110 |
+
|
111 |
+
if ( ! is_ssl() ) {
|
112 |
+
$error_messages[] = esc_html__( 'A valid SSL certificate is required to accept payments and set up your PayPal account. Once a
|
113 |
+
certificate is installed and the site is using https, please disconnect and reconnect your account.', 'event-tickets' );
|
114 |
+
}
|
115 |
+
|
116 |
+
if ( array_diff( [ 'payments_receivable', 'primary_email_confirmed' ], array_keys( $on_boarded_data ) ) ) {
|
117 |
+
$error_messages[] = esc_html__( 'There was a problem with the status check for your account. Please try disconnecting and connecting again. If the problem persists, please contact support.', 'event-tickets' );
|
118 |
+
|
119 |
+
// Log error messages.
|
120 |
+
array_map( static function ( $error_message ) {
|
121 |
+
$error_message = is_array( $error_message ) ? $error_message['message'] . ' ' . $error_message['value'] : $error_message;
|
122 |
+
tribe( 'logger' )->log_error( $error_message, 'tickets-commerce-paypal-commerce' );
|
123 |
+
}, $error_messages );
|
124 |
+
|
125 |
+
// Return here since the rest of the validations will definitely fail
|
126 |
+
return $error_messages;
|
127 |
+
}
|
128 |
+
|
129 |
+
if ( ! $on_boarded_data['payments_receivable'] ) {
|
130 |
+
$error_messages[] = esc_html__( 'Set up an account to receive payment from PayPal', 'event-tickets' );
|
131 |
+
}
|
132 |
+
|
133 |
+
if ( ! $on_boarded_data['primary_email_confirmed'] ) {
|
134 |
+
$error_messages[] = esc_html__( 'Confirm your primary email address', 'event-tickets' );
|
135 |
+
}
|
136 |
+
|
137 |
+
if ( ! $uses_custom_payments ) {
|
138 |
+
return count( $error_messages ) > 1 ? $error_messages : true;
|
139 |
+
}
|
140 |
+
|
141 |
+
if ( array_diff( [ 'products', 'capabilities' ], array_keys( $on_boarded_data ) ) ) {
|
142 |
+
$error_messages[] = esc_html__( 'Your account was expected to be able to accept custom payments, but is not. Please make sure your
|
143 |
+
account country matches the country setting. If the problem persists, please contact PayPal.', 'event-tickets' );
|
144 |
+
|
145 |
+
// Return here since the rest of the validations will definitely fail
|
146 |
+
return $error_messages;
|
147 |
+
}
|
148 |
+
|
149 |
+
// Grab the PPCP_CUSTOM product from the status data
|
150 |
+
$custom_product = current(
|
151 |
+
array_filter(
|
152 |
+
$on_boarded_data['products'],
|
153 |
+
static function ( $product ) {
|
154 |
+
return 'PPCP_CUSTOM' === $product['name'];
|
155 |
+
}
|
156 |
+
)
|
157 |
+
);
|
158 |
+
|
159 |
+
if ( empty( $custom_product ) || $custom_product['vetting_status'] !== 'SUBSCRIBED' ) {
|
160 |
+
$error_messages[] = esc_html__( 'Reach out to PayPal to enable PPCP_CUSTOM for your account', 'event-tickets' );
|
161 |
+
}
|
162 |
+
|
163 |
+
// Loop through the capabilities and see if any are not active
|
164 |
+
$invalid_capabilities = [];
|
165 |
+
foreach ( $on_boarded_data['capabilities'] as $capability ) {
|
166 |
+
if ( $capability['status'] !== 'ACTIVE' ) {
|
167 |
+
$invalid_capabilities[] = $capability['name'];
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
+
if ( ! empty( $invalid_capabilities ) ) {
|
172 |
+
$error_messages[] = esc_html__( 'Reach out to PayPal to resolve the following capabilities:', 'event-tickets' ) . ' ' . implode( ', ', $invalid_capabilities );
|
173 |
+
}
|
174 |
+
|
175 |
+
// If there were errors then redirect the user with notices
|
176 |
+
return count( $error_messages ) > 1 ? $error_messages : true;
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Displays a notice of the site is not using SSL.
|
181 |
+
*
|
182 |
+
* @since 5.1.6
|
183 |
+
*/
|
184 |
+
private function register_paypal_ssl_notice() {
|
185 |
+
if ( ! is_ssl() || ! empty( $this->webhooks_repository->get_webhook_config() ) ) {
|
186 |
+
return;
|
187 |
+
}
|
188 |
+
|
189 |
+
/** @var Tribe__Settings $settings */
|
190 |
+
$settings = tribe( 'settings' );
|
191 |
+
|
192 |
+
// Get link to Help page.
|
193 |
+
$log_url = $settings->get_url( [
|
194 |
+
'page' => 'tribe-help',
|
195 |
+
] ) . '#tribe-event-log';
|
196 |
+
|
197 |
+
$log_link = sprintf(
|
198 |
+
'<a href="%1$s">%2$s</a>',
|
199 |
+
$log_url,
|
200 |
+
esc_html__( 'logged data', 'event-tickets' )
|
201 |
+
);
|
202 |
+
|
203 |
+
tribe_error(
|
204 |
+
'paypal-webhook-error',
|
205 |
+
sprintf(
|
206 |
+
// Translators: %1$s: The logged data link.
|
207 |
+
esc_html__( 'There was a problem setting up the webhooks for your PayPal account. Please try disconnecting and reconnecting your PayPal account. If the problem persists, please contact support and provide them with the latest %1$s', 'event-tickets' ),
|
208 |
+
$log_link
|
209 |
+
),
|
210 |
+
[
|
211 |
+
'type' => 'error',
|
212 |
+
]
|
213 |
+
);
|
214 |
+
}
|
215 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Provider.php
CHANGED
@@ -2,8 +2,6 @@
|
|
2 |
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
|
5 |
-
use Tribe\Tickets\REST\V1\Endpoints\Commerce\PayPal_Webhook;
|
6 |
-
|
7 |
/**
|
8 |
* Service provider for the Tickets Commerce: PayPal Commerce gateway.
|
9 |
*
|
@@ -25,36 +23,30 @@ class Provider extends \tad_DI52_ServiceProvider {
|
|
25 |
|
26 |
// @todo Is this needed?
|
27 |
// $this->container->singleton( PaymentFormElements::class );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
-
|
30 |
-
$this->container->singleton(
|
31 |
-
|
32 |
-
$this->container->singleton(
|
33 |
-
|
34 |
-
$this->container->singleton(
|
35 |
-
$this->container->singleton(
|
36 |
-
|
37 |
-
|
38 |
-
$this->container->singleton( SDK\Models\MerchantDetail::class, null, [ 'init' ] );
|
39 |
-
$this->container->singleton( SDK\Repositories\MerchantDetails::class, null, [ 'init' ] );
|
40 |
-
|
41 |
-
$this->container->singleton( Webhooks\WebhookRegister::class );
|
42 |
-
$this->container->singleton( Webhooks\WebhooksRoute::class );
|
43 |
-
$this->container->singleton( SDK\Repositories\Webhooks::class, null, [ 'init' ] );
|
44 |
-
|
45 |
-
$this->container->singleton( Webhooks\Listeners\PaymentCaptureCompleted::class );
|
46 |
-
$this->container->singleton( Webhooks\Listeners\PaymentCaptureDenied::class );
|
47 |
-
$this->container->singleton( Webhooks\Listeners\PaymentCaptureRefunded::class );
|
48 |
-
$this->container->singleton( Webhooks\Listeners\PaymentCaptureReversed::class );
|
49 |
-
|
50 |
-
$this->container->singleton( REST::class );
|
51 |
-
$this->container->singleton( PayPal_Webhook::class, static function() {
|
52 |
-
return new PayPal_Webhook(
|
53 |
-
tribe( 'tickets.rest-v1.messages' ),
|
54 |
-
tribe( 'tickets.rest-v1.repository' ),
|
55 |
-
tribe( 'tickets.rest-v1.validator' )
|
56 |
-
);
|
57 |
-
} );
|
58 |
}
|
59 |
|
60 |
/**
|
@@ -88,7 +80,11 @@ class Provider extends \tad_DI52_ServiceProvider {
|
|
88 |
* @since 5.1.6
|
89 |
*/
|
90 |
public function register_endpoints() {
|
|
|
|
|
91 |
|
|
|
|
|
92 |
}
|
93 |
|
94 |
}
|
2 |
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
|
|
|
|
|
5 |
/**
|
6 |
* Service provider for the Tickets Commerce: PayPal Commerce gateway.
|
7 |
*
|
23 |
|
24 |
// @todo Is this needed?
|
25 |
// $this->container->singleton( PaymentFormElements::class );
|
26 |
+
// $this->container->singleton( PaymentProcessor::class );
|
27 |
+
|
28 |
+
$this->container->singleton( Merchant::class, Merchant::class, [ 'init' ] );
|
29 |
+
|
30 |
+
$this->container->singleton( Ajax_Request_Handler::class );
|
31 |
+
$this->container->singleton( On_Boarding_Redirect_Handler::class );
|
32 |
+
$this->container->singleton( Refresh_Token::class );
|
33 |
+
$this->container->singleton( Client::class );
|
34 |
+
$this->container->singleton( Signup::class );
|
35 |
+
$this->container->singleton( Status::class );
|
36 |
+
|
37 |
+
$this->container->singleton( Repositories\Authorization::class );
|
38 |
+
$this->container->singleton( Repositories\Order::class );
|
39 |
+
$this->container->singleton( Repositories\Webhooks::class );
|
40 |
|
41 |
+
$this->container->singleton( Webhooks\Webhook_Register::class );
|
42 |
+
$this->container->singleton( Webhooks\Webhooks_Route::class );
|
43 |
+
|
44 |
+
$this->container->singleton( Webhooks\Listeners\Payment_Capture_Completed::class );
|
45 |
+
$this->container->singleton( Webhooks\Listeners\Payment_Capture_Denied::class );
|
46 |
+
$this->container->singleton( Webhooks\Listeners\Payment_Capture_Refunded::class );
|
47 |
+
$this->container->singleton( Webhooks\Listeners\Payment_Capture_Reversed::class );
|
48 |
+
|
49 |
+
$this->register_endpoints();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
|
52 |
/**
|
80 |
* @since 5.1.6
|
81 |
*/
|
82 |
public function register_endpoints() {
|
83 |
+
$hooks = new REST( $this->container );
|
84 |
+
$hooks->register();
|
85 |
|
86 |
+
// Allow Hooks to be removed, by having the them registered to the container
|
87 |
+
$this->container->singleton( REST::class, $hooks );
|
88 |
}
|
89 |
|
90 |
}
|
src/Tickets/Commerce/Gateways/PayPal/REST.php
CHANGED
@@ -2,38 +2,19 @@
|
|
2 |
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
|
5 |
-
use Tribe\Tickets\REST\V1\Endpoints\Commerce\PayPal_Webhook;
|
6 |
use WP_REST_Server;
|
7 |
|
8 |
/**
|
9 |
* Class REST
|
10 |
*
|
11 |
-
* @since 5.1.
|
12 |
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
13 |
*/
|
14 |
-
class REST {
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
* @since 5.1.6
|
20 |
-
*
|
21 |
-
* @var string
|
22 |
-
*/
|
23 |
-
public $namespace = '';
|
24 |
-
|
25 |
-
/**
|
26 |
-
* The REST API documentation endpoint.
|
27 |
-
*
|
28 |
-
* @since 5.1.6
|
29 |
-
*
|
30 |
-
* @var \Tribe__Tickets__REST__V1__Endpoints__Swagger_Documentation
|
31 |
-
*/
|
32 |
-
public $documentation;
|
33 |
-
|
34 |
-
public function __construct() {
|
35 |
-
$this->namespace = tribe( 'tickets.rest-v1.main' )->get_events_route_namespace();
|
36 |
-
$this->documentation = tribe( 'tickets.rest-v1.endpoints.documentation' );
|
37 |
}
|
38 |
|
39 |
/**
|
@@ -42,20 +23,7 @@ class REST {
|
|
42 |
* @since 5.1.6
|
43 |
*/
|
44 |
public function register_endpoints() {
|
45 |
-
|
46 |
-
$
|
47 |
-
|
48 |
-
register_rest_route(
|
49 |
-
$this->namespace,
|
50 |
-
$endpoint->path,
|
51 |
-
[
|
52 |
-
'methods' => WP_REST_Server::CREATABLE,
|
53 |
-
'args' => $endpoint->CREATE_args(),
|
54 |
-
'callback' => [ $endpoint, 'create' ],
|
55 |
-
'permission_callback' => '__return_true',
|
56 |
-
]
|
57 |
-
);
|
58 |
-
|
59 |
-
$this->documentation->register_documentation_provider( $endpoint->path, $endpoint );
|
60 |
}
|
61 |
}
|
2 |
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
|
|
|
5 |
use WP_REST_Server;
|
6 |
|
7 |
/**
|
8 |
* Class REST
|
9 |
*
|
10 |
+
* @since 5.1.9
|
11 |
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
12 |
*/
|
13 |
+
class REST extends \tad_DI52_ServiceProvider {
|
14 |
+
public function register() {
|
15 |
+
// $this->container->singleton( REST\Webhook_Endpoint::class, [ $this, 'boot_webhook_endpoint' ] );
|
16 |
+
$this->container->singleton( REST\On_Boarding_Endpoint::class );
|
17 |
+
$this->container->singleton( REST\Order_Endpoint::class );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
}
|
19 |
|
20 |
/**
|
23 |
* @since 5.1.6
|
24 |
*/
|
25 |
public function register_endpoints() {
|
26 |
+
$this->container->make( REST\On_Boarding_Endpoint::class )->register();
|
27 |
+
$this->container->make( REST\Order_Endpoint::class )->register();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
}
|
29 |
}
|
src/Tickets/Commerce/Gateways/PayPal/REST/On_Boarding_Endpoint.php
ADDED
@@ -0,0 +1,433 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\REST;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Client;
|
6 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
7 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Refresh_Token;
|
8 |
+
|
9 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Signup;
|
10 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\WhoDat;
|
11 |
+
use Tribe__Documentation__Swagger__Provider_Interface;
|
12 |
+
use Tribe__Settings;
|
13 |
+
use Tribe__Utils__Array as Arr;
|
14 |
+
|
15 |
+
use WP_Error;
|
16 |
+
use WP_REST_Request;
|
17 |
+
use WP_REST_Response;
|
18 |
+
use WP_REST_Server;
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Class On_Boarding_Endpoint
|
23 |
+
*
|
24 |
+
* @since 5.1.9
|
25 |
+
*
|
26 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal\REST
|
27 |
+
*/
|
28 |
+
class On_Boarding_Endpoint implements Tribe__Documentation__Swagger__Provider_Interface {
|
29 |
+
|
30 |
+
/**
|
31 |
+
* The REST API endpoint path.
|
32 |
+
*
|
33 |
+
* @since 5.1.9
|
34 |
+
*
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
protected $path = '/commerce/paypal/on-boarding';
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Register the actual endpoint on WP Rest API.
|
41 |
+
*
|
42 |
+
* @since 5.1.9
|
43 |
+
*/
|
44 |
+
public function register() {
|
45 |
+
$namespace = tribe( 'tickets.rest-v1.main' )->get_events_route_namespace();
|
46 |
+
$documentation = tribe( 'tickets.rest-v1.endpoints.documentation' );
|
47 |
+
|
48 |
+
register_rest_route(
|
49 |
+
$namespace,
|
50 |
+
$this->get_endpoint_path(),
|
51 |
+
[
|
52 |
+
'methods' => WP_REST_Server::CREATABLE,
|
53 |
+
'args' => $this->fetch_token_args(),
|
54 |
+
'callback' => [ $this, 'handle_fetch_token' ],
|
55 |
+
'permission_callback' => '__return_true',
|
56 |
+
]
|
57 |
+
);
|
58 |
+
|
59 |
+
register_rest_route(
|
60 |
+
$namespace,
|
61 |
+
$this->get_endpoint_path(),
|
62 |
+
[
|
63 |
+
'methods' => WP_REST_Server::READABLE,
|
64 |
+
'args' => $this->signup_redirect_args(),
|
65 |
+
'callback' => [ $this, 'handle_signup_redirect' ],
|
66 |
+
'permission_callback' => '__return_true',
|
67 |
+
]
|
68 |
+
);
|
69 |
+
|
70 |
+
$documentation->register_documentation_provider( $this->get_endpoint_path(), $this );
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Gets the Endpoint path for the on boarding process.
|
75 |
+
*
|
76 |
+
* @since 5.1.9
|
77 |
+
*
|
78 |
+
* @return string
|
79 |
+
*/
|
80 |
+
public function get_endpoint_path() {
|
81 |
+
return $this->path;
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Get the REST API route URL.
|
86 |
+
*
|
87 |
+
* @since 5.1.9
|
88 |
+
*
|
89 |
+
* @return string The REST API route URL.
|
90 |
+
*/
|
91 |
+
public function get_route_url() {
|
92 |
+
$namespace = tribe( 'tickets.rest-v1.main' )->get_events_route_namespace();
|
93 |
+
|
94 |
+
return rest_url( '/' . $namespace . $this->get_endpoint_path(), 'https' );
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Gets the Return URL pointing to this on boarding route.
|
99 |
+
*
|
100 |
+
* @since 5.1.9
|
101 |
+
*
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
public function get_return_url( $hash = null ) {
|
105 |
+
$arguments = [
|
106 |
+
'hash' => $hash,
|
107 |
+
];
|
108 |
+
|
109 |
+
return add_query_arg( $arguments, $this->get_route_url() );
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Handles the request that happens in parallel to the User Signup on PayPal but before we redirect the user from
|
114 |
+
* the mini browser. So when passing error messages, they need to be registered to be fetched in the FE.
|
115 |
+
*
|
116 |
+
* @since 5.1.9
|
117 |
+
*
|
118 |
+
* @param WP_REST_Request $request The request object.
|
119 |
+
*
|
120 |
+
* @return WP_REST_Response An array containing the data on success or a WP_Error instance on failure.
|
121 |
+
*/
|
122 |
+
public function handle_fetch_token( WP_REST_Request $request ) {
|
123 |
+
$response = [
|
124 |
+
'success' => false,
|
125 |
+
];
|
126 |
+
|
127 |
+
$signup = tribe( Signup::class );
|
128 |
+
$client = tribe( Client::class );
|
129 |
+
$merchant = tribe( Merchant::class );
|
130 |
+
|
131 |
+
// Send a request to fetch the access token.
|
132 |
+
$paypal_response = $client->get_access_token_from_authorization_code(
|
133 |
+
$request->get_param( 'shared_id' ),
|
134 |
+
$request->get_param( 'auth_code' ),
|
135 |
+
$signup->get_transient_hash()
|
136 |
+
);
|
137 |
+
|
138 |
+
if ( ! $paypal_response || array_key_exists( 'error', $paypal_response ) ) {
|
139 |
+
$response['error'] = __( 'Unexpected response from PayPal when on boarding', 'event-tickets' );
|
140 |
+
|
141 |
+
return new WP_REST_Response( $response );
|
142 |
+
}
|
143 |
+
|
144 |
+
// Save the information on the merchant system.
|
145 |
+
$merchant->save_access_token_data( $paypal_response );
|
146 |
+
|
147 |
+
tribe( Refresh_Token::class )->register_cron_job_to_refresh_token( $paypal_response['expires_in'] );
|
148 |
+
|
149 |
+
$response['success'] = true;
|
150 |
+
|
151 |
+
return new WP_REST_Response( $response );
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* This request is ran when the user is redirected back from the PayPal miniBrowser, and will not respond with
|
156 |
+
* a JSON request, but with a redirect of the user with a success link or error link into the payments tab.
|
157 |
+
*
|
158 |
+
* @since 5.1.9
|
159 |
+
*
|
160 |
+
* @param WP_REST_Request $request The request object.
|
161 |
+
*
|
162 |
+
* @return void This is strictly a redirect response.
|
163 |
+
*/
|
164 |
+
public function handle_signup_redirect( WP_REST_Request $request ) {
|
165 |
+
$signup = tribe( Signup::class );
|
166 |
+
$existing_hash = $signup->get_transient_hash();
|
167 |
+
$request_hash = $request->get_param( 'hash' );
|
168 |
+
$return_url = Tribe__Settings::instance()->get_url( [ 'tab' => 'payments', ] );
|
169 |
+
|
170 |
+
if ( $request_hash !== $existing_hash ) {
|
171 |
+
$this->redirect_with( 'invalid-paypal-signup-hash', $return_url );
|
172 |
+
}
|
173 |
+
|
174 |
+
$seller_data = tribe( WhoDat::class )->get_seller_referral_data( $signup->get_referral_data_link() );
|
175 |
+
$has_custom_payments = in_array( 'PPCP', Arr::get( $seller_data, [ 'referral_data', 'products' ], [] ), true );
|
176 |
+
|
177 |
+
$merchant_id = $request->get_param( 'merchantId' );
|
178 |
+
$merchant_id_in_paypal = $request->get_param( 'merchantIdInPayPal' );
|
179 |
+
|
180 |
+
/**
|
181 |
+
* @todo Need to figure out where this gets saved in the merchant API.
|
182 |
+
*/
|
183 |
+
$permissions_granted = $request->get_param( 'permissionsGranted' );
|
184 |
+
$consent_status = $request->get_param( 'consentStatus' );
|
185 |
+
$account_status = $request->get_param( 'accountStatus' );
|
186 |
+
|
187 |
+
$merchant = tribe( Merchant::class );
|
188 |
+
|
189 |
+
$merchant->save_signup_data( $seller_data );
|
190 |
+
|
191 |
+
$merchant->set_signup_hash( $request_hash );
|
192 |
+
$merchant->set_merchant_id( $merchant_id );
|
193 |
+
$merchant->set_merchant_id_in_paypal( $merchant_id_in_paypal );
|
194 |
+
|
195 |
+
$access_token = $merchant->get_access_token();
|
196 |
+
$credentials = tribe( WhoDat::class )->get_seller_credentials( $access_token );
|
197 |
+
|
198 |
+
if ( ! isset( $credentials['client_id'], $credentials['client_secret'] ) ) {
|
199 |
+
// Save what we have before moving forward.
|
200 |
+
$merchant->save();
|
201 |
+
|
202 |
+
$this->redirect_with( 'invalid-paypal-seller-credentials', $return_url );
|
203 |
+
}
|
204 |
+
|
205 |
+
$merchant->set_client_id( $credentials['client_id'] );
|
206 |
+
$merchant->set_client_secret( $credentials['client_secret'] );
|
207 |
+
$merchant->set_account_is_ready( true );
|
208 |
+
$merchant->set_supports_custom_payments( $has_custom_payments );
|
209 |
+
$merchant->save();
|
210 |
+
|
211 |
+
$client = tribe( Client::class );
|
212 |
+
|
213 |
+
// Pull Access token data.
|
214 |
+
$token_data = $client->get_access_token_from_client_credentials( $credentials['client_id'], $credentials['client_secret'] );
|
215 |
+
$merchant->save_access_token_data( $token_data );
|
216 |
+
|
217 |
+
// Pull user info from PayPal.
|
218 |
+
$user_info = $client->get_user_info();
|
219 |
+
$merchant->save_user_info( $user_info );
|
220 |
+
|
221 |
+
/**
|
222 |
+
* @todo Need to figure out where this gets saved in the merchant API.
|
223 |
+
*/
|
224 |
+
update_option( 'tickets_commerce_permissions_granted', $permissions_granted );
|
225 |
+
update_option( 'tickets_commerce_consent_status', $consent_status );
|
226 |
+
update_option( 'tickets_commerce_account_status', $account_status );
|
227 |
+
|
228 |
+
$this->redirect_with( 'paypal-signup-complete', $return_url );
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Using wp_safe_redirect sends the client back to a given URL after removing the Signup data acquired.
|
233 |
+
*
|
234 |
+
* @since 5.1.9
|
235 |
+
*
|
236 |
+
* @param string $status Which status we will add to the URL
|
237 |
+
* @param string $url Which URL we are sending the client to.
|
238 |
+
* @param array $data Extra that that will be json encoded to the URL.
|
239 |
+
*
|
240 |
+
*/
|
241 |
+
protected function redirect_with( $status, $url, array $data = [] ) {
|
242 |
+
$signup = tribe( Signup::class );
|
243 |
+
|
244 |
+
// We always clean signup data before redirect.
|
245 |
+
$signup->delete_transient_data();
|
246 |
+
$signup->delete_transient_hash();
|
247 |
+
|
248 |
+
$query_args = [ 'tc-status' => $status ];
|
249 |
+
|
250 |
+
if ( ! empty( $data ) ) {
|
251 |
+
$query_args['tc-data'] = wp_json_encode( $data );
|
252 |
+
}
|
253 |
+
|
254 |
+
// Add an status slug to the URL.
|
255 |
+
$url = add_query_arg( $query_args, $url );
|
256 |
+
|
257 |
+
wp_safe_redirect( $url );
|
258 |
+
exit;
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Arguments used for the signup redirect.
|
263 |
+
*
|
264 |
+
* @since 5.1.9
|
265 |
+
*
|
266 |
+
* @return array
|
267 |
+
*/
|
268 |
+
public function signup_redirect_args() {
|
269 |
+
// Webhooks do not send any arguments, only JSON content.
|
270 |
+
return [
|
271 |
+
'hash' => [
|
272 |
+
'description' => 'The nonce validation',
|
273 |
+
'required' => true,
|
274 |
+
'type' => 'string',
|
275 |
+
'validate_callback' => static function ( $value ) {
|
276 |
+
if ( ! is_string( $value ) ) {
|
277 |
+
return new WP_Error( 'rest_invalid_param', 'The wp_nonce argument must be a string.', [ 'status' => 400 ] );
|
278 |
+
}
|
279 |
+
|
280 |
+
return $value;
|
281 |
+
},
|
282 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
283 |
+
],
|
284 |
+
'merchantId' => [
|
285 |
+
'description' => 'The merchant ID',
|
286 |
+
'required' => true,
|
287 |
+
'type' => 'string',
|
288 |
+
'validate_callback' => static function ( $value ) {
|
289 |
+
if ( ! is_string( $value ) ) {
|
290 |
+
return new WP_Error( 'rest_invalid_param', 'The merchantId argument must be a string.', [ 'status' => 400 ] );
|
291 |
+
}
|
292 |
+
|
293 |
+
return $value;
|
294 |
+
},
|
295 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
296 |
+
],
|
297 |
+
'merchantIdInPayPal' => [
|
298 |
+
'description' => 'The merchant ID in PayPal',
|
299 |
+
'required' => true,
|
300 |
+
'type' => 'string',
|
301 |
+
'validate_callback' => static function ( $value ) {
|
302 |
+
if ( ! is_string( $value ) ) {
|
303 |
+
return new WP_Error( 'rest_invalid_param', 'The merchantIdInPayPal argument must be a string.', [ 'status' => 400 ] );
|
304 |
+
}
|
305 |
+
|
306 |
+
return $value;
|
307 |
+
},
|
308 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
309 |
+
],
|
310 |
+
'permissionsGranted' => [
|
311 |
+
'description' => 'The merchant ID in PayPal',
|
312 |
+
'required' => true,
|
313 |
+
'type' => 'string',
|
314 |
+
'validate_callback' => static function ( $value ) {
|
315 |
+
if ( ! is_string( $value ) ) {
|
316 |
+
return new WP_Error( 'rest_invalid_param', 'The permissionsGranted argument must be a string.', [ 'status' => 400 ] );
|
317 |
+
}
|
318 |
+
|
319 |
+
return $value;
|
320 |
+
},
|
321 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
322 |
+
],
|
323 |
+
'consentStatus' => [
|
324 |
+
'description' => 'The merchant ID in PayPal',
|
325 |
+
'required' => true,
|
326 |
+
'type' => 'string',
|
327 |
+
'validate_callback' => static function ( $value ) {
|
328 |
+
if ( ! is_string( $value ) ) {
|
329 |
+
return new WP_Error( 'rest_invalid_param', 'The consentStatus argument must be a string.', [ 'status' => 400 ] );
|
330 |
+
}
|
331 |
+
|
332 |
+
return $value;
|
333 |
+
},
|
334 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
335 |
+
],
|
336 |
+
'accountStatus' => [
|
337 |
+
'description' => 'The merchant ID in PayPal',
|
338 |
+
'required' => true,
|
339 |
+
'type' => 'string',
|
340 |
+
'validate_callback' => static function ( $value ) {
|
341 |
+
if ( ! is_string( $value ) ) {
|
342 |
+
return new WP_Error( 'rest_invalid_param', 'The accountStatus argument must be a string.', [ 'status' => 400 ] );
|
343 |
+
}
|
344 |
+
|
345 |
+
return $value;
|
346 |
+
},
|
347 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
348 |
+
],
|
349 |
+
];
|
350 |
+
}
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Arguments used for the fetching of the token request.
|
354 |
+
*
|
355 |
+
* @since 5.1.9
|
356 |
+
*
|
357 |
+
* @return array
|
358 |
+
*/
|
359 |
+
public function fetch_token_args() {
|
360 |
+
// Webhooks do not send any arguments, only JSON content.
|
361 |
+
return [
|
362 |
+
'nonce' => [
|
363 |
+
'description' => 'The nonce validation for WP',
|
364 |
+
'required' => true,
|
365 |
+
'type' => 'string',
|
366 |
+
'validate_callback' => static function ( $value ) {
|
367 |
+
if ( ! is_string( $value ) ) {
|
368 |
+
return new WP_Error( 'rest_invalid_param', 'The wp_nonce argument must be a string.', [ 'status' => 400 ] );
|
369 |
+
}
|
370 |
+
|
371 |
+
return $value;
|
372 |
+
},
|
373 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
374 |
+
],
|
375 |
+
'auth_code' => [
|
376 |
+
'description' => 'Authorization Code from PayPal',
|
377 |
+
'required' => true,
|
378 |
+
'type' => 'string',
|
379 |
+
'validate_callback' => static function ( $value ) {
|
380 |
+
if ( ! is_string( $value ) ) {
|
381 |
+
return new WP_Error( 'rest_invalid_param', 'The merchantId auth_code must be a string.', [ 'status' => 400 ] );
|
382 |
+
}
|
383 |
+
|
384 |
+
return $value;
|
385 |
+
},
|
386 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
387 |
+
],
|
388 |
+
'shared_id' => [
|
389 |
+
'description' => 'The shared ID from PayPal',
|
390 |
+
'required' => true,
|
391 |
+
'type' => 'string',
|
392 |
+
'validate_callback' => static function ( $value ) {
|
393 |
+
if ( ! is_string( $value ) ) {
|
394 |
+
return new WP_Error( 'rest_invalid_param', 'The shared_id argument must be a string.', [ 'status' => 400 ] );
|
395 |
+
}
|
396 |
+
|
397 |
+
return $value;
|
398 |
+
},
|
399 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
400 |
+
],
|
401 |
+
];
|
402 |
+
}
|
403 |
+
|
404 |
+
/**
|
405 |
+
* Sanitize a request argument based on details registered to the route.
|
406 |
+
*
|
407 |
+
* @since 5.1.9
|
408 |
+
*
|
409 |
+
* @param mixed $value Value of the 'filter' argument.
|
410 |
+
*
|
411 |
+
* @return string|array
|
412 |
+
*/
|
413 |
+
public function sanitize_callback( $value ) {
|
414 |
+
if ( is_array( $value ) ) {
|
415 |
+
return array_map( 'sanitize_text_field', $value );
|
416 |
+
}
|
417 |
+
|
418 |
+
return sanitize_text_field( $value );
|
419 |
+
}
|
420 |
+
|
421 |
+
/**
|
422 |
+
* {@inheritDoc}
|
423 |
+
*
|
424 |
+
* @TODO We need to make sure Swagger documentation is present.
|
425 |
+
*
|
426 |
+
* @since 5.1.9
|
427 |
+
*
|
428 |
+
* @return array
|
429 |
+
*/
|
430 |
+
public function get_documentation() {
|
431 |
+
return [];
|
432 |
+
}
|
433 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php
ADDED
@@ -0,0 +1,278 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\REST;
|
4 |
+
|
5 |
+
use tad\WPBrowser\Adapters\WP;
|
6 |
+
use TEC\Tickets\Commerce\Cart;
|
7 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Gateway;
|
8 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Status;
|
9 |
+
use TEC\Tickets\Commerce\Order;
|
10 |
+
|
11 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Client;
|
12 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
13 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Refresh_Token;
|
14 |
+
|
15 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Signup;
|
16 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\WhoDat;
|
17 |
+
|
18 |
+
|
19 |
+
use TEC\Tickets\Commerce\Status\Pending;
|
20 |
+
use TEC\Tickets\Commerce\Status\Completed;
|
21 |
+
use TEC\Tickets\Commerce\Status\Created;
|
22 |
+
use TEC\Tickets\Commerce\Success;
|
23 |
+
use Tribe__Documentation__Swagger__Provider_Interface;
|
24 |
+
use Tribe__Settings;
|
25 |
+
use Tribe__Utils__Array as Arr;
|
26 |
+
|
27 |
+
use WP_Error;
|
28 |
+
use WP_REST_Request;
|
29 |
+
use WP_REST_Response;
|
30 |
+
use WP_REST_Server;
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Class Order Endpoint.
|
35 |
+
*
|
36 |
+
* @since 5.1.9
|
37 |
+
*
|
38 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal\REST
|
39 |
+
*/
|
40 |
+
class Order_Endpoint implements Tribe__Documentation__Swagger__Provider_Interface {
|
41 |
+
|
42 |
+
/**
|
43 |
+
* The REST API endpoint path.
|
44 |
+
*
|
45 |
+
* @since 5.1.9
|
46 |
+
*
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
protected $path = '/commerce/paypal/order';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Register the actual endpoint on WP Rest API.
|
53 |
+
*
|
54 |
+
* @since 5.1.9
|
55 |
+
*/
|
56 |
+
public function register() {
|
57 |
+
$namespace = tribe( 'tickets.rest-v1.main' )->get_events_route_namespace();
|
58 |
+
$documentation = tribe( 'tickets.rest-v1.endpoints.documentation' );
|
59 |
+
|
60 |
+
register_rest_route(
|
61 |
+
$namespace,
|
62 |
+
$this->get_endpoint_path(),
|
63 |
+
[
|
64 |
+
'methods' => WP_REST_Server::CREATABLE,
|
65 |
+
'args' => $this->create_order_args(),
|
66 |
+
'callback' => [ $this, 'handle_create_order' ],
|
67 |
+
'permission_callback' => '__return_true',
|
68 |
+
]
|
69 |
+
);
|
70 |
+
|
71 |
+
register_rest_route(
|
72 |
+
$namespace,
|
73 |
+
$this->get_endpoint_path() . '/(?P<order_id>[0-9a-zA-Z]+)',
|
74 |
+
[
|
75 |
+
'methods' => WP_REST_Server::CREATABLE,
|
76 |
+
'args' => $this->update_order_args(),
|
77 |
+
'callback' => [ $this, 'handle_update_order' ],
|
78 |
+
'permission_callback' => '__return_true',
|
79 |
+
]
|
80 |
+
);
|
81 |
+
|
82 |
+
$documentation->register_documentation_provider( $this->get_endpoint_path(), $this );
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Gets the Endpoint path for the on boarding process.
|
87 |
+
*
|
88 |
+
* @since 5.1.9
|
89 |
+
*
|
90 |
+
* @return string
|
91 |
+
*/
|
92 |
+
public function get_endpoint_path() {
|
93 |
+
return $this->path;
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Get the REST API route URL.
|
98 |
+
*
|
99 |
+
* @since 5.1.9
|
100 |
+
*
|
101 |
+
* @return string The REST API route URL.
|
102 |
+
*/
|
103 |
+
public function get_route_url() {
|
104 |
+
$namespace = tribe( 'tickets.rest-v1.main' )->get_events_route_namespace();
|
105 |
+
|
106 |
+
return rest_url( '/' . $namespace . $this->get_endpoint_path(), 'https' );
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Handles the request that creates an order with Tickets Commerce and the PayPal gateway.
|
111 |
+
*
|
112 |
+
* @since 5.1.9
|
113 |
+
*
|
114 |
+
* @param WP_REST_Request $request The request object.
|
115 |
+
*
|
116 |
+
* @return WP_Error|WP_REST_Response An array containing the data on success or a WP_Error instance on failure.
|
117 |
+
*/
|
118 |
+
public function handle_create_order( WP_REST_Request $request ) {
|
119 |
+
$response = [
|
120 |
+
'success' => false,
|
121 |
+
];
|
122 |
+
|
123 |
+
$order = tribe( Order::class )->create_from_cart( tribe( Gateway::class ) );
|
124 |
+
|
125 |
+
$unit = [
|
126 |
+
'reference_id' => $order->ID,
|
127 |
+
'value' => $order->total_value,
|
128 |
+
'currency' => $order->currency,
|
129 |
+
'first_name' => $order->purchaser_first_name,
|
130 |
+
'last_name' => $order->purchaser_last_name,
|
131 |
+
'email' => $order->purchaser_email,
|
132 |
+
];
|
133 |
+
|
134 |
+
$paypal_order = tribe( Client::class )->create_order( $unit );
|
135 |
+
|
136 |
+
if ( empty( $paypal_order['id'] ) || empty( $paypal_order['create_time'] ) ) {
|
137 |
+
return new WP_Error( 'tec-tc-gateway-paypal-failed-creating-order', null, $order );
|
138 |
+
}
|
139 |
+
|
140 |
+
$updated = tribe( Order::class )->modify_status( $order->ID, Pending::SLUG, [
|
141 |
+
'gateway_payload' => $paypal_order,
|
142 |
+
'gateway_order_id' => $paypal_order['id'],
|
143 |
+
] );
|
144 |
+
|
145 |
+
if ( is_wp_error( $updated ) ) {
|
146 |
+
return $updated;
|
147 |
+
}
|
148 |
+
|
149 |
+
// Respond with the ID for Paypal Usage.
|
150 |
+
$response['success'] = true;
|
151 |
+
$response['id'] = $paypal_order['id'];
|
152 |
+
|
153 |
+
return new WP_REST_Response( $response );
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Handles the request that updates an order with Tickets Commerce and the PayPal gateway.
|
158 |
+
*
|
159 |
+
* @since 5.1.9
|
160 |
+
*
|
161 |
+
* @param WP_REST_Request $request The request object.
|
162 |
+
*
|
163 |
+
* @return WP_Error|WP_REST_Response An array containing the data on success or a WP_Error instance on failure.
|
164 |
+
*/
|
165 |
+
public function handle_update_order( WP_REST_Request $request ) {
|
166 |
+
$response = [
|
167 |
+
'success' => false,
|
168 |
+
];
|
169 |
+
|
170 |
+
$paypal_order_id = $request->get_param( 'order_id' );
|
171 |
+
$order = tec_tc_orders()->by_args( [
|
172 |
+
'status' => tribe( Pending::class )->get_wp_slug(),
|
173 |
+
'gateway_order_id' => $paypal_order_id,
|
174 |
+
] )->first();
|
175 |
+
|
176 |
+
if ( ! $order ) {
|
177 |
+
return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', null, $order );
|
178 |
+
}
|
179 |
+
|
180 |
+
$paypal_capture_response = tribe( Client::class )->capture_order( $paypal_order_id );
|
181 |
+
|
182 |
+
if ( ! $paypal_capture_response ) {
|
183 |
+
return new WP_Error( 'tec-tc-gateway-paypal-failed-capture', null, $paypal_capture_response );
|
184 |
+
}
|
185 |
+
|
186 |
+
$paypal_capture_status = Arr::get( $paypal_capture_response, [ 'status' ] );
|
187 |
+
$status = tribe( Status::class )->convert_to_commerce_status( $paypal_capture_status );
|
188 |
+
|
189 |
+
if ( ! $status ) {
|
190 |
+
return new WP_Error( 'tec-tc-gateway-paypal-invalid-capture-status', null, $paypal_capture_response );
|
191 |
+
}
|
192 |
+
|
193 |
+
$updated = tribe( Order::class )->modify_status( $order->ID, $status->get_slug(), [
|
194 |
+
'gateway_payload' => $paypal_capture_response,
|
195 |
+
] );
|
196 |
+
|
197 |
+
if ( is_wp_error( $updated ) ) {
|
198 |
+
return $updated;
|
199 |
+
}
|
200 |
+
|
201 |
+
$response['success'] = true;
|
202 |
+
$response['status'] = $status->get_slug();
|
203 |
+
$response['order_id'] = $order->ID;
|
204 |
+
|
205 |
+
// When we have success we clear the cart.
|
206 |
+
tribe( Cart::class )->clear_cart();
|
207 |
+
|
208 |
+
$response['redirect_url'] = add_query_arg( [ 'tc-order-id' => $paypal_order_id ], tribe( Success::class )->get_url() );
|
209 |
+
|
210 |
+
return new WP_REST_Response( $response );
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Arguments used for the signup redirect.
|
215 |
+
*
|
216 |
+
* @since 5.1.9
|
217 |
+
*
|
218 |
+
* @return array
|
219 |
+
*/
|
220 |
+
public function create_order_args() {
|
221 |
+
return [];
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Arguments used for the signup redirect.
|
226 |
+
*
|
227 |
+
* @since 5.1.9
|
228 |
+
*
|
229 |
+
* @return array
|
230 |
+
*/
|
231 |
+
public function update_order_args() {
|
232 |
+
return [
|
233 |
+
'order_id' => [
|
234 |
+
'description' => __( 'Order ID in PayPal', 'event-tickets' ),
|
235 |
+
'required' => true,
|
236 |
+
'type' => 'string',
|
237 |
+
'validate_callback' => static function ( $value ) {
|
238 |
+
if ( ! is_string( $value ) ) {
|
239 |
+
return new WP_Error( 'rest_invalid_param', 'The order ID argument must be a string.', [ 'status' => 400 ] );
|
240 |
+
}
|
241 |
+
|
242 |
+
return $value;
|
243 |
+
},
|
244 |
+
'sanitize_callback' => [ $this, 'sanitize_callback' ],
|
245 |
+
],
|
246 |
+
];
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Sanitize a request argument based on details registered to the route.
|
251 |
+
*
|
252 |
+
* @since 5.1.9
|
253 |
+
*
|
254 |
+
* @param mixed $value Value of the 'filter' argument.
|
255 |
+
*
|
256 |
+
* @return string|array
|
257 |
+
*/
|
258 |
+
public function sanitize_callback( $value ) {
|
259 |
+
if ( is_array( $value ) ) {
|
260 |
+
return array_map( 'sanitize_text_field', $value );
|
261 |
+
}
|
262 |
+
|
263 |
+
return sanitize_text_field( $value );
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* {@inheritDoc}
|
268 |
+
*
|
269 |
+
* @TODO We need to make sure Swagger documentation is present.
|
270 |
+
*
|
271 |
+
* @since 5.1.9
|
272 |
+
*
|
273 |
+
* @return array
|
274 |
+
*/
|
275 |
+
public function get_documentation() {
|
276 |
+
return [];
|
277 |
+
}
|
278 |
+
}
|
src/{Tribe/REST/V1/Endpoints/Commerce/PayPal_Webhook.php → Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php}
RENAMED
@@ -1,9 +1,10 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
namespace
|
4 |
|
5 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\
|
|
|
7 |
use Tribe__Documentation__Swagger__Provider_Interface;
|
8 |
use Tribe__REST__Endpoints__CREATE_Endpoint_Interface;
|
9 |
use Tribe__Tickets__REST__V1__Endpoints__Base;
|
@@ -17,7 +18,7 @@ use WP_REST_Response;
|
|
17 |
* @since 5.1.6
|
18 |
* @package Tribe\Tickets\REST\V1\Endpoints\PayPal_Commerce
|
19 |
*/
|
20 |
-
class
|
21 |
extends Tribe__Tickets__REST__V1__Endpoints__Base
|
22 |
implements Tribe__REST__Endpoints__CREATE_Endpoint_Interface,
|
23 |
Tribe__Documentation__Swagger__Provider_Interface {
|
@@ -29,7 +30,31 @@ class PayPal_Webhook
|
|
29 |
*
|
30 |
* @var string
|
31 |
*/
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
/**
|
35 |
* {@inheritDoc}
|
@@ -78,6 +103,8 @@ class PayPal_Webhook
|
|
78 |
/**
|
79 |
* {@inheritDoc}
|
80 |
*
|
|
|
|
|
81 |
* @since 5.1.6
|
82 |
*
|
83 |
* @param WP_REST_Request $request The request object.
|
@@ -89,8 +116,8 @@ class PayPal_Webhook
|
|
89 |
$event = $request->get_body();
|
90 |
$headers = $request->get_headers();
|
91 |
|
92 |
-
/** @var
|
93 |
-
$webhook = tribe(
|
94 |
|
95 |
try {
|
96 |
$processed = $webhook->handle( $event, $headers );
|
1 |
<?php
|
2 |
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\REST;
|
4 |
|
5 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\REST;
|
6 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\Payment_Capture_Completed;
|
7 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Webhooks_Route;
|
8 |
use Tribe__Documentation__Swagger__Provider_Interface;
|
9 |
use Tribe__REST__Endpoints__CREATE_Endpoint_Interface;
|
10 |
use Tribe__Tickets__REST__V1__Endpoints__Base;
|
18 |
* @since 5.1.6
|
19 |
* @package Tribe\Tickets\REST\V1\Endpoints\PayPal_Commerce
|
20 |
*/
|
21 |
+
class Webhook_Endpoint
|
22 |
extends Tribe__Tickets__REST__V1__Endpoints__Base
|
23 |
implements Tribe__REST__Endpoints__CREATE_Endpoint_Interface,
|
24 |
Tribe__Documentation__Swagger__Provider_Interface {
|
30 |
*
|
31 |
* @var string
|
32 |
*/
|
33 |
+
protected $path = '/tickets-commerce/paypal/webhook';
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Gets the Endpoint path for the on boarding process.
|
37 |
+
*
|
38 |
+
* @since 5.1.9
|
39 |
+
*
|
40 |
+
* @return string
|
41 |
+
*/
|
42 |
+
public function get_endpoint_path() {
|
43 |
+
return $this->path;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Get the REST API route URL.
|
48 |
+
*
|
49 |
+
* @since 5.1.9
|
50 |
+
*
|
51 |
+
* @return string The REST API route URL.
|
52 |
+
*/
|
53 |
+
public function get_route_url() {
|
54 |
+
$rest = tribe( REST::class );
|
55 |
+
|
56 |
+
return rest_url( '/' . $rest->namespace . $this->get_endpoint_path(), 'https' );
|
57 |
+
}
|
58 |
|
59 |
/**
|
60 |
* {@inheritDoc}
|
103 |
/**
|
104 |
* {@inheritDoc}
|
105 |
*
|
106 |
+
* @todo WIP -- Still using pieces from Give.
|
107 |
+
*
|
108 |
* @since 5.1.6
|
109 |
*
|
110 |
* @param WP_REST_Request $request The request object.
|
116 |
$event = $request->get_body();
|
117 |
$headers = $request->get_headers();
|
118 |
|
119 |
+
/** @var Webhooks_Route $webhook */
|
120 |
+
$webhook = tribe( Webhooks_Route::class );
|
121 |
|
122 |
try {
|
123 |
$processed = $webhook->handle( $event, $headers );
|
src/Tickets/Commerce/Gateways/PayPal/Refresh_Token.php
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Repositories\Authorization;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Refresh_Token
|
9 |
+
*
|
10 |
+
* @since 5.1.6
|
11 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
12 |
+
*/
|
13 |
+
class Refresh_Token {
|
14 |
+
|
15 |
+
/*
|
16 |
+
* @since 5.1.6
|
17 |
+
*
|
18 |
+
* @var Merchant
|
19 |
+
*/
|
20 |
+
private $merchant;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @since 5.1.6
|
24 |
+
*
|
25 |
+
* @var Client
|
26 |
+
*/
|
27 |
+
private $client;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Refresh_Token constructor.
|
31 |
+
*
|
32 |
+
* @since 5.1.6
|
33 |
+
*
|
34 |
+
* @param Merchant $merchant
|
35 |
+
* @param Client $client
|
36 |
+
*/
|
37 |
+
public function __construct(
|
38 |
+
Merchant $merchant = null,
|
39 |
+
Client $client = null
|
40 |
+
) {
|
41 |
+
$this->merchant = $merchant ?: tribe( Merchant::class );
|
42 |
+
$this->client = $client ?: tribe( Client::class );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Return cron json name which uses to refresh token.
|
47 |
+
*
|
48 |
+
* @since 5.1.6
|
49 |
+
*
|
50 |
+
* @return string
|
51 |
+
*/
|
52 |
+
private function get_cron_job_hook_name() {
|
53 |
+
return 'tec_tickets_commerce_paypal_refresh_access_token';
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Register cron job to refresh access token.
|
58 |
+
* Note: only for internal use.
|
59 |
+
*
|
60 |
+
* @since 5.1.6
|
61 |
+
*
|
62 |
+
* @param string $tokenExpires What time the token expires.
|
63 |
+
*/
|
64 |
+
public function register_cron_job_to_refresh_token( $tokenExpires ) {
|
65 |
+
// @todo Verify we need this as a cron, do we lose total API access if it expires (no visitors)?
|
66 |
+
wp_schedule_single_event(
|
67 |
+
// Refresh token before half hours of expires date.
|
68 |
+
time() + ( $tokenExpires - 1800 ),
|
69 |
+
$this->get_cron_job_hook_name()
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Delete cron job which refresh access token.
|
75 |
+
* Note: only for internal use.
|
76 |
+
*
|
77 |
+
* @since 5.1.6
|
78 |
+
*/
|
79 |
+
public function delete_refresh_token_cron_job() {
|
80 |
+
wp_clear_scheduled_hook( $this->get_cron_job_hook_name() );
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Refresh token.
|
85 |
+
* Note: only for internal use
|
86 |
+
*
|
87 |
+
* @since 5.1.6
|
88 |
+
*/
|
89 |
+
public function refresh_token() {
|
90 |
+
// Exit if account is not connected.
|
91 |
+
if ( ! $this->merchant->account_is_connected() ) {
|
92 |
+
return;
|
93 |
+
}
|
94 |
+
|
95 |
+
$token_data = $this->client->get_access_token_from_client_credentials( $this->merchant->get_client_id(), $this->merchant->get_client_secret() );
|
96 |
+
|
97 |
+
$this->merchant->save_access_token_data( $token_data );
|
98 |
+
|
99 |
+
$this->register_cron_job_to_refresh_token( $token_data['expires_in'] );
|
100 |
+
}
|
101 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Repositories/Authorization.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\Repositories;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\WhoDat;
|
6 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Client;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Authorization
|
10 |
+
*
|
11 |
+
* @since 5.1.6
|
12 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal\Repositories
|
13 |
+
*/
|
14 |
+
class Authorization {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @since 5.1.6
|
18 |
+
*
|
19 |
+
* @var Client
|
20 |
+
*/
|
21 |
+
private $paypal_client;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @since 5.1.6
|
25 |
+
*
|
26 |
+
* @var WhoDat
|
27 |
+
*/
|
28 |
+
private $connect_client;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Authorization constructor.
|
32 |
+
*
|
33 |
+
* @since 5.1.6
|
34 |
+
*
|
35 |
+
* @param Client $paypal_client
|
36 |
+
* @param WhoDat $connect_client
|
37 |
+
*/
|
38 |
+
public function __construct( Client $paypal_client, WhoDat $connect_client ) {
|
39 |
+
$this->paypal_client = $paypal_client;
|
40 |
+
$this->connect_client = $connect_client;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Retrieves a token for the Client ID and Secret.
|
45 |
+
*
|
46 |
+
* @since 5.1.6
|
47 |
+
*
|
48 |
+
* @param string $client_id The Client ID.
|
49 |
+
* @param string $client_secret The Client Secret.
|
50 |
+
*
|
51 |
+
* @return array|null The token details response or null if there was a problem.
|
52 |
+
*/
|
53 |
+
public function get_token_from_client_credentials( $client_id, $client_secret ) {
|
54 |
+
$auth = base64_encode( "$client_id:$client_secret" );
|
55 |
+
|
56 |
+
$request = wp_remote_post( $this->paypal_client->get_api_url( 'v1/oauth2/token' ), [
|
57 |
+
'headers' => [
|
58 |
+
'Authorization' => sprintf( 'Basic %1$s', $auth ),
|
59 |
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
60 |
+
],
|
61 |
+
'body' => [
|
62 |
+
'grant_type' => 'client_credentials',
|
63 |
+
],
|
64 |
+
] );
|
65 |
+
|
66 |
+
if ( is_wp_error( $request ) ) {
|
67 |
+
tribe( 'logger' )->log_error( sprintf(
|
68 |
+
// Translators: %s: The error message.
|
69 |
+
__( 'PayPal request error: %s', 'event-tickets' ),
|
70 |
+
$request->get_error_message()
|
71 |
+
), 'tickets-commerce-paypal-commerce' );
|
72 |
+
|
73 |
+
return null;
|
74 |
+
}
|
75 |
+
|
76 |
+
$response = wp_remote_retrieve_body( $request );
|
77 |
+
$response = @json_decode( $response, true );
|
78 |
+
|
79 |
+
if ( ! is_array( $response ) ) {
|
80 |
+
tribe( 'logger' )->log_error( __( 'Unexpected PayPal response when getting token from client credentials', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
81 |
+
|
82 |
+
return null;
|
83 |
+
}
|
84 |
+
|
85 |
+
return $response;
|
86 |
+
}
|
87 |
+
|
88 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Repositories/Order.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\Repositories;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Client;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Order
|
9 |
+
*
|
10 |
+
* @since 5.1.6
|
11 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal\Repositories
|
12 |
+
*
|
13 |
+
*/
|
14 |
+
class Order {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @since 5.1.6
|
18 |
+
*
|
19 |
+
* @var Client
|
20 |
+
*/
|
21 |
+
private $client;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Order constructor.
|
25 |
+
*
|
26 |
+
* @since 5.1.6
|
27 |
+
*
|
28 |
+
* @param Client $client
|
29 |
+
*/
|
30 |
+
public function __construct( Client $client = null ) {
|
31 |
+
$this->client = $client ?: tribe( Client::class );
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Approve order.
|
36 |
+
*
|
37 |
+
* @since 5.1.6
|
38 |
+
*
|
39 |
+
* @param string|int $order_id Which Order Post Type ID we are going to create a PayPal Order from.
|
40 |
+
*
|
41 |
+
* @return string
|
42 |
+
*/
|
43 |
+
public function approve( $order_id ) {
|
44 |
+
$response = $this->client->capture_order( $order_id );
|
45 |
+
|
46 |
+
return $response;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Create order based on Event Ticket Order ID we send the data to Paypal to create the order there.
|
51 |
+
*
|
52 |
+
* @since 5.1.9
|
53 |
+
*
|
54 |
+
* @param string|int $order_id Which Order Post Type ID we are going to create a PayPal Order from.
|
55 |
+
*
|
56 |
+
* @return array
|
57 |
+
*/
|
58 |
+
public function create( $order_id ) {
|
59 |
+
|
60 |
+
$data = [
|
61 |
+
|
62 |
+
];
|
63 |
+
|
64 |
+
$order_response = $this->client->create_order( $data );
|
65 |
+
|
66 |
+
return $order_response['id'];
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Refunds a processed payment
|
71 |
+
*
|
72 |
+
* @since 5.1.6
|
73 |
+
|
74 |
+
* @param string|int $order_id Which Order Post Type ID we are going to create a PayPal Order from.
|
75 |
+
*
|
76 |
+
* @return string The id of the refund
|
77 |
+
*/
|
78 |
+
public function refund_payment( $order_id ) {
|
79 |
+
$response = $this->client->refund_payment( $order_id );
|
80 |
+
|
81 |
+
return $response;
|
82 |
+
}
|
83 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/{SDK/Repositories → Repositories}/Webhooks.php
RENAMED
@@ -1,36 +1,39 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\
|
4 |
|
5 |
use Exception;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
8 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
9 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
10 |
use TEC\Tickets\Commerce\Gateways\PayPal\Settings;
|
11 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\
|
12 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
class Webhooks {
|
15 |
-
|
16 |
-
use HasMode;
|
17 |
-
|
18 |
/**
|
19 |
* @since 5.1.6
|
20 |
*
|
21 |
-
* @var
|
22 |
*/
|
23 |
-
private $
|
24 |
|
25 |
/**
|
26 |
-
* @var
|
27 |
*/
|
28 |
-
private $
|
29 |
|
30 |
/**
|
31 |
-
* @var
|
32 |
*/
|
33 |
-
private $
|
34 |
|
35 |
/**
|
36 |
* @var Settings
|
@@ -42,23 +45,14 @@ class Webhooks {
|
|
42 |
*
|
43 |
* @since 5.1.6
|
44 |
*
|
45 |
-
* @param
|
46 |
-
* @param
|
47 |
-
* @param Settings
|
48 |
-
*/
|
49 |
-
public function __construct( PayPalClient $payPalClient, WebhookRegister $webhooksRegister, Settings $settings ) {
|
50 |
-
$this->payPalClient = $payPalClient;
|
51 |
-
$this->webhooksRegister = $webhooksRegister;
|
52 |
-
$this->settings = $settings;
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Handle initial setup for the object singleton.
|
57 |
-
*
|
58 |
-
* @since 5.1.6
|
59 |
*/
|
60 |
-
public function
|
61 |
-
$this->
|
|
|
|
|
62 |
}
|
63 |
|
64 |
/**
|
@@ -67,20 +61,20 @@ class Webhooks {
|
|
67 |
* @see https://developer.paypal.com/docs/api/webhooks/v1/#verify-webhook-signature
|
68 |
* @since 5.1.6
|
69 |
*
|
70 |
-
* @param string
|
71 |
-
* @param object
|
72 |
-
* @param
|
73 |
*
|
74 |
* @return bool
|
75 |
*/
|
76 |
-
public function
|
77 |
// @todo Move this to the SDK.
|
78 |
-
$
|
79 |
|
80 |
-
$
|
81 |
|
82 |
$request = wp_remote_post(
|
83 |
-
$
|
84 |
[
|
85 |
'headers' => [
|
86 |
'Content-Type' => 'application/json',
|
@@ -88,12 +82,12 @@ class Webhooks {
|
|
88 |
],
|
89 |
'body' => wp_json_encode(
|
90 |
[
|
91 |
-
'transmission_id' => $
|
92 |
-
'transmission_time' => $
|
93 |
-
'transmission_sig' => $
|
94 |
-
'cert_url' => $
|
95 |
-
'auth_algo' => $
|
96 |
-
'webhook_id' => $
|
97 |
'webhook_event' => $event,
|
98 |
]
|
99 |
),
|
@@ -102,7 +96,7 @@ class Webhooks {
|
|
102 |
|
103 |
if ( is_wp_error( $request ) ) {
|
104 |
tribe( 'logger' )->log_error( sprintf(
|
105 |
-
|
106 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
107 |
$request->get_error_message()
|
108 |
), 'tickets-commerce-paypal-commerce' );
|
@@ -135,12 +129,12 @@ class Webhooks {
|
|
135 |
*
|
136 |
* @return object[] The list of PayPal webhooks.
|
137 |
*/
|
138 |
-
public function
|
139 |
// @todo Move this to the SDK.
|
140 |
-
$
|
141 |
|
142 |
$request = wp_remote_get(
|
143 |
-
$
|
144 |
[
|
145 |
'headers' => [
|
146 |
'Content-Type' => 'application/json',
|
@@ -151,7 +145,7 @@ class Webhooks {
|
|
151 |
|
152 |
if ( is_wp_error( $request ) ) {
|
153 |
tribe( 'logger' )->log_error( sprintf(
|
154 |
-
|
155 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
156 |
$request->get_error_message()
|
157 |
), 'tickets-commerce-paypal-commerce' );
|
@@ -177,19 +171,19 @@ class Webhooks {
|
|
177 |
* @see https://developer.paypal.com/docs/api/webhooks/v1/#webhooks_get
|
178 |
* @since 5.1.6
|
179 |
*
|
180 |
-
* @param string $token
|
181 |
-
* @param string $
|
182 |
*
|
183 |
* @throws Exception
|
184 |
*
|
185 |
* @return object The PayPal webhook data.
|
186 |
*/
|
187 |
-
public function
|
188 |
// @todo Move this to the SDK.
|
189 |
-
$
|
190 |
|
191 |
$request = wp_remote_get(
|
192 |
-
$
|
193 |
[
|
194 |
'headers' => [
|
195 |
'Content-Type' => 'application/json',
|
@@ -200,7 +194,7 @@ class Webhooks {
|
|
200 |
|
201 |
if ( is_wp_error( $request ) ) {
|
202 |
tribe( 'logger' )->log_error( sprintf(
|
203 |
-
|
204 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
205 |
$request->get_error_message()
|
206 |
), 'tickets-commerce-paypal-commerce' );
|
@@ -234,15 +228,15 @@ class Webhooks {
|
|
234 |
*
|
235 |
* @param string $token
|
236 |
*
|
237 |
-
* @return
|
238 |
* @throws Exception
|
239 |
*/
|
240 |
-
public function
|
241 |
// @todo Move this to the SDK.
|
242 |
-
$apiUrl = $this->
|
243 |
|
244 |
-
$events
|
245 |
-
$
|
246 |
|
247 |
$request = wp_remote_post(
|
248 |
$apiUrl,
|
@@ -253,7 +247,7 @@ class Webhooks {
|
|
253 |
],
|
254 |
'body' => json_encode(
|
255 |
[
|
256 |
-
'url' => $
|
257 |
'event_types' => array_map(
|
258 |
static function ( $eventType ) {
|
259 |
return [
|
@@ -269,7 +263,7 @@ class Webhooks {
|
|
269 |
|
270 |
if ( is_wp_error( $request ) ) {
|
271 |
tribe( 'logger' )->log_error( sprintf(
|
272 |
-
|
273 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
274 |
$request->get_error_message()
|
275 |
), 'tickets-commerce-paypal-commerce' );
|
@@ -284,13 +278,13 @@ class Webhooks {
|
|
284 |
if ( ! empty( $response->name ) ) {
|
285 |
if ( 'WEBHOOK_URL_ALREADY_EXISTS' === $response->name ) {
|
286 |
// The webhook already exists, this is fine!
|
287 |
-
$webhooks = $this->
|
288 |
|
289 |
if ( $webhooks ) {
|
290 |
$webhooks = wp_list_pluck( $webhooks, 'id', 'url' );
|
291 |
|
292 |
-
if ( isset( $webhooks[ $
|
293 |
-
return new
|
294 |
}
|
295 |
}
|
296 |
} elseif ( 'WEBHOOK_NUMBER_LIMIT_EXCEEDED' === $response->name ) {
|
@@ -304,7 +298,7 @@ class Webhooks {
|
|
304 |
throw new Exception( 'Failed to create webhook' );
|
305 |
}
|
306 |
|
307 |
-
return new
|
308 |
}
|
309 |
|
310 |
/**
|
@@ -312,22 +306,23 @@ class Webhooks {
|
|
312 |
*
|
313 |
* @since 5.1.6
|
314 |
*
|
315 |
-
* @param string $token
|
316 |
-
* @param string $webhookId
|
317 |
-
*
|
318 |
* @throws Exception
|
319 |
*
|
|
|
|
|
|
|
|
|
320 |
* @return bool
|
321 |
*/
|
322 |
-
public function
|
323 |
// @todo Move this to the SDK.
|
324 |
-
$
|
325 |
|
326 |
-
$events
|
327 |
-
$
|
328 |
|
329 |
$request = wp_remote_request(
|
330 |
-
$
|
331 |
[
|
332 |
'method' => 'PATCH',
|
333 |
'headers' => [
|
@@ -339,15 +334,15 @@ class Webhooks {
|
|
339 |
[
|
340 |
'op' => 'replace',
|
341 |
'path' => '/url',
|
342 |
-
'value' => $
|
343 |
],
|
344 |
[
|
345 |
'op' => 'replace',
|
346 |
'path' => '/event_types',
|
347 |
'value' => array_map(
|
348 |
-
static function ( $
|
349 |
return [
|
350 |
-
'name' => $
|
351 |
];
|
352 |
},
|
353 |
$events
|
@@ -360,7 +355,7 @@ class Webhooks {
|
|
360 |
|
361 |
if ( is_wp_error( $request ) ) {
|
362 |
tribe( 'logger' )->log_error( sprintf(
|
363 |
-
|
364 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
365 |
$request->get_error_message()
|
366 |
), 'tickets-commerce-paypal-commerce' );
|
@@ -375,11 +370,11 @@ class Webhooks {
|
|
375 |
if ( ! empty( $response->name ) ) {
|
376 |
if ( 'INVALID_RESOURCE_ID' === $response->name ) {
|
377 |
// The webhook was not found, let's create it.
|
378 |
-
$
|
379 |
|
380 |
tribe( 'logger' )->log_warning( __( 'The PayPal webhook was not able to be updated because it did not exist, attempting to create it now', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
381 |
|
382 |
-
if ( $
|
383 |
return true;
|
384 |
}
|
385 |
}
|
@@ -399,16 +394,16 @@ class Webhooks {
|
|
399 |
* @since 5.1.6
|
400 |
*
|
401 |
* @param string $token
|
402 |
-
* @param string $
|
403 |
*
|
404 |
* @return bool Whether or not the deletion was successful
|
405 |
*/
|
406 |
-
public function
|
407 |
// @todo Move this to the SDK.
|
408 |
-
$
|
409 |
|
410 |
$request = wp_remote_request(
|
411 |
-
$
|
412 |
[
|
413 |
'method' => 'DELETE',
|
414 |
'headers' => [
|
@@ -428,10 +423,10 @@ class Webhooks {
|
|
428 |
*
|
429 |
* @since 5.1.6
|
430 |
*
|
431 |
-
* @param
|
432 |
*/
|
433 |
-
public function
|
434 |
-
$this->settings->update_webhook_config(
|
435 |
}
|
436 |
|
437 |
/**
|
@@ -439,10 +434,10 @@ class Webhooks {
|
|
439 |
*
|
440 |
* @since 5.1.6
|
441 |
*
|
442 |
-
* @return
|
443 |
*/
|
444 |
-
public function
|
445 |
-
return $this->settings->get_webhook_config(
|
446 |
}
|
447 |
|
448 |
/**
|
@@ -450,7 +445,7 @@ class Webhooks {
|
|
450 |
*
|
451 |
* @since 5.1.6
|
452 |
*/
|
453 |
-
public function
|
454 |
-
$this->settings->delete_webhook_config(
|
455 |
}
|
456 |
}
|
1 |
<?php
|
2 |
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\Repositories;
|
4 |
|
5 |
use Exception;
|
6 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Headers;
|
7 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Models\Webhook_Config;
|
8 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Client;
|
9 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
10 |
use TEC\Tickets\Commerce\Gateways\PayPal\Settings;
|
11 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Webhook_Register;
|
12 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Webhooks_Route;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class Webhooks
|
16 |
+
*
|
17 |
+
* @since 5.1.6
|
18 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal\Repositories
|
19 |
+
*/
|
20 |
class Webhooks {
|
|
|
|
|
|
|
21 |
/**
|
22 |
* @since 5.1.6
|
23 |
*
|
24 |
+
* @var Webhooks_Route
|
25 |
*/
|
26 |
+
private $webhook_route;
|
27 |
|
28 |
/**
|
29 |
+
* @var Webhook_Register
|
30 |
*/
|
31 |
+
private $webhooks_register;
|
32 |
|
33 |
/**
|
34 |
+
* @var Client
|
35 |
*/
|
36 |
+
private $paypal_client;
|
37 |
|
38 |
/**
|
39 |
* @var Settings
|
45 |
*
|
46 |
* @since 5.1.6
|
47 |
*
|
48 |
+
* @param Client $paypal_client
|
49 |
+
* @param Webhook_Register $webhooks_register
|
50 |
+
* @param Settings $settings
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
*/
|
52 |
+
public function __construct( Client $paypal_client, Webhook_Register $webhooks_register, Settings $settings ) {
|
53 |
+
$this->paypal_client = $paypal_client;
|
54 |
+
$this->webhooks_register = $webhooks_register;
|
55 |
+
$this->settings = $settings;
|
56 |
}
|
57 |
|
58 |
/**
|
61 |
* @see https://developer.paypal.com/docs/api/webhooks/v1/#verify-webhook-signature
|
62 |
* @since 5.1.6
|
63 |
*
|
64 |
+
* @param string $token
|
65 |
+
* @param object $event The event to verify
|
66 |
+
* @param Headers $paypal_headers
|
67 |
*
|
68 |
* @return bool
|
69 |
*/
|
70 |
+
public function verify_event_signature( $token, $event, $paypal_headers ) {
|
71 |
// @todo Move this to the SDK.
|
72 |
+
$api_url = $this->paypal_client->get_api_url( 'v1/notifications/verify-webhook-signature' );
|
73 |
|
74 |
+
$webhook_config = $this->get_webhook_config();
|
75 |
|
76 |
$request = wp_remote_post(
|
77 |
+
$api_url,
|
78 |
[
|
79 |
'headers' => [
|
80 |
'Content-Type' => 'application/json',
|
82 |
],
|
83 |
'body' => wp_json_encode(
|
84 |
[
|
85 |
+
'transmission_id' => $paypal_headers->transmission_id,
|
86 |
+
'transmission_time' => $paypal_headers->transmission_time,
|
87 |
+
'transmission_sig' => $paypal_headers->transmission_sig,
|
88 |
+
'cert_url' => $paypal_headers->cert_url,
|
89 |
+
'auth_algo' => $paypal_headers->auth_algo,
|
90 |
+
'webhook_id' => $webhook_config->id,
|
91 |
'webhook_event' => $event,
|
92 |
]
|
93 |
),
|
96 |
|
97 |
if ( is_wp_error( $request ) ) {
|
98 |
tribe( 'logger' )->log_error( sprintf(
|
99 |
+
// Translators: %s: The error message.
|
100 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
101 |
$request->get_error_message()
|
102 |
), 'tickets-commerce-paypal-commerce' );
|
129 |
*
|
130 |
* @return object[] The list of PayPal webhooks.
|
131 |
*/
|
132 |
+
public function list_webhooks( $token ) {
|
133 |
// @todo Move this to the SDK.
|
134 |
+
$api_url = $this->paypal_client->get_api_url( 'v1/notifications/webhooks' );
|
135 |
|
136 |
$request = wp_remote_get(
|
137 |
+
$api_url,
|
138 |
[
|
139 |
'headers' => [
|
140 |
'Content-Type' => 'application/json',
|
145 |
|
146 |
if ( is_wp_error( $request ) ) {
|
147 |
tribe( 'logger' )->log_error( sprintf(
|
148 |
+
// Translators: %s: The error message.
|
149 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
150 |
$request->get_error_message()
|
151 |
), 'tickets-commerce-paypal-commerce' );
|
171 |
* @see https://developer.paypal.com/docs/api/webhooks/v1/#webhooks_get
|
172 |
* @since 5.1.6
|
173 |
*
|
174 |
+
* @param string $token The PayPal auth token.
|
175 |
+
* @param string $webhook_id The webhook ID.
|
176 |
*
|
177 |
* @throws Exception
|
178 |
*
|
179 |
* @return object The PayPal webhook data.
|
180 |
*/
|
181 |
+
public function get_webhook( $token, $webhook_id ) {
|
182 |
// @todo Move this to the SDK.
|
183 |
+
$api_url = $this->paypal_client->get_api_url( "v1/notifications/webhooks/{$webhook_id}" );
|
184 |
|
185 |
$request = wp_remote_get(
|
186 |
+
$api_url,
|
187 |
[
|
188 |
'headers' => [
|
189 |
'Content-Type' => 'application/json',
|
194 |
|
195 |
if ( is_wp_error( $request ) ) {
|
196 |
tribe( 'logger' )->log_error( sprintf(
|
197 |
+
// Translators: %s: The error message.
|
198 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
199 |
$request->get_error_message()
|
200 |
), 'tickets-commerce-paypal-commerce' );
|
228 |
*
|
229 |
* @param string $token
|
230 |
*
|
231 |
+
* @return Webhook_Config
|
232 |
* @throws Exception
|
233 |
*/
|
234 |
+
public function create_webhook( $token ) {
|
235 |
// @todo Move this to the SDK.
|
236 |
+
$apiUrl = $this->paypal_client->get_api_url( 'v1/notifications/webhooks' );
|
237 |
|
238 |
+
$events = $this->webhooks_register->get_registered_events();
|
239 |
+
$webhook_url = tribe( Webhooks_Route::class )->get_route_url();
|
240 |
|
241 |
$request = wp_remote_post(
|
242 |
$apiUrl,
|
247 |
],
|
248 |
'body' => json_encode(
|
249 |
[
|
250 |
+
'url' => $webhook_url,
|
251 |
'event_types' => array_map(
|
252 |
static function ( $eventType ) {
|
253 |
return [
|
263 |
|
264 |
if ( is_wp_error( $request ) ) {
|
265 |
tribe( 'logger' )->log_error( sprintf(
|
266 |
+
// Translators: %s: The error message.
|
267 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
268 |
$request->get_error_message()
|
269 |
), 'tickets-commerce-paypal-commerce' );
|
278 |
if ( ! empty( $response->name ) ) {
|
279 |
if ( 'WEBHOOK_URL_ALREADY_EXISTS' === $response->name ) {
|
280 |
// The webhook already exists, this is fine!
|
281 |
+
$webhooks = $this->list_webhooks( $token );
|
282 |
|
283 |
if ( $webhooks ) {
|
284 |
$webhooks = wp_list_pluck( $webhooks, 'id', 'url' );
|
285 |
|
286 |
+
if ( isset( $webhooks[ $webhook_url ] ) ) {
|
287 |
+
return new Webhook_Config( $webhooks[ $webhook_url ], $webhook_url, $events );
|
288 |
}
|
289 |
}
|
290 |
} elseif ( 'WEBHOOK_NUMBER_LIMIT_EXCEEDED' === $response->name ) {
|
298 |
throw new Exception( 'Failed to create webhook' );
|
299 |
}
|
300 |
|
301 |
+
return new Webhook_Config( $response->id, $webhook_url, $events );
|
302 |
}
|
303 |
|
304 |
/**
|
306 |
*
|
307 |
* @since 5.1.6
|
308 |
*
|
|
|
|
|
|
|
309 |
* @throws Exception
|
310 |
*
|
311 |
+
* @param string $webhook_id
|
312 |
+
*
|
313 |
+
* @param string $token
|
314 |
+
*
|
315 |
* @return bool
|
316 |
*/
|
317 |
+
public function update_webhook( $token, $webhook_id ) {
|
318 |
// @todo Move this to the SDK.
|
319 |
+
$api_url = $this->paypal_client->get_api_url( "v1/notifications/webhooks/{$webhook_id}" );
|
320 |
|
321 |
+
$events = $this->webhooks_register->get_registered_events();
|
322 |
+
$webhook_url = tribe( Webhooks_Route::class )->get_route_url();
|
323 |
|
324 |
$request = wp_remote_request(
|
325 |
+
$api_url,
|
326 |
[
|
327 |
'method' => 'PATCH',
|
328 |
'headers' => [
|
334 |
[
|
335 |
'op' => 'replace',
|
336 |
'path' => '/url',
|
337 |
+
'value' => $webhook_url,
|
338 |
],
|
339 |
[
|
340 |
'op' => 'replace',
|
341 |
'path' => '/event_types',
|
342 |
'value' => array_map(
|
343 |
+
static function ( $event_type ) {
|
344 |
return [
|
345 |
+
'name' => $event_type,
|
346 |
];
|
347 |
},
|
348 |
$events
|
355 |
|
356 |
if ( is_wp_error( $request ) ) {
|
357 |
tribe( 'logger' )->log_error( sprintf(
|
358 |
+
// Translators: %s: The error message.
|
359 |
__( 'PayPal request error: %s', 'event-tickets' ),
|
360 |
$request->get_error_message()
|
361 |
), 'tickets-commerce-paypal-commerce' );
|
370 |
if ( ! empty( $response->name ) ) {
|
371 |
if ( 'INVALID_RESOURCE_ID' === $response->name ) {
|
372 |
// The webhook was not found, let's create it.
|
373 |
+
$webhook_config = $this->create_webhook( $token );
|
374 |
|
375 |
tribe( 'logger' )->log_warning( __( 'The PayPal webhook was not able to be updated because it did not exist, attempting to create it now', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
376 |
|
377 |
+
if ( $webhook_config ) {
|
378 |
return true;
|
379 |
}
|
380 |
}
|
394 |
* @since 5.1.6
|
395 |
*
|
396 |
* @param string $token
|
397 |
+
* @param string $webhook_id
|
398 |
*
|
399 |
* @return bool Whether or not the deletion was successful
|
400 |
*/
|
401 |
+
public function delete_webhook( $token, $webhook_id ) {
|
402 |
// @todo Move this to the SDK.
|
403 |
+
$api_url = $this->paypal_client->get_api_url( "v1/notifications/webhooks/{$webhook_id}" );
|
404 |
|
405 |
$request = wp_remote_request(
|
406 |
+
$api_url,
|
407 |
[
|
408 |
'method' => 'DELETE',
|
409 |
'headers' => [
|
423 |
*
|
424 |
* @since 5.1.6
|
425 |
*
|
426 |
+
* @param Webhook_Config $config
|
427 |
*/
|
428 |
+
public function save_webhook_config( Webhook_Config $config ) {
|
429 |
+
$this->settings->update_webhook_config( tribe( Merchant::class )->get_mode(), $config );
|
430 |
}
|
431 |
|
432 |
/**
|
434 |
*
|
435 |
* @since 5.1.6
|
436 |
*
|
437 |
+
* @return Webhook_Config|null
|
438 |
*/
|
439 |
+
public function get_webhook_config() {
|
440 |
+
return $this->settings->get_webhook_config( tribe( Merchant::class )->get_mode() );
|
441 |
}
|
442 |
|
443 |
/**
|
445 |
*
|
446 |
* @since 5.1.6
|
447 |
*/
|
448 |
+
public function delete_webhook_config() {
|
449 |
+
$this->settings->delete_webhook_config( tribe( Merchant::class )->get_mode() );
|
450 |
}
|
451 |
}
|
src/Tickets/Commerce/Gateways/PayPal/SDK/Models/MerchantDetail.php
DELETED
@@ -1,216 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models;
|
4 |
-
|
5 |
-
use InvalidArgumentException;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\MerchantDetails;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Class MerchantDetail
|
10 |
-
*
|
11 |
-
* @since 5.1.6
|
12 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
13 |
-
*
|
14 |
-
*/
|
15 |
-
class MerchantDetail {
|
16 |
-
|
17 |
-
/**
|
18 |
-
* PayPal merchant Id (email address)
|
19 |
-
*
|
20 |
-
* @since 5.1.6
|
21 |
-
*
|
22 |
-
* @var null|string
|
23 |
-
*/
|
24 |
-
public $merchantId = null;
|
25 |
-
|
26 |
-
/**
|
27 |
-
* PayPal merchant id
|
28 |
-
*
|
29 |
-
* @since 5.1.6
|
30 |
-
*
|
31 |
-
* @var null|string
|
32 |
-
*/
|
33 |
-
public $merchantIdInPayPal = null;
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Client id.
|
37 |
-
*
|
38 |
-
* @since 5.1.6
|
39 |
-
*
|
40 |
-
* @var null |string
|
41 |
-
*/
|
42 |
-
public $clientId = null;
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Client Secret
|
46 |
-
*
|
47 |
-
* @since 5.1.6
|
48 |
-
*
|
49 |
-
* @var null|string
|
50 |
-
*/
|
51 |
-
public $clientSecret = null;
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Access token.
|
55 |
-
*
|
56 |
-
* @since 5.1.6
|
57 |
-
*
|
58 |
-
* @var null|string
|
59 |
-
*/
|
60 |
-
public $accessToken = null;
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Whether or not the connected account is ready to process payments.
|
64 |
-
*
|
65 |
-
* @since 5.1.6
|
66 |
-
*
|
67 |
-
* @var bool
|
68 |
-
*/
|
69 |
-
public $accountIsReady = false;
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Whether or not the account can make custom payments (i.e Advanced Fields & PPCP)
|
73 |
-
*
|
74 |
-
* @since 5.1.6
|
75 |
-
*
|
76 |
-
* @var bool
|
77 |
-
*/
|
78 |
-
public $supportsCustomPayments;
|
79 |
-
|
80 |
-
/**
|
81 |
-
* PayPal account accountCountry.
|
82 |
-
*
|
83 |
-
* @since 5.1.6
|
84 |
-
*
|
85 |
-
* @var bool
|
86 |
-
*/
|
87 |
-
public $accountCountry;
|
88 |
-
|
89 |
-
/**
|
90 |
-
* Access token.
|
91 |
-
*
|
92 |
-
* @since 5.1.6
|
93 |
-
*
|
94 |
-
* @var array
|
95 |
-
*/
|
96 |
-
private $tokenDetails = null;
|
97 |
-
|
98 |
-
/**
|
99 |
-
* Handle initial setup for the object singleton.
|
100 |
-
*
|
101 |
-
* @since 5.1.6
|
102 |
-
*/
|
103 |
-
public function init() {
|
104 |
-
/** @var MerchantDetails $repository */
|
105 |
-
$repository = tribe( MerchantDetails::class );
|
106 |
-
|
107 |
-
$merchantDetails = $repository->getDetailsData();
|
108 |
-
|
109 |
-
try {
|
110 |
-
$this->validate( $merchantDetails );
|
111 |
-
} catch ( InvalidArgumentException $exception ) {
|
112 |
-
// Do not continue to set up the properties.
|
113 |
-
return;
|
114 |
-
}
|
115 |
-
|
116 |
-
$this->setupProperties( $merchantDetails );
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* Return array of merchant details.
|
121 |
-
*
|
122 |
-
* @since 5.1.6
|
123 |
-
*
|
124 |
-
* @return array
|
125 |
-
*/
|
126 |
-
public function toArray() {
|
127 |
-
return [
|
128 |
-
'merchantId' => $this->merchantId,
|
129 |
-
'merchantIdInPayPal' => $this->merchantIdInPayPal,
|
130 |
-
'clientId' => $this->clientId,
|
131 |
-
'clientSecret' => $this->clientSecret,
|
132 |
-
'token' => $this->tokenDetails,
|
133 |
-
'accountIsReady' => $this->accountIsReady,
|
134 |
-
'supportsCustomPayments' => $this->supportsCustomPayments,
|
135 |
-
'accountCountry' => $this->accountCountry,
|
136 |
-
];
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* Make MerchantDetail object from array.
|
141 |
-
*
|
142 |
-
* @since 5.1.6
|
143 |
-
*
|
144 |
-
* @param array $merchantDetails
|
145 |
-
*
|
146 |
-
* @return MerchantDetail
|
147 |
-
*/
|
148 |
-
public static function fromArray( $merchantDetails ) {
|
149 |
-
$obj = new static();
|
150 |
-
|
151 |
-
if ( ! $merchantDetails ) {
|
152 |
-
return $obj;
|
153 |
-
}
|
154 |
-
|
155 |
-
$obj->validate( $merchantDetails );
|
156 |
-
$obj->setupProperties( $merchantDetails );
|
157 |
-
|
158 |
-
return $obj;
|
159 |
-
}
|
160 |
-
|
161 |
-
/**
|
162 |
-
* Setup properties from array.
|
163 |
-
*
|
164 |
-
* @since 5.1.6
|
165 |
-
*
|
166 |
-
* @param $merchantDetails
|
167 |
-
*
|
168 |
-
*/
|
169 |
-
private function setupProperties( $merchantDetails ) {
|
170 |
-
$this->merchantId = $merchantDetails['merchantId'];
|
171 |
-
$this->merchantIdInPayPal = $merchantDetails['merchantIdInPayPal'];
|
172 |
-
|
173 |
-
$this->clientId = $merchantDetails['clientId'];
|
174 |
-
$this->clientSecret = $merchantDetails['clientSecret'];
|
175 |
-
$this->tokenDetails = $merchantDetails['token'];
|
176 |
-
$this->accountIsReady = $merchantDetails['accountIsReady'];
|
177 |
-
$this->supportsCustomPayments = $merchantDetails['supportsCustomPayments'];
|
178 |
-
$this->accountCountry = $merchantDetails['accountCountry'];
|
179 |
-
$this->accessToken = $this->tokenDetails['access_token'];
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* Validate merchant details.
|
184 |
-
*
|
185 |
-
* @since 5.1.6
|
186 |
-
*
|
187 |
-
* @param array $merchantDetails
|
188 |
-
*/
|
189 |
-
private function validate( $merchantDetails ) {
|
190 |
-
$required = [
|
191 |
-
'merchantId',
|
192 |
-
'merchantIdInPayPal',
|
193 |
-
'clientId',
|
194 |
-
'clientSecret',
|
195 |
-
'token',
|
196 |
-
'accountIsReady',
|
197 |
-
'supportsCustomPayments',
|
198 |
-
'accountCountry',
|
199 |
-
];
|
200 |
-
|
201 |
-
if ( array_diff( $required, array_keys( $merchantDetails ) ) ) {
|
202 |
-
throw new InvalidArgumentException( esc_html__( 'To create a MerchantDetail object, please provide the following: ' . implode( ', ', $required ), 'event-tickets' ) );
|
203 |
-
}
|
204 |
-
}
|
205 |
-
|
206 |
-
/**
|
207 |
-
* Get refresh token code.
|
208 |
-
*
|
209 |
-
* @since 5.1.6
|
210 |
-
*
|
211 |
-
* @param array $tokenDetails
|
212 |
-
*/
|
213 |
-
public function setTokenDetails( $tokenDetails ) {
|
214 |
-
$this->tokenDetails = array_merge( $this->tokenDetails, $tokenDetails );
|
215 |
-
}
|
216 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/SDK/Models/WebhookConfig.php
DELETED
@@ -1,70 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models;
|
4 |
-
|
5 |
-
class WebhookConfig {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @since 5.1.6
|
9 |
-
*
|
10 |
-
* @var string
|
11 |
-
*/
|
12 |
-
public $id;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @since 5.1.6
|
16 |
-
*
|
17 |
-
* @var string
|
18 |
-
*/
|
19 |
-
public $returnUrl;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @since 5.1.6
|
23 |
-
*
|
24 |
-
* @var string[]
|
25 |
-
*/
|
26 |
-
public $events;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* WebhookConfig constructor.
|
30 |
-
*
|
31 |
-
* @since 5.1.6
|
32 |
-
*
|
33 |
-
* @param string $id
|
34 |
-
* @param string $returnUrl
|
35 |
-
* @param string[] $events
|
36 |
-
*/
|
37 |
-
public function __construct( $id, $returnUrl, $events ) {
|
38 |
-
$this->id = $id;
|
39 |
-
$this->returnUrl = $returnUrl;
|
40 |
-
$this->events = $events;
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Generates an instance from serialized data
|
45 |
-
*
|
46 |
-
* @since 5.1.6
|
47 |
-
*
|
48 |
-
* @param array $data
|
49 |
-
*
|
50 |
-
* @return WebhookConfig
|
51 |
-
*/
|
52 |
-
public static function fromArray( array $data ) {
|
53 |
-
return new self( $data['id'], $data['returnUrl'], $data['events'] );
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Generates an array for serialization
|
58 |
-
*
|
59 |
-
* @since 5.1.6
|
60 |
-
*
|
61 |
-
* @return array
|
62 |
-
*/
|
63 |
-
public function toArray() {
|
64 |
-
return [
|
65 |
-
'id' => $this->id,
|
66 |
-
'returnUrl' => $this->returnUrl,
|
67 |
-
'events' => $this->events,
|
68 |
-
];
|
69 |
-
}
|
70 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/SDK/PayPalClient.php
DELETED
@@ -1,92 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\SDK;
|
4 |
-
|
5 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models\MerchantDetail;
|
6 |
-
use PayPalCheckoutSdk\Core\PayPalHttpClient;
|
7 |
-
use PayPalCheckoutSdk\Core\ProductionEnvironment;
|
8 |
-
use PayPalCheckoutSdk\Core\SandboxEnvironment;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Class PayPalClient
|
12 |
-
*
|
13 |
-
* @since 5.1.6
|
14 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal\SDK
|
15 |
-
*
|
16 |
-
*/
|
17 |
-
class PayPalClient {
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Environment mode.
|
21 |
-
*
|
22 |
-
* @since 5.1.6
|
23 |
-
*
|
24 |
-
* @var string
|
25 |
-
*/
|
26 |
-
public $mode = null;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* PayPalClient constructor.
|
30 |
-
*/
|
31 |
-
public function __construct() {
|
32 |
-
$this->mode = tribe_tickets_commerce_is_test_mode() ? 'sandbox' : 'live';
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Get environment.
|
37 |
-
*
|
38 |
-
* @since 5.1.6
|
39 |
-
*
|
40 |
-
* @return ProductionEnvironment|SandboxEnvironment
|
41 |
-
*/
|
42 |
-
public function getEnvironment() {
|
43 |
-
/* @var MerchantDetail $merchant */
|
44 |
-
$merchant = tribe( MerchantDetail::class );
|
45 |
-
|
46 |
-
return 'sandbox' === $this->mode ?
|
47 |
-
new SandboxEnvironment( $merchant->clientId, $merchant->clientSecret ) :
|
48 |
-
new ProductionEnvironment( $merchant->clientId, $merchant->clientSecret );
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Get http client.
|
53 |
-
*
|
54 |
-
* @since 5.1.6
|
55 |
-
*
|
56 |
-
* @return PayPalHttpClient
|
57 |
-
*/
|
58 |
-
public function getHttpClient() {
|
59 |
-
return new PayPalHttpClient( $this->getEnvironment() );
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Get api url.
|
64 |
-
*
|
65 |
-
* @since 5.1.6
|
66 |
-
*
|
67 |
-
* @param string $endpoint
|
68 |
-
*
|
69 |
-
* @return string
|
70 |
-
*/
|
71 |
-
public function getApiUrl( $endpoint ) {
|
72 |
-
$baseUrl = $this->getEnvironment()->baseUrl();
|
73 |
-
|
74 |
-
return "{$baseUrl}/$endpoint";
|
75 |
-
}
|
76 |
-
|
77 |
-
/**
|
78 |
-
* Get PayPal homepage url.
|
79 |
-
*
|
80 |
-
* @since 5.1.6
|
81 |
-
*
|
82 |
-
* @return string
|
83 |
-
*/
|
84 |
-
public function getHomePageUrl() {
|
85 |
-
$subdomain = 'sandbox' === $this->mode ? 'sandbox.' : '';
|
86 |
-
|
87 |
-
return sprintf(
|
88 |
-
'https://%1$spaypal.com/',
|
89 |
-
$subdomain
|
90 |
-
);
|
91 |
-
}
|
92 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/SDK/RefreshToken.php
DELETED
@@ -1,113 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\SDK;
|
4 |
-
|
5 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models\MerchantDetail;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\PayPalAuth;
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\MerchantDetails;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Class RefreshToken
|
11 |
-
*
|
12 |
-
* @since 5.1.6
|
13 |
-
*/
|
14 |
-
class RefreshToken {
|
15 |
-
|
16 |
-
/*
|
17 |
-
* @since 5.1.6
|
18 |
-
*
|
19 |
-
* @var MerchantDetail
|
20 |
-
*/
|
21 |
-
private $merchantDetail;
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @since 5.1.6
|
25 |
-
*
|
26 |
-
* @var MerchantDetails
|
27 |
-
*/
|
28 |
-
private $detailsRepository;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* @since 5.1.6
|
32 |
-
*
|
33 |
-
* @var PayPalAuth
|
34 |
-
*/
|
35 |
-
private $payPalAuth;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* RefreshToken constructor.
|
39 |
-
*
|
40 |
-
* @since 5.1.6
|
41 |
-
*
|
42 |
-
* @param MerchantDetails $detailsRepository
|
43 |
-
* @param PayPalAuth $payPalAuth
|
44 |
-
* @param MerchantDetail $merchantDetail
|
45 |
-
*/
|
46 |
-
public function __construct(
|
47 |
-
MerchantDetails $detailsRepository,
|
48 |
-
PayPalAuth $payPalAuth,
|
49 |
-
MerchantDetail $merchantDetail
|
50 |
-
) {
|
51 |
-
$this->detailsRepository = $detailsRepository;
|
52 |
-
$this->payPalAuth = $payPalAuth;
|
53 |
-
$this->merchantDetail = $merchantDetail;
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Return cron json name which uses to refresh token.
|
58 |
-
*
|
59 |
-
* @since 5.1.6
|
60 |
-
*
|
61 |
-
* @return string
|
62 |
-
*/
|
63 |
-
private function getCronJobHookName() {
|
64 |
-
return 'tribe_tickets_commerce_paypal_commerce_refresh_token';
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Register cron job to refresh access token.
|
69 |
-
* Note: only for internal use.
|
70 |
-
*
|
71 |
-
* @since 5.1.6
|
72 |
-
*
|
73 |
-
* @param string $tokenExpires What time the token expires.
|
74 |
-
*/
|
75 |
-
public function registerCronJobToRefreshToken( $tokenExpires ) {
|
76 |
-
// @todo Verify we need this as a cron, do we lose total API access if it expires (no visitors)?
|
77 |
-
wp_schedule_single_event(
|
78 |
-
// Refresh token before half hours of expires date.
|
79 |
-
time() + ( $tokenExpires - 1800 ),
|
80 |
-
$this->getCronJobHookName()
|
81 |
-
);
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* Delete cron job which refresh access token.
|
86 |
-
* Note: only for internal use.
|
87 |
-
*
|
88 |
-
* @since 5.1.6
|
89 |
-
*/
|
90 |
-
public function deleteRefreshTokenCronJob() {
|
91 |
-
wp_clear_scheduled_hook( $this->getCronJobHookName() );
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Refresh token.
|
96 |
-
* Note: only for internal use
|
97 |
-
*
|
98 |
-
* @since 5.1.6
|
99 |
-
*/
|
100 |
-
public function refreshToken() {
|
101 |
-
// Exit if account is not connected.
|
102 |
-
if ( ! $this->detailsRepository->accountIsConnected() ) {
|
103 |
-
return;
|
104 |
-
}
|
105 |
-
|
106 |
-
$tokenDetails = $this->payPalAuth->getTokenFromClientCredentials( $this->merchantDetail->clientId, $this->merchantDetail->clientSecret );
|
107 |
-
|
108 |
-
$this->merchantDetail->setTokenDetails( $tokenDetails );
|
109 |
-
$this->detailsRepository->save( $this->merchantDetail );
|
110 |
-
|
111 |
-
$this->registerCronJobToRefreshToken( $tokenDetails['expires_in'] );
|
112 |
-
}
|
113 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/MerchantDetails.php
DELETED
@@ -1,213 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories;
|
4 |
-
|
5 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models\MerchantDetail;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\PayPalClient;
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\Traits\HasMode;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Class MerchantDetails
|
11 |
-
*
|
12 |
-
* @since 5.1.6
|
13 |
-
*/
|
14 |
-
class MerchantDetails {
|
15 |
-
|
16 |
-
use HasMode;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Handle initial setup for the object singleton.
|
20 |
-
*
|
21 |
-
* @since 5.1.6
|
22 |
-
*/
|
23 |
-
public function init() {
|
24 |
-
$this->setMode( tribe_tickets_commerce_is_test_mode() ? 'sandbox' : 'live' );
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Returns whether or not the account has been connected
|
29 |
-
*
|
30 |
-
* @since 5.1.6
|
31 |
-
*
|
32 |
-
* @return bool
|
33 |
-
*/
|
34 |
-
public function accountIsConnected() {
|
35 |
-
/* @var $merchantDetail MerchantDetail */
|
36 |
-
$merchantDetail = tribe( MerchantDetail::class );
|
37 |
-
|
38 |
-
return (bool) $merchantDetail->merchantIdInPayPal;
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Get the merchant details data.
|
43 |
-
*
|
44 |
-
* @since 5.1.6
|
45 |
-
*
|
46 |
-
* @return array
|
47 |
-
*/
|
48 |
-
public function getDetailsData() {
|
49 |
-
return (array) get_option( $this->getAccountKey(), [] );
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Get merchant details.
|
54 |
-
*
|
55 |
-
* @since 5.1.6
|
56 |
-
*
|
57 |
-
* @return MerchantDetail
|
58 |
-
*/
|
59 |
-
public function getDetails() {
|
60 |
-
return MerchantDetail::fromArray( $this->getDetailsData() );
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Save merchant details.
|
65 |
-
*
|
66 |
-
* @since 5.1.6
|
67 |
-
*
|
68 |
-
* @param MerchantDetail $merchantDetails
|
69 |
-
*
|
70 |
-
* @return bool
|
71 |
-
*/
|
72 |
-
public function save( MerchantDetail $merchantDetails ) {
|
73 |
-
return update_option( $this->getAccountKey(), $merchantDetails->toArray() );
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Delete merchant details.
|
78 |
-
*
|
79 |
-
* @since 5.1.6
|
80 |
-
*
|
81 |
-
* @return bool
|
82 |
-
*/
|
83 |
-
public function delete() {
|
84 |
-
return delete_option( $this->getAccountKey() );
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* Returns the account errors if there are any
|
89 |
-
*
|
90 |
-
* @since 5.1.6
|
91 |
-
*
|
92 |
-
* @return string[]|null
|
93 |
-
*/
|
94 |
-
public function getAccountErrors() {
|
95 |
-
return get_option( $this->getAccountErrorsKey(), null );
|
96 |
-
}
|
97 |
-
|
98 |
-
/**
|
99 |
-
* Saves the account error message
|
100 |
-
*
|
101 |
-
* @since 5.1.6
|
102 |
-
*
|
103 |
-
* @param string[] $errorMessage
|
104 |
-
*
|
105 |
-
* @return bool
|
106 |
-
*/
|
107 |
-
public function saveAccountErrors( $errorMessage ) {
|
108 |
-
return update_option( $this->getAccountErrorsKey(), $errorMessage );
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Deletes the errors for the account
|
113 |
-
*
|
114 |
-
* @since 5.1.6
|
115 |
-
*
|
116 |
-
* @return bool
|
117 |
-
*/
|
118 |
-
public function deleteAccountErrors() {
|
119 |
-
return delete_option( $this->getAccountErrorsKey() );
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Deletes the client token for the account
|
124 |
-
*
|
125 |
-
* @since 5.1.6
|
126 |
-
*
|
127 |
-
* @return bool
|
128 |
-
*/
|
129 |
-
public function deleteClientToken() {
|
130 |
-
return delete_transient( $this->getClientTokenKey() );
|
131 |
-
}
|
132 |
-
|
133 |
-
/**
|
134 |
-
* Get client token for hosted credit card fields.
|
135 |
-
*
|
136 |
-
* @since 5.1.6
|
137 |
-
*
|
138 |
-
* @return string
|
139 |
-
*/
|
140 |
-
public function getClientToken() {
|
141 |
-
$optionName = $this->getClientTokenKey();
|
142 |
-
|
143 |
-
if ( $optionValue = get_transient( $optionName ) ) {
|
144 |
-
return $optionValue;
|
145 |
-
}
|
146 |
-
|
147 |
-
/** @var MerchantDetail $merchant */
|
148 |
-
$merchant = tribe( MerchantDetail::class );
|
149 |
-
|
150 |
-
$response = wp_remote_retrieve_body(
|
151 |
-
wp_remote_post(
|
152 |
-
tribe( PayPalClient::class )->getApiUrl( 'v1/identity/generate-token' ),
|
153 |
-
[
|
154 |
-
'headers' => [
|
155 |
-
'Accept' => 'application/json',
|
156 |
-
'Accept-Language' => 'en_US',
|
157 |
-
'Authorization' => sprintf( 'Bearer %1$s', $merchant->accessToken ),
|
158 |
-
'Content-Type' => 'application/json',
|
159 |
-
],
|
160 |
-
]
|
161 |
-
)
|
162 |
-
);
|
163 |
-
|
164 |
-
if ( ! $response ) {
|
165 |
-
return '';
|
166 |
-
}
|
167 |
-
|
168 |
-
// @todo Replace this with a new method somewhere else.
|
169 |
-
$response = ArrayDataSet::camelCaseKeys( json_decode( $response, true ) );
|
170 |
-
|
171 |
-
if ( ! array_key_exists( 'client_token', $response ) ) {
|
172 |
-
return '';
|
173 |
-
}
|
174 |
-
|
175 |
-
// Expire token before one minute to prevent unnecessary race condition.
|
176 |
-
set_transient( $optionName, $response['client_token'], $response['expires_in'] - 60 );
|
177 |
-
|
178 |
-
return $response['clientToken'];
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Returns the options key for the account in the give mode
|
183 |
-
*
|
184 |
-
* @since 5.1.6
|
185 |
-
*
|
186 |
-
* @return string
|
187 |
-
*/
|
188 |
-
public function getAccountKey() {
|
189 |
-
return "tribe_tickets_paypal_commerce_{$this->mode}_account";
|
190 |
-
}
|
191 |
-
|
192 |
-
/**
|
193 |
-
* Returns the options key for the account errors in the give mode
|
194 |
-
*
|
195 |
-
* @since 5.1.6
|
196 |
-
*
|
197 |
-
* @return string
|
198 |
-
*/
|
199 |
-
private function getAccountErrorsKey() {
|
200 |
-
return "tribe_tickets_paypal_commerce_{$this->mode}_account_errors";
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* Returns the options key for the client token in the give mode
|
205 |
-
*
|
206 |
-
* @since 5.1.6
|
207 |
-
*
|
208 |
-
* @return string
|
209 |
-
*/
|
210 |
-
private function getClientTokenKey() {
|
211 |
-
return "tribe_tickets_paypal_commerce_{$this->mode}_client_token";
|
212 |
-
}
|
213 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/PayPalAuth.php
DELETED
@@ -1,246 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories;
|
4 |
-
|
5 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Connect_Client;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\PayPalClient;
|
7 |
-
|
8 |
-
class PayPalAuth {
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @since 5.1.6
|
12 |
-
*
|
13 |
-
* @var PayPalClient
|
14 |
-
*/
|
15 |
-
private $payPalClient;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @since 5.1.6
|
19 |
-
*
|
20 |
-
* @var Connect_Client
|
21 |
-
*/
|
22 |
-
private $connectClient;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* PayPalAuth constructor.
|
26 |
-
*
|
27 |
-
* @since 5.1.6
|
28 |
-
*
|
29 |
-
* @param PayPalClient $payPalClient
|
30 |
-
* @param Connect_Client $connectClient
|
31 |
-
*/
|
32 |
-
public function __construct( PayPalClient $payPalClient, Connect_Client $connectClient ) {
|
33 |
-
$this->payPalClient = $payPalClient;
|
34 |
-
$this->connectClient = $connectClient;
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Retrieves a token for the Client ID and Secret.
|
39 |
-
*
|
40 |
-
* @since 5.1.6
|
41 |
-
*
|
42 |
-
* @param string $client_id The Client ID.
|
43 |
-
* @param string $client_secret The Client Secret.
|
44 |
-
*
|
45 |
-
* @return array|null The token details response or null if there was a problem.
|
46 |
-
*/
|
47 |
-
public function getTokenFromClientCredentials( $client_id, $client_secret ) {
|
48 |
-
$auth = base64_encode( "$client_id:$client_secret" );
|
49 |
-
|
50 |
-
$request = wp_remote_post( $this->payPalClient->getApiUrl( 'v1/oauth2/token' ), [
|
51 |
-
'headers' => [
|
52 |
-
'Authorization' => sprintf( 'Basic %1$s', $auth ),
|
53 |
-
'Content-Type' => 'application/x-www-form-urlencoded',
|
54 |
-
],
|
55 |
-
'body' => [
|
56 |
-
'grant_type' => 'client_credentials',
|
57 |
-
],
|
58 |
-
] );
|
59 |
-
|
60 |
-
if ( is_wp_error( $request ) ) {
|
61 |
-
tribe( 'logger' )->log_error( sprintf(
|
62 |
-
// Translators: %s: The error message.
|
63 |
-
__( 'PayPal request error: %s', 'event-tickets' ),
|
64 |
-
$request->get_error_message()
|
65 |
-
), 'tickets-commerce-paypal-commerce' );
|
66 |
-
|
67 |
-
return null;
|
68 |
-
}
|
69 |
-
|
70 |
-
$response = wp_remote_retrieve_body( $request );
|
71 |
-
$response = @json_decode( $response, true );
|
72 |
-
|
73 |
-
if ( ! is_array( $response ) ) {
|
74 |
-
tribe( 'logger' )->log_error( __( 'Unexpected PayPal response when getting token from client credentials', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
75 |
-
|
76 |
-
return null;
|
77 |
-
}
|
78 |
-
|
79 |
-
return $response;
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Retrieves a token from the authorization code.
|
84 |
-
*
|
85 |
-
* @since 5.1.6
|
86 |
-
*
|
87 |
-
* @param string $sharedId Shared ID for merchant.
|
88 |
-
* @param string $authCode Authorization code from onboarding.
|
89 |
-
* @param string $nonce Seller nonce from onboarding.
|
90 |
-
*
|
91 |
-
* @return array|null The token details response or null if there was a problem.
|
92 |
-
*/
|
93 |
-
public function getTokenFromAuthorizationCode( $sharedId, $authCode, $nonce ) {
|
94 |
-
$request = wp_remote_post( $this->payPalClient->getApiUrl( 'v1/oauth2/token' ), [
|
95 |
-
'headers' => [
|
96 |
-
'Authorization' => sprintf( 'Basic %1$s', base64_encode( $sharedId ) ),
|
97 |
-
'Content-Type' => 'application/x-www-form-urlencoded',
|
98 |
-
],
|
99 |
-
'body' => [
|
100 |
-
'grant_type' => 'authorization_code',
|
101 |
-
'code' => $authCode,
|
102 |
-
'code_verifier' => $nonce,
|
103 |
-
],
|
104 |
-
] );
|
105 |
-
|
106 |
-
if ( is_wp_error( $request ) ) {
|
107 |
-
tribe( 'logger' )->log_error( sprintf(
|
108 |
-
// Translators: %s: The error message.
|
109 |
-
__( 'PayPal request error: %s', 'event-tickets' ),
|
110 |
-
$request->get_error_message()
|
111 |
-
), 'tickets-commerce-paypal-commerce' );
|
112 |
-
|
113 |
-
return null;
|
114 |
-
}
|
115 |
-
|
116 |
-
$response = wp_remote_retrieve_body( $request );
|
117 |
-
$response = @json_decode( $response, true );
|
118 |
-
|
119 |
-
if ( ! is_array( $response ) ) {
|
120 |
-
tribe( 'logger' )->log_error( __( 'Unexpected PayPal response when getting token from authorization code', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
121 |
-
|
122 |
-
return null;
|
123 |
-
}
|
124 |
-
|
125 |
-
return $response;
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Retrieves a Partner Link for on-boarding
|
130 |
-
*
|
131 |
-
* @param $returnUrl
|
132 |
-
* @param $country
|
133 |
-
*
|
134 |
-
* @return array|null
|
135 |
-
*/
|
136 |
-
public function getSellerPartnerLink( $returnUrl, $country ) {
|
137 |
-
$request = wp_remote_post( sprintf( $this->connectClient->get_api_url( 'paypal-commerce/?mode=%1$s&request=partner-link' ), $this->payPalClient->mode ), [
|
138 |
-
'body' => [
|
139 |
-
'return_url' => $returnUrl,
|
140 |
-
'country_code' => $country,
|
141 |
-
],
|
142 |
-
// @todo Remove this when SSL is fixed.
|
143 |
-
'sslverify' => false,
|
144 |
-
] );
|
145 |
-
|
146 |
-
if ( is_wp_error( $request ) ) {
|
147 |
-
tribe( 'logger' )->log_error( sprintf(
|
148 |
-
// Translators: %s: The error message.
|
149 |
-
__( 'PayPal Commerce Connect request error: %s', 'event-tickets' ),
|
150 |
-
$request->get_error_message()
|
151 |
-
), 'tickets-commerce-paypal-commerce' );
|
152 |
-
|
153 |
-
return null;
|
154 |
-
}
|
155 |
-
|
156 |
-
$response = wp_remote_retrieve_body( $request );
|
157 |
-
$response = @json_decode( $response, true );
|
158 |
-
|
159 |
-
if ( ! is_array( $response ) ) {
|
160 |
-
tribe( 'logger' )->log_error( __( 'Unexpected PayPal Commerce Connect response', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
161 |
-
|
162 |
-
return null;
|
163 |
-
}
|
164 |
-
|
165 |
-
return $response;
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* Get seller on-boarding details from seller.
|
170 |
-
*
|
171 |
-
* @since 5.1.6
|
172 |
-
*
|
173 |
-
* @param string $accessToken
|
174 |
-
*
|
175 |
-
* @param string $merchantId
|
176 |
-
*
|
177 |
-
* @return array
|
178 |
-
*/
|
179 |
-
public function getSellerOnBoardingDetailsFromPayPal( $merchantId, $accessToken ) {
|
180 |
-
$request = wp_remote_post( $this->connectClient->get_api_url( sprintf( 'paypal-commerce/?mode=%1$s&request=seller-status', $this->payPalClient->mode ) ), [
|
181 |
-
'body' => [
|
182 |
-
'merchant_id' => $merchantId,
|
183 |
-
'token' => $accessToken,
|
184 |
-
],
|
185 |
-
] );
|
186 |
-
|
187 |
-
if ( is_wp_error( $request ) ) {
|
188 |
-
tribe( 'logger' )->log_error( sprintf(
|
189 |
-
// Translators: %s: The error message.
|
190 |
-
__( 'PayPal Commerce Connect request error: %s', 'event-tickets' ),
|
191 |
-
$request->get_error_message()
|
192 |
-
), 'tickets-commerce-paypal-commerce' );
|
193 |
-
|
194 |
-
return null;
|
195 |
-
}
|
196 |
-
|
197 |
-
$response = wp_remote_retrieve_body( $request );
|
198 |
-
$response = @json_decode( $response, true );
|
199 |
-
|
200 |
-
if ( ! is_array( $response ) ) {
|
201 |
-
tribe( 'logger' )->log_error( __( 'Unexpected PayPal Commerce Connect response', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
202 |
-
|
203 |
-
return null;
|
204 |
-
}
|
205 |
-
|
206 |
-
return $response;
|
207 |
-
}
|
208 |
-
|
209 |
-
/**
|
210 |
-
* Get seller rest API credentials
|
211 |
-
*
|
212 |
-
* @since 5.1.6
|
213 |
-
*
|
214 |
-
* @param string $accessToken
|
215 |
-
*
|
216 |
-
* @return array
|
217 |
-
*/
|
218 |
-
public function getSellerRestAPICredentials( $accessToken ) {
|
219 |
-
$request = wp_remote_post( $this->connectClient->get_api_url( sprintf( 'paypal-commerce/?mode=%1$s&request=seller-credentials', $this->payPalClient->mode ) ), [
|
220 |
-
'body' => [
|
221 |
-
'token' => $accessToken,
|
222 |
-
],
|
223 |
-
] );
|
224 |
-
|
225 |
-
if ( is_wp_error( $request ) ) {
|
226 |
-
tribe( 'logger' )->log_error( sprintf(
|
227 |
-
// Translators: %s: The error message.
|
228 |
-
__( 'PayPal Commerce Connect request error: %s', 'event-tickets' ),
|
229 |
-
$request->get_error_message()
|
230 |
-
), 'tickets-commerce-paypal-commerce' );
|
231 |
-
|
232 |
-
return null;
|
233 |
-
}
|
234 |
-
|
235 |
-
$response = wp_remote_retrieve_body( $request );
|
236 |
-
$response = @json_decode( $response, true );
|
237 |
-
|
238 |
-
if ( ! is_array( $response ) ) {
|
239 |
-
tribe( 'logger' )->log_error( __( 'Unexpected PayPal Commerce Connect response', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
240 |
-
|
241 |
-
return null;
|
242 |
-
}
|
243 |
-
|
244 |
-
return $response;
|
245 |
-
}
|
246 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/PayPalOrder.php
DELETED
@@ -1,175 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories;
|
4 |
-
|
5 |
-
use Exception;
|
6 |
-
use InvalidArgumentException;
|
7 |
-
|
8 |
-
// @todo Implement PayPal Checkout SDK.
|
9 |
-
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
|
10 |
-
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
|
11 |
-
use PayPalCheckoutSdk\Payments\CapturesRefundRequest;
|
12 |
-
|
13 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models\MerchantDetail;
|
14 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\PayPalClient;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Class PayPalOrder
|
18 |
-
*
|
19 |
-
* @since 5.1.6
|
20 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories
|
21 |
-
*
|
22 |
-
*/
|
23 |
-
class PayPalOrder {
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @since 5.1.6
|
27 |
-
*
|
28 |
-
* @var PayPalClient
|
29 |
-
*/
|
30 |
-
private $paypalClient;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @since 5.1.6
|
34 |
-
*
|
35 |
-
* @var MerchantDetail
|
36 |
-
*/
|
37 |
-
private $merchantDetails;
|
38 |
-
|
39 |
-
/**
|
40 |
-
* PayPalOrder constructor.
|
41 |
-
*
|
42 |
-
* @since 5.1.6
|
43 |
-
*
|
44 |
-
* @param MerchantDetail $merchantDetails
|
45 |
-
*
|
46 |
-
* @param PayPalClient $paypalClient
|
47 |
-
*/
|
48 |
-
public function __construct( PayPalClient $paypalClient, MerchantDetail $merchantDetails ) {
|
49 |
-
$this->paypalClient = $paypalClient;
|
50 |
-
$this->merchantDetails = $merchantDetails;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Approve order.
|
55 |
-
*
|
56 |
-
* @since 5.1.6
|
57 |
-
*
|
58 |
-
* @param string $orderId
|
59 |
-
*
|
60 |
-
* @return string
|
61 |
-
* @throws Exception
|
62 |
-
*/
|
63 |
-
public function approveOrder( $orderId ) {
|
64 |
-
$request = new OrdersCaptureRequest( $orderId );
|
65 |
-
|
66 |
-
try {
|
67 |
-
return $this->paypalClient->getHttpClient()->execute( $request )->result;
|
68 |
-
} catch ( Exception $ex ) {
|
69 |
-
// @todo Log the error.
|
70 |
-
logError( 'Capture PayPal Commerce payment failure', sprintf( '<strong>Response</strong><pre>%1$s</pre>', print_r( json_decode( $ex->getMessage(), true ), true ) ) );
|
71 |
-
|
72 |
-
throw $ex;
|
73 |
-
}
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Create order.
|
78 |
-
*
|
79 |
-
* @since 5.1.6
|
80 |
-
*
|
81 |
-
* @param array $array
|
82 |
-
*
|
83 |
-
* @return string
|
84 |
-
* @throws Exception
|
85 |
-
*/
|
86 |
-
public function createOrder( $array ) {
|
87 |
-
$this->validateCreateOrderArguments( $array );
|
88 |
-
|
89 |
-
$request = new OrdersCreateRequest();
|
90 |
-
// @todo Replace this with our bin code from Gateway::ATTRIBUTION_ID.
|
91 |
-
$request->payPalPartnerAttributionId( Give( 'PAYPAL_COMMERCE_ATTRIBUTION_ID' ) );
|
92 |
-
$request->body = [
|
93 |
-
'intent' => 'CAPTURE',
|
94 |
-
'purchase_units' => [
|
95 |
-
[
|
96 |
-
// @todo Replace this.
|
97 |
-
'reference_id' => get_post_field( 'post_name', $array['formId'] ),
|
98 |
-
// @todo Replace this.
|
99 |
-
'description' => $array['formTitle'],
|
100 |
-
'amount' => [
|
101 |
-
// @todo Replace this.
|
102 |
-
'value' => give_maybe_sanitize_amount( $array['paymentAmount'], [ 'currency' => give_get_currency( $array['formId'] ) ] ),
|
103 |
-
// @todo Replace this.
|
104 |
-
'currency_code' => give_get_currency( $array['formId'] ),
|
105 |
-
],
|
106 |
-
'payee' => [
|
107 |
-
'email_address' => $this->merchantDetails->merchantId,
|
108 |
-
'merchant_id' => $this->merchantDetails->merchantIdInPayPal,
|
109 |
-
],
|
110 |
-
'payer' => [
|
111 |
-
// @todo Replace these.
|
112 |
-
'given_name' => $array['payer']['firstName'],
|
113 |
-
'surname' => $array['payer']['lastName'],
|
114 |
-
'email_address' => $array['payer']['email'],
|
115 |
-
],
|
116 |
-
'payment_instruction' => [
|
117 |
-
'disbursement_mode' => 'INSTANT',
|
118 |
-
],
|
119 |
-
],
|
120 |
-
],
|
121 |
-
'application_context' => [
|
122 |
-
'shipping_preference' => 'NO_SHIPPING',
|
123 |
-
'user_action' => 'PAY_NOW',
|
124 |
-
],
|
125 |
-
];
|
126 |
-
|
127 |
-
try {
|
128 |
-
return $this->paypalClient->getHttpClient()->execute( $request )->result->id;
|
129 |
-
} catch ( Exception $ex ) {
|
130 |
-
logError( 'Create PayPal Commerce order failure', sprintf( '<strong>Request</strong><pre>%1$s</pre><br><strong>Response</strong><pre>%2$s</pre>', print_r( $request->body, true ), print_r( json_decode( $ex->getMessage(), true ), true ) ) );
|
131 |
-
|
132 |
-
throw $ex;
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Refunds a processed payment
|
138 |
-
*
|
139 |
-
* @since 5.1.6
|
140 |
-
*
|
141 |
-
* @param $captureId
|
142 |
-
*
|
143 |
-
* @return string The id of the refund
|
144 |
-
* @throws Exception
|
145 |
-
*/
|
146 |
-
public function refundPayment( $captureId ) {
|
147 |
-
$refund = new CapturesRefundRequest( $captureId );
|
148 |
-
|
149 |
-
try {
|
150 |
-
return $this->paypalClient->getHttpClient()->execute( $refund )->result->id;
|
151 |
-
} catch ( Exception $exception ) {
|
152 |
-
logError( 'Create PayPal Commerce payment refund failure', sprintf( '<strong>Response</strong><pre>%1$s</pre>', print_r( json_decode( $exception->getMessage(), true ), true ) ) );
|
153 |
-
|
154 |
-
throw $exception;
|
155 |
-
}
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Validate argument given to create PayPal order.
|
160 |
-
*
|
161 |
-
* @since 5.1.6
|
162 |
-
*
|
163 |
-
* @param array $array
|
164 |
-
*
|
165 |
-
* @throws InvalidArgumentException
|
166 |
-
*/
|
167 |
-
private function validateCreateOrderArguments( $array ) {
|
168 |
-
$required = [ 'formId', 'paymentAmount', 'payer' ];
|
169 |
-
$array = array_filter( $array ); // Remove empty values.
|
170 |
-
|
171 |
-
if ( array_diff( $required, array_keys( $array ) ) ) {
|
172 |
-
throw new InvalidArgumentException( __( 'To create a paypal order, please provide formId, paymentAmount and payer', 'event-tickets' ) );
|
173 |
-
}
|
174 |
-
}
|
175 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/SDK/Repositories/Traits/HasMode.php
DELETED
@@ -1,36 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\Traits;
|
4 |
-
|
5 |
-
use InvalidArgumentException;
|
6 |
-
|
7 |
-
trait HasMode {
|
8 |
-
|
9 |
-
/**
|
10 |
-
* The current working mode: live or sandbox
|
11 |
-
*
|
12 |
-
* @since 5.1.6
|
13 |
-
*
|
14 |
-
* @var string
|
15 |
-
*/
|
16 |
-
protected $mode;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Sets the mode for the repository for handling operations
|
20 |
-
*
|
21 |
-
* @since 5.1.6
|
22 |
-
*
|
23 |
-
* @param $mode
|
24 |
-
*
|
25 |
-
* @return $this
|
26 |
-
*/
|
27 |
-
public function setMode( $mode ) {
|
28 |
-
if ( ! in_array( $mode, [ 'live', 'sandbox' ], true ) ) {
|
29 |
-
throw new InvalidArgumentException( "Must be either 'live' or 'sandbox', received: $mode" );
|
30 |
-
}
|
31 |
-
|
32 |
-
$this->mode = $mode;
|
33 |
-
|
34 |
-
return $this;
|
35 |
-
}
|
36 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/Settings.php
CHANGED
@@ -3,9 +3,7 @@
|
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
|
5 |
use TEC\Tickets\Commerce\Abstract_Settings;
|
6 |
-
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models\WebhookConfig;
|
8 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\MerchantDetails;
|
9 |
use Tribe__Languages__Locations;
|
10 |
use Tribe__Tickets__Admin__Views;
|
11 |
use Tribe__Tickets__Main;
|
@@ -17,74 +15,6 @@ use Tribe__Tickets__Main;
|
|
17 |
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
18 |
*/
|
19 |
class Settings extends Abstract_Settings {
|
20 |
-
|
21 |
-
/**
|
22 |
-
* The option key for account country.
|
23 |
-
*
|
24 |
-
* @since 5.1.6
|
25 |
-
*
|
26 |
-
* @var string
|
27 |
-
*/
|
28 |
-
public $option_account_country = 'tickets-commerce-paypal-commerce-account-country';
|
29 |
-
|
30 |
-
/**
|
31 |
-
* The option key for access token.
|
32 |
-
*
|
33 |
-
* @since 5.1.6
|
34 |
-
*
|
35 |
-
* @var string
|
36 |
-
*/
|
37 |
-
public $option_access_token = 'tickets-commerce-paypal-commerce-access-token';
|
38 |
-
|
39 |
-
/**
|
40 |
-
* The option key for partner link detail.
|
41 |
-
*
|
42 |
-
* @since 5.1.6
|
43 |
-
*
|
44 |
-
* @var string
|
45 |
-
*/
|
46 |
-
public $option_partner_link_detail = 'tickets-commerce-paypal-commerce-partner-link-detail';
|
47 |
-
|
48 |
-
/**
|
49 |
-
* The option key for webhook config.
|
50 |
-
*
|
51 |
-
* @since 5.1.6
|
52 |
-
*
|
53 |
-
* @var string
|
54 |
-
*/
|
55 |
-
public $option_webhook_config = 'tickets-commerce-paypal-commerce-webhook-config';
|
56 |
-
|
57 |
-
/**
|
58 |
-
* The merchant detail model.
|
59 |
-
*
|
60 |
-
* @since 5.1.6
|
61 |
-
*
|
62 |
-
* @var MerchantDetail
|
63 |
-
*/
|
64 |
-
private $merchant_model;
|
65 |
-
|
66 |
-
/**
|
67 |
-
* The merchant details repository.
|
68 |
-
*
|
69 |
-
* @since 5.1.6
|
70 |
-
*
|
71 |
-
* @var MerchantDetails
|
72 |
-
*/
|
73 |
-
private $merchant_repository;
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Set up the things we need for the settings.
|
77 |
-
*
|
78 |
-
* @since 5.1.6
|
79 |
-
*
|
80 |
-
* @param MerchantDetail $merchantDetail
|
81 |
-
* @param MerchantDetails $merchantDetailRepository
|
82 |
-
*/
|
83 |
-
public function __construct( MerchantDetail $merchantDetail, MerchantDetails $merchantDetailRepository ) {
|
84 |
-
$this->merchant_model = $merchantDetail;
|
85 |
-
$this->merchant_repository = $merchantDetailRepository;
|
86 |
-
}
|
87 |
-
|
88 |
/**
|
89 |
* Get the list of settings for the gateway.
|
90 |
*
|
@@ -110,22 +40,6 @@ class Settings extends Abstract_Settings {
|
|
110 |
'html' => $this->get_introduction_html(),
|
111 |
'validation_type' => 'html',
|
112 |
],
|
113 |
-
$this->option_account_country => [
|
114 |
-
'type' => 'dropdown',
|
115 |
-
'label' => esc_html__( 'Account Country', 'event-tickets' ),
|
116 |
-
'tooltip' => esc_html__( 'This is the country your site operates from.', 'event-tickets' ),
|
117 |
-
'size' => 'medium',
|
118 |
-
'validation_type' => 'options',
|
119 |
-
'options' => $countries,
|
120 |
-
'required' => true, // @todo This is not working.
|
121 |
-
'can_be_empty' => false, // @todo This is not working.
|
122 |
-
],
|
123 |
-
'tickets-commerce-paypal-commerce-connect' => [
|
124 |
-
'type' => 'wrapped_html',
|
125 |
-
'label' => esc_html__( 'PayPal Connection', 'event-tickets' ),
|
126 |
-
'html' => $this->get_connect_html(),
|
127 |
-
'validation_type' => 'html',
|
128 |
-
],
|
129 |
];
|
130 |
}
|
131 |
|
@@ -149,31 +63,6 @@ class Settings extends Abstract_Settings {
|
|
149 |
return $admin_views->template( 'settings/tickets-commerce/paypal-commerce/introduction', [], false );
|
150 |
}
|
151 |
|
152 |
-
/**
|
153 |
-
* Get the Connect with PayPal HTML.
|
154 |
-
*
|
155 |
-
* @since 5.1.6
|
156 |
-
*
|
157 |
-
* @return string The Connect with PayPal HTML.
|
158 |
-
*/
|
159 |
-
public function get_connect_html() {
|
160 |
-
/** @var Tribe__Tickets__Admin__Views $admin_views */
|
161 |
-
$admin_views = tribe( 'tickets.admin.views' );
|
162 |
-
|
163 |
-
$account_errors = $this->merchant_repository->getAccountErrors();
|
164 |
-
|
165 |
-
$context = [
|
166 |
-
'account_is_connected' => $this->merchant_repository->accountIsConnected(),
|
167 |
-
'merchant_id' => $this->merchant_model->merchantId,
|
168 |
-
'formatted_errors' => $this->get_formatted_error_html( $account_errors ),
|
169 |
-
'guidance_html' => $this->get_guidance_html(),
|
170 |
-
];
|
171 |
-
|
172 |
-
$admin_views->add_template_globals( $context );
|
173 |
-
|
174 |
-
return $admin_views->template( 'settings/tickets-commerce/paypal-commerce/connect-with-paypal', [], false );
|
175 |
-
}
|
176 |
-
|
177 |
/**
|
178 |
* Get the guidance HTML.
|
179 |
*
|
@@ -361,129 +250,4 @@ class Settings extends Abstract_Settings {
|
|
361 |
public function update_account_country( $country ) {
|
362 |
return tribe_update_option( $this->option_account_country, $country );
|
363 |
}
|
364 |
-
|
365 |
-
/**
|
366 |
-
* Returns the account access token
|
367 |
-
*
|
368 |
-
* @since 5.1.6
|
369 |
-
*
|
370 |
-
* @return array|null
|
371 |
-
*/
|
372 |
-
public function get_access_token() {
|
373 |
-
$access_token = tribe_get_option( $this->option_access_token );
|
374 |
-
|
375 |
-
if ( ! is_array( $access_token ) ) {
|
376 |
-
return null;
|
377 |
-
}
|
378 |
-
|
379 |
-
return $access_token;
|
380 |
-
}
|
381 |
-
|
382 |
-
/**
|
383 |
-
* Updates the account access token.
|
384 |
-
*
|
385 |
-
* @since 5.1.6
|
386 |
-
*
|
387 |
-
* @param array $token The account access token.
|
388 |
-
*
|
389 |
-
* @return bool
|
390 |
-
*/
|
391 |
-
public function update_access_token( $token ) {
|
392 |
-
return tribe_update_option( $this->option_access_token, (array) $token );
|
393 |
-
}
|
394 |
-
|
395 |
-
/**
|
396 |
-
* Deletes the account access token
|
397 |
-
*
|
398 |
-
* @since 5.1.6
|
399 |
-
*
|
400 |
-
* @return bool
|
401 |
-
*/
|
402 |
-
public function delete_access_token() {
|
403 |
-
return tribe_update_option( $this->option_access_token, '' );
|
404 |
-
}
|
405 |
-
|
406 |
-
/**
|
407 |
-
* Returns the partner link details
|
408 |
-
*
|
409 |
-
* @since 5.1.6
|
410 |
-
*
|
411 |
-
* @since 5.1.6
|
412 |
-
*
|
413 |
-
* @return string|null
|
414 |
-
*/
|
415 |
-
public function get_partner_link_details() {
|
416 |
-
return tribe_get_option( $this->option_partner_link_detail, null );
|
417 |
-
}
|
418 |
-
|
419 |
-
/**
|
420 |
-
* Updates the partner link details
|
421 |
-
*
|
422 |
-
* @since 5.1.6
|
423 |
-
*
|
424 |
-
* @param $linkDetails
|
425 |
-
*
|
426 |
-
* @return bool
|
427 |
-
*/
|
428 |
-
public function update_partner_link_details( $linkDetails ) {
|
429 |
-
return tribe_update_option( $this->option_partner_link_detail, $linkDetails );
|
430 |
-
}
|
431 |
-
|
432 |
-
/**
|
433 |
-
* Deletes the partner link details
|
434 |
-
*
|
435 |
-
* @since 5.1.6
|
436 |
-
*
|
437 |
-
* @return bool
|
438 |
-
*/
|
439 |
-
public function delete_partner_link_details() {
|
440 |
-
return tribe_update_option( $this->option_partner_link_detail, '' );
|
441 |
-
}
|
442 |
-
|
443 |
-
/**
|
444 |
-
* Returns the webhook config.
|
445 |
-
*
|
446 |
-
* @since 5.1.6
|
447 |
-
*
|
448 |
-
* @param string $mode The mode (live/sandbox).
|
449 |
-
*
|
450 |
-
* @return WebhookConfig|null
|
451 |
-
*/
|
452 |
-
public function get_webhook_config( $mode ) {
|
453 |
-
$config = tribe_get_option( "{$this->option_webhook_config}-{$mode}", null );
|
454 |
-
|
455 |
-
if ( empty( $config ) ) {
|
456 |
-
return null;
|
457 |
-
}
|
458 |
-
|
459 |
-
return WebhookConfig::fromArray( $config );
|
460 |
-
}
|
461 |
-
|
462 |
-
/**
|
463 |
-
* Updates the webhook config.
|
464 |
-
*
|
465 |
-
* @since 5.1.6
|
466 |
-
*
|
467 |
-
* @param string $mode The mode (live/sandbox).
|
468 |
-
* @param WebhookConfig $config The webhook config array.
|
469 |
-
*
|
470 |
-
* @return bool
|
471 |
-
*/
|
472 |
-
public function update_webhook_config( $mode, WebhookConfig $config ) {
|
473 |
-
return tribe_update_option( "{$this->option_webhook_config}-{$mode}", $config->toArray() );
|
474 |
-
}
|
475 |
-
|
476 |
-
/**
|
477 |
-
* Deletes the webhook config.
|
478 |
-
*
|
479 |
-
* @since 5.1.6
|
480 |
-
*
|
481 |
-
* @param string $mode The mode (live/sandbox).
|
482 |
-
*
|
483 |
-
* @return bool
|
484 |
-
*/
|
485 |
-
public function delete_webhook_config( $mode ) {
|
486 |
-
return tribe_update_option( "{$this->option_webhook_config}-{$mode}", '' );
|
487 |
-
}
|
488 |
-
|
489 |
}
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
|
5 |
use TEC\Tickets\Commerce\Abstract_Settings;
|
6 |
+
|
|
|
|
|
7 |
use Tribe__Languages__Locations;
|
8 |
use Tribe__Tickets__Admin__Views;
|
9 |
use Tribe__Tickets__Main;
|
15 |
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
16 |
*/
|
17 |
class Settings extends Abstract_Settings {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* Get the list of settings for the gateway.
|
20 |
*
|
40 |
'html' => $this->get_introduction_html(),
|
41 |
'validation_type' => 'html',
|
42 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
];
|
44 |
}
|
45 |
|
63 |
return $admin_views->template( 'settings/tickets-commerce/paypal-commerce/introduction', [], false );
|
64 |
}
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
/**
|
67 |
* Get the guidance HTML.
|
68 |
*
|
250 |
public function update_account_country( $country ) {
|
251 |
return tribe_update_option( $this->option_account_country, $country );
|
252 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
}
|
src/Tickets/Commerce/Gateways/PayPal/Signup.php
ADDED
@@ -0,0 +1,235 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
use Tribe__Utils__Array as Arr;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Class Signup
|
8 |
+
*
|
9 |
+
* @since 5.1.9
|
10 |
+
*
|
11 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
12 |
+
*/
|
13 |
+
class Signup {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Holds the transient key used to store hash passed to PayPal.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
public static $signup_hash_meta_key = 'tec_tc_paypal_signup_hash';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Holds the transient key used to link PayPal to this site.
|
26 |
+
*
|
27 |
+
* @since 5.1.9
|
28 |
+
*
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public static $signup_data_meta_key = 'tec_tc_paypal_signup_data';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Stores the instance of the template engine that we will use for rendering the page.
|
35 |
+
*
|
36 |
+
* @since 5.1.9
|
37 |
+
*
|
38 |
+
* @var \Tribe__Template
|
39 |
+
*/
|
40 |
+
protected $template;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Gets the template instance used to setup the rendering of the page.
|
44 |
+
*
|
45 |
+
* @since 5.1.9
|
46 |
+
*
|
47 |
+
* @return \Tribe__Template
|
48 |
+
*/
|
49 |
+
public function get_template() {
|
50 |
+
if ( empty( $this->template ) ) {
|
51 |
+
$this->template = new \Tribe__Template();
|
52 |
+
$this->template->set_template_origin( \Tribe__Tickets__Main::instance() );
|
53 |
+
$this->template->set_template_folder( 'src/admin-views/commerce/gateways/paypal' );
|
54 |
+
$this->template->set_template_context_extract( true );
|
55 |
+
}
|
56 |
+
|
57 |
+
return $this->template;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Gets the saved hash for a given user, empty when non-existent.
|
62 |
+
*
|
63 |
+
* @since 5.1.9
|
64 |
+
*
|
65 |
+
* @return string
|
66 |
+
*/
|
67 |
+
public function get_transient_hash() {
|
68 |
+
return get_transient( static::$signup_hash_meta_key );
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Gets the saved hash for a given user, empty when non-existent.
|
73 |
+
*
|
74 |
+
* @since 5.1.9
|
75 |
+
*
|
76 |
+
* @param string $value Hash for signup.
|
77 |
+
*
|
78 |
+
* @return bool
|
79 |
+
*/
|
80 |
+
public function update_transient_hash( $value ) {
|
81 |
+
return set_transient( static::$signup_hash_meta_key, $value, DAY_IN_SECONDS );
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Delete Hash transient from the DB.
|
86 |
+
*
|
87 |
+
* @since 5.1.9
|
88 |
+
*
|
89 |
+
* @return bool
|
90 |
+
*/
|
91 |
+
public function delete_transient_hash() {
|
92 |
+
return delete_transient( static::$signup_hash_meta_key );
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Gets the saved hash for a given user, empty when non-existent.
|
97 |
+
*
|
98 |
+
* @since 5.1.9
|
99 |
+
*
|
100 |
+
* @return array
|
101 |
+
*/
|
102 |
+
public function get_transient_data() {
|
103 |
+
return get_transient( static::$signup_data_meta_key );
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Saves the URL in a transient for later use.
|
108 |
+
*
|
109 |
+
* @since 5.1.9
|
110 |
+
*
|
111 |
+
* @param string $value URL for signup.
|
112 |
+
*
|
113 |
+
* @return bool
|
114 |
+
*/
|
115 |
+
public function update_transient_data( $value ) {
|
116 |
+
return set_transient( static::$signup_data_meta_key, $value, DAY_IN_SECONDS );
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Delete url transient from the DB.
|
121 |
+
*
|
122 |
+
* @since 5.1.9
|
123 |
+
*
|
124 |
+
* @return bool
|
125 |
+
*/
|
126 |
+
public function delete_transient_data() {
|
127 |
+
return delete_transient( static::$signup_data_meta_key );
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Generate a Unique Hash for signup. It will always be 20 characters long.
|
132 |
+
*
|
133 |
+
* @since 5.1.9
|
134 |
+
*
|
135 |
+
* @return string
|
136 |
+
*/
|
137 |
+
public function generate_unique_signup_hash() {
|
138 |
+
$nonce_key = defined( 'NONCE_KEY' ) ? NONCE_KEY : uniqid( '', true );
|
139 |
+
$nonce_salt = defined( 'NONCE_SALT' ) ? NONCE_SALT : uniqid( '', true );
|
140 |
+
|
141 |
+
$unique = uniqid( '', true );
|
142 |
+
|
143 |
+
$keys = [ $nonce_key, $nonce_salt, $unique ];
|
144 |
+
$keys = array_map( 'md5', $keys );
|
145 |
+
|
146 |
+
return substr( str_shuffle( implode( '-', $keys ) ), 0, 45 );
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Generates a Tracking it for this website.
|
151 |
+
*
|
152 |
+
* @since 5.1.9
|
153 |
+
*
|
154 |
+
* @return string
|
155 |
+
*/
|
156 |
+
public function generate_unique_tracking_id() {
|
157 |
+
$id = wp_generate_password( 6, false, false );;
|
158 |
+
$url_frags = wp_parse_url( home_url() );
|
159 |
+
$url = Arr::get( $url_frags, 'host' ) . Arr::get( $url_frags, 'path' );
|
160 |
+
$url = add_query_arg( [
|
161 |
+
'v' => Gateway::VERSION . '-' . $id,
|
162 |
+
], $url );
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Tracking ID sent to PayPal.
|
166 |
+
*
|
167 |
+
* @since 5.1.9
|
168 |
+
*
|
169 |
+
* @param string $url Which ID we are using normally a URL, cannot be longer than 127 chars.
|
170 |
+
*/
|
171 |
+
$url = apply_filters( 'tec_tickets_commerce_gateway_paypal_tracking_id', $url );
|
172 |
+
|
173 |
+
// Always limit it to 127 chars.
|
174 |
+
return substr( (string) $url, 0, 127 );
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Request the signup link that redirects the seller to PayPal.
|
179 |
+
*
|
180 |
+
* @since 5.1.9
|
181 |
+
*
|
182 |
+
* @return string|false
|
183 |
+
*/
|
184 |
+
public function generate_url() {
|
185 |
+
// Fetch the cached value for this user.
|
186 |
+
$signup = $this->get_transient_data();
|
187 |
+
if ( $signup_url = Arr::get( $signup, [ 'links', 1, 'href' ] ) ) {
|
188 |
+
return $signup_url;
|
189 |
+
}
|
190 |
+
|
191 |
+
$hash = $this->generate_unique_signup_hash();
|
192 |
+
$this->update_transient_hash( $hash );
|
193 |
+
|
194 |
+
$signup = tribe( WhoDat::class )->get_seller_signup_data( $hash );
|
195 |
+
|
196 |
+
if ( ! $signup_url = Arr::get( $signup, [ 'links', 1, 'href' ] ) ) {
|
197 |
+
return false;
|
198 |
+
}
|
199 |
+
|
200 |
+
$this->update_transient_data( $signup );
|
201 |
+
|
202 |
+
return $signup_url;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* From the Transient data store we get the referral data link.
|
207 |
+
*
|
208 |
+
* @since 5.1.9
|
209 |
+
*
|
210 |
+
* @return false|string
|
211 |
+
*/
|
212 |
+
public function get_referral_data_link() {
|
213 |
+
$links = $this->get_transient_data();
|
214 |
+
if ( empty( $links ) ) {
|
215 |
+
return false;
|
216 |
+
}
|
217 |
+
|
218 |
+
return Arr::get( $links, [ 'links', 0, 'href' ], false );
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Gets the content for the template used for the sign up link that paypal creates.
|
223 |
+
*
|
224 |
+
* @since 5.1.9
|
225 |
+
*
|
226 |
+
* @return false|string
|
227 |
+
*/
|
228 |
+
public function get_link_html() {
|
229 |
+
$template_vars = [
|
230 |
+
'url' => $this->generate_url(),
|
231 |
+
];
|
232 |
+
|
233 |
+
return $this->get_template()->template( 'signup-link', $template_vars, false );
|
234 |
+
}
|
235 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Status.php
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Status as Commerce_Status;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Status
|
9 |
+
*
|
10 |
+
* @since 5.1.9
|
11 |
+
*
|
12 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
13 |
+
*/
|
14 |
+
class Status {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Order Status in PayPal for created.
|
18 |
+
*
|
19 |
+
* @since 5.1.9
|
20 |
+
*
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
CONST CREATED = 'CREATED';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Order Status in PayPal for saved.
|
27 |
+
*
|
28 |
+
* @since 5.1.9
|
29 |
+
*
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
CONST SAVED = 'SAVED';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Order Status in PayPal for approved.
|
36 |
+
*
|
37 |
+
* @since 5.1.9
|
38 |
+
*
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
CONST APPROVED = 'APPROVED';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Order Status in PayPal for voided.
|
45 |
+
*
|
46 |
+
* @since 5.1.9
|
47 |
+
*
|
48 |
+
* @var string
|
49 |
+
*/
|
50 |
+
CONST VOIDED = 'VOIDED';
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Order Status in PayPal for completed.
|
54 |
+
*
|
55 |
+
* @since 5.1.9
|
56 |
+
*
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
CONST COMPLETED = 'COMPLETED';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Order Status in PayPal for payer action required.
|
63 |
+
*
|
64 |
+
* @since 5.1.9
|
65 |
+
*
|
66 |
+
* @var string
|
67 |
+
*/
|
68 |
+
CONST PAYER_ACTION_REQUIRED = 'PAYER_ACTION_REQUIRED';
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Default mapping from PayPal Status to Tickets Commerce
|
72 |
+
*
|
73 |
+
* @since 5.1.9
|
74 |
+
*
|
75 |
+
* @var array
|
76 |
+
*/
|
77 |
+
protected $default_map = [
|
78 |
+
self::CREATED => Commerce_Status\Created::SLUG,
|
79 |
+
self::SAVED => Commerce_Status\Pending::SLUG,
|
80 |
+
self::APPROVED => Commerce_Status\Approved::SLUG,
|
81 |
+
self::VOIDED => Commerce_Status\Voided::SLUG,
|
82 |
+
self::COMPLETED => Commerce_Status\Completed::SLUG,
|
83 |
+
self::PAYER_ACTION_REQUIRED => Commerce_Status\Action_Required::SLUG,
|
84 |
+
];
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Gets the valid mapping of the statuses.
|
88 |
+
*
|
89 |
+
* @since 5.1.9
|
90 |
+
*
|
91 |
+
* @return array
|
92 |
+
*/
|
93 |
+
public function get_valid_statuses() {
|
94 |
+
return $this->default_map;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Checks if a given PayPal status is valid.
|
99 |
+
*
|
100 |
+
* @since 5.1.9
|
101 |
+
*
|
102 |
+
* @param string $status Status from PayPal.
|
103 |
+
*
|
104 |
+
* @return bool
|
105 |
+
*/
|
106 |
+
public function is_valid_status( $status ) {
|
107 |
+
$statuses = $this->get_valid_statuses();
|
108 |
+
return isset( $statuses[ $status ] );
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Converts a valid PayPal status into a commerce status object.
|
113 |
+
*
|
114 |
+
* @since 5.1.9
|
115 |
+
*
|
116 |
+
* @param string $paypal_status A PayPal status string.
|
117 |
+
*
|
118 |
+
* @return false|Commerce_Status\Status_Interface|null
|
119 |
+
*/
|
120 |
+
public function convert_to_commerce_status( $paypal_status ) {
|
121 |
+
if ( ! $this->is_valid_status( $paypal_status ) ) {
|
122 |
+
return false;
|
123 |
+
}
|
124 |
+
$statuses = $this->get_valid_statuses();
|
125 |
+
|
126 |
+
return tribe( Commerce_Status\Status_Handler::class )->get_by_slug( $statuses[ $paypal_status ] );
|
127 |
+
}
|
128 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php
ADDED
@@ -0,0 +1,221 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Attendee;
|
6 |
+
use TEC\Tickets\Commerce\Module;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Tickets_Form
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
14 |
+
*/
|
15 |
+
class Tickets_Form {
|
16 |
+
protected static $messages = [];
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Gets ticket messages
|
20 |
+
*
|
21 |
+
* @since 4.7
|
22 |
+
*
|
23 |
+
* @return array
|
24 |
+
*/
|
25 |
+
public function get_messages() {
|
26 |
+
return static::$messages;
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Adds a submission message
|
31 |
+
*
|
32 |
+
* @since 4.7
|
33 |
+
*
|
34 |
+
* @param $message
|
35 |
+
* @param string $type
|
36 |
+
*/
|
37 |
+
public function add_message( $message, $type = 'update' ) {
|
38 |
+
$message = apply_filters( 'tribe_tpp_submission_message', $message, $type );
|
39 |
+
static::$messages[] = (object) array( 'message' => $message, 'type' => $type );
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Filters the post_updated_messages array for attendees
|
45 |
+
*
|
46 |
+
* @since 4.7
|
47 |
+
*
|
48 |
+
* @param array $messages Array of update messages
|
49 |
+
*
|
50 |
+
* @return array
|
51 |
+
*/
|
52 |
+
public function updated_messages( $messages ) {
|
53 |
+
$ticket_post = get_post();
|
54 |
+
|
55 |
+
if ( ! $ticket_post ) {
|
56 |
+
return $messages;
|
57 |
+
}
|
58 |
+
|
59 |
+
$post_type = get_post_type( $ticket_post );
|
60 |
+
|
61 |
+
if ( Attendee::POSTTYPE !== $post_type ) {
|
62 |
+
return $messages;
|
63 |
+
}
|
64 |
+
|
65 |
+
$event = tribe( Module::class )->get_event_for_ticket( $ticket_post );
|
66 |
+
|
67 |
+
$attendees_report_url = add_query_arg(
|
68 |
+
array(
|
69 |
+
'post_type' => $event->post_type,
|
70 |
+
'page' => \Tribe__Tickets__Tickets_Handler::$attendees_slug,
|
71 |
+
'event_id' => $event->ID,
|
72 |
+
),
|
73 |
+
admin_url( 'edit.php' )
|
74 |
+
);
|
75 |
+
|
76 |
+
$return_link = sprintf(
|
77 |
+
esc_html__( 'Return to the %1$sAttendees Report%2$s.', 'event-tickets' ),
|
78 |
+
"<a href='" . esc_url( $attendees_report_url ) . "'>",
|
79 |
+
'</a>'
|
80 |
+
);
|
81 |
+
|
82 |
+
$messages[ Attendee::POSTTYPE ] = $messages['post'];
|
83 |
+
$messages[ Attendee::POSTTYPE ][1] = sprintf(
|
84 |
+
esc_html__( 'Post updated. %1$s', 'event-tickets' ),
|
85 |
+
$return_link
|
86 |
+
);
|
87 |
+
$messages[ Attendee::POSTTYPE ][6] = sprintf(
|
88 |
+
esc_html__( 'Post published. %1$s', 'event-tickets' ),
|
89 |
+
$return_link
|
90 |
+
);
|
91 |
+
$messages[ Attendee::POSTTYPE ][8] = esc_html__( 'Post submitted.', 'event-tickets' );
|
92 |
+
$messages[ Attendee::POSTTYPE ][9] = esc_html__( 'Post scheduled.', 'event-tickets' );
|
93 |
+
$messages[ Attendee::POSTTYPE ][10] = esc_html__( 'Post draft updated.', 'event-tickets' );
|
94 |
+
|
95 |
+
return $messages;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Whether the form has rendered already or not
|
100 |
+
*
|
101 |
+
* @var bool
|
102 |
+
*/
|
103 |
+
protected $has_rendered = false;
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Modifies the passed content to inject the front-end tickets form.
|
107 |
+
*
|
108 |
+
* @todo @juanfra We need to move this to use a whole new set of templates. This is currently still using
|
109 |
+
* Tribe Commerce templates and the old system.
|
110 |
+
*
|
111 |
+
* @since TBR
|
112 |
+
*
|
113 |
+
* @return void The method will echo in the context of a buffered output.
|
114 |
+
*
|
115 |
+
* @see Tribe__Tickets__Tickets::front_end_tickets_form_in_content
|
116 |
+
*/
|
117 |
+
public function render() {
|
118 |
+
if ( $this->has_rendered || ! tribe( Module::class )->is_active() ) {
|
119 |
+
return;
|
120 |
+
}
|
121 |
+
|
122 |
+
$post = get_post();
|
123 |
+
|
124 |
+
if ( empty( $post ) ) {
|
125 |
+
return;
|
126 |
+
}
|
127 |
+
|
128 |
+
// For recurring events (child instances only), default to loading tickets for the parent event
|
129 |
+
if ( ! empty( $post->post_parent ) && function_exists( 'tribe_is_recurring_event' ) && tribe_is_recurring_event( $post->ID ) ) {
|
130 |
+
$post = get_post( $post->post_parent );
|
131 |
+
}
|
132 |
+
|
133 |
+
$tickets = tribe( Module::class )->get_tickets( $post->ID );
|
134 |
+
|
135 |
+
foreach ( $tickets as $key => $ticket ) {
|
136 |
+
/** @var \Tribe__Tickets__Ticket_Object $ticket */
|
137 |
+
if ( ! $ticket->date_in_range() ) {
|
138 |
+
unset( $tickets[ $key ] );
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
if ( empty( $tickets ) ) {
|
143 |
+
return;
|
144 |
+
}
|
145 |
+
|
146 |
+
$ticket_sent = empty( $_GET['tpp_sent'] ) ? false : true;
|
147 |
+
|
148 |
+
if ( $ticket_sent ) {
|
149 |
+
$this->add_message( esc_html( sprintf( __( 'Your PayPal %1$s has been received! Check your email for your PayPal %1$s confirmation.', 'event-tickets' ), tribe_get_ticket_label_singular( 'ticket_sent' ) ) ), 'success' );
|
150 |
+
}
|
151 |
+
|
152 |
+
$ticket_error = empty( $_GET['tpp_error'] ) ? false : (int) $_GET['tpp_error'];
|
153 |
+
|
154 |
+
if ( $ticket_error ) {
|
155 |
+
$this->add_message( \Tribe__Tickets__Commerce__PayPal__Errors::error_code_to_message( $ticket_error ), 'error' );
|
156 |
+
}
|
157 |
+
|
158 |
+
$ticket_message = empty( $_GET['tpp_message'] ) ? false : (int) $_GET['tpp_message'];
|
159 |
+
|
160 |
+
if ( $ticket_message ) {
|
161 |
+
$this->add_message( \Tribe__Tickets__Commerce__PayPal__Errors::error_code_to_message( $ticket_message ), 'update' );
|
162 |
+
}
|
163 |
+
|
164 |
+
$must_login = ! is_user_logged_in() && tribe( Module::class )->login_required();
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Controls the visibility of the "Log it before purchasing" link below the tickets form
|
168 |
+
* for TPP tickets
|
169 |
+
*
|
170 |
+
* @since 4.9.3
|
171 |
+
*
|
172 |
+
*/
|
173 |
+
$display_login_link = apply_filters( 'tribe_tickets_show_login_before_purchasing_link', true );
|
174 |
+
|
175 |
+
ob_start();
|
176 |
+
tribe( Module::class )->getTemplateHierarchy( 'tickets/tpp' );
|
177 |
+
$form = ob_get_clean();
|
178 |
+
|
179 |
+
$currently_available_tickets = array_filter( $tickets, array( $this, 'is_currently_available' ) );
|
180 |
+
|
181 |
+
if ( count( $currently_available_tickets ) > 0 ) {
|
182 |
+
// If we have available tickets there is generally no need to display a 'tickets unavailable' message
|
183 |
+
// for this post
|
184 |
+
tribe( Module::class )->do_not_show_tickets_unavailable_message();
|
185 |
+
} else {
|
186 |
+
// Indicate that there are not any tickets, so a 'tickets unavailable' message may be
|
187 |
+
// appropriate (depending on whether other ticket providers are active and have a similar
|
188 |
+
// result)
|
189 |
+
tribe( Module::class )->maybe_show_tickets_unavailable_message( $tickets );
|
190 |
+
}
|
191 |
+
|
192 |
+
// It's only done when it's included
|
193 |
+
$this->has_rendered = true;
|
194 |
+
|
195 |
+
echo $form;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Sets whether the form rendered already or not.
|
200 |
+
*
|
201 |
+
* @since 4.7
|
202 |
+
*
|
203 |
+
* @param bool $has_rendered
|
204 |
+
*/
|
205 |
+
public function has_rendered( $has_rendered ) {
|
206 |
+
$this->has_rendered = (bool) $has_rendered;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* A utility method to filter the list of tickets by their currently available status.
|
211 |
+
*
|
212 |
+
* @since 4.7
|
213 |
+
*
|
214 |
+
* @param Tribe__Tickets__Ticket_Object $ticket
|
215 |
+
*
|
216 |
+
* @return bool
|
217 |
+
*/
|
218 |
+
protected function is_currently_available( \Tribe__Tickets__Ticket_Object $ticket ) {
|
219 |
+
return $ticket->date_in_range();
|
220 |
+
}
|
221 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/{SDK/DataTransferObjects/PayPalWebhookHeaders.php → Webhooks/Headers.php}
RENAMED
@@ -1,47 +1,47 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\
|
4 |
|
5 |
use Exception;
|
6 |
|
7 |
/**
|
8 |
-
* Class
|
9 |
*
|
10 |
-
* @since
|
11 |
*
|
12 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal\
|
13 |
*/
|
14 |
-
class
|
15 |
|
16 |
/**
|
17 |
* @since 5.1.6
|
18 |
* @var string
|
19 |
*/
|
20 |
-
public $
|
21 |
|
22 |
/**
|
23 |
* @since 5.1.6
|
24 |
* @var string
|
25 |
*/
|
26 |
-
public $
|
27 |
|
28 |
/**
|
29 |
* @since 5.1.6
|
30 |
* @var string
|
31 |
*/
|
32 |
-
public $
|
33 |
|
34 |
/**
|
35 |
* @since 5.1.6
|
36 |
* @var string
|
37 |
*/
|
38 |
-
public $
|
39 |
|
40 |
/**
|
41 |
* @since 5.1.6
|
42 |
* @var string
|
43 |
*/
|
44 |
-
public $
|
45 |
|
46 |
/**
|
47 |
* This grabs the headers from the webhook request to be used in the signature verification
|
@@ -51,23 +51,24 @@ class PayPalWebhookHeaders {
|
|
51 |
*
|
52 |
* @since 5.1.6
|
53 |
*
|
|
|
|
|
54 |
* @param array $headers
|
55 |
*
|
56 |
* @return self
|
57 |
-
* @throws HttpHeaderException
|
58 |
*/
|
59 |
-
public static function
|
60 |
-
$
|
61 |
-
'
|
62 |
-
'
|
63 |
-
'
|
64 |
-
'
|
65 |
-
'
|
66 |
];
|
67 |
|
68 |
-
$
|
69 |
-
$
|
70 |
-
foreach ( $
|
71 |
if ( ! isset( $headers[ $key ] ) ) {
|
72 |
$key = str_replace( '-', '_', $key );
|
73 |
$key = strtoupper( $key );
|
@@ -78,19 +79,19 @@ class PayPalWebhookHeaders {
|
|
78 |
}
|
79 |
|
80 |
if ( isset( $headers[ $key ] ) ) {
|
81 |
-
$
|
82 |
} else {
|
83 |
-
$
|
84 |
}
|
85 |
}
|
86 |
|
87 |
-
if ( ! empty( $
|
88 |
tribe( 'logger' )->log_error(
|
89 |
sprintf(
|
90 |
-
|
91 |
__( 'Missing PayPal webhook header: %s', 'event-tickets' ),
|
92 |
json_encode( [
|
93 |
-
'
|
94 |
'headers' => $headers,
|
95 |
] )
|
96 |
),
|
@@ -100,6 +101,6 @@ class PayPalWebhookHeaders {
|
|
100 |
throw new Exception( "Missing PayPal header: $key" );
|
101 |
}
|
102 |
|
103 |
-
return $
|
104 |
}
|
105 |
}
|
1 |
<?php
|
2 |
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks;
|
4 |
|
5 |
use Exception;
|
6 |
|
7 |
/**
|
8 |
+
* Class Headers.
|
9 |
*
|
10 |
+
* @since 5.1.6
|
11 |
*
|
12 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal\Webhooks
|
13 |
*/
|
14 |
+
class Headers {
|
15 |
|
16 |
/**
|
17 |
* @since 5.1.6
|
18 |
* @var string
|
19 |
*/
|
20 |
+
public $transmission_id;
|
21 |
|
22 |
/**
|
23 |
* @since 5.1.6
|
24 |
* @var string
|
25 |
*/
|
26 |
+
public $transmission_time;
|
27 |
|
28 |
/**
|
29 |
* @since 5.1.6
|
30 |
* @var string
|
31 |
*/
|
32 |
+
public $transmission_sig;
|
33 |
|
34 |
/**
|
35 |
* @since 5.1.6
|
36 |
* @var string
|
37 |
*/
|
38 |
+
public $cert_url;
|
39 |
|
40 |
/**
|
41 |
* @since 5.1.6
|
42 |
* @var string
|
43 |
*/
|
44 |
+
public $auth_algo;
|
45 |
|
46 |
/**
|
47 |
* This grabs the headers from the webhook request to be used in the signature verification
|
51 |
*
|
52 |
* @since 5.1.6
|
53 |
*
|
54 |
+
* @throws \HttpHeaderException
|
55 |
+
*
|
56 |
* @param array $headers
|
57 |
*
|
58 |
* @return self
|
|
|
59 |
*/
|
60 |
+
public static function from_headers( array $headers ) {
|
61 |
+
$header_keys = [
|
62 |
+
'transmission_id' => 'Paypal-Transmission-Id',
|
63 |
+
'transmission_time' => 'Paypal-Transmission-Time',
|
64 |
+
'transmission_sig' => 'Paypal-Transmission-Sig',
|
65 |
+
'cert_url' => 'Paypal-Cert-Url',
|
66 |
+
'auth_algo' => 'Paypal-Auth-Algo',
|
67 |
];
|
68 |
|
69 |
+
$paypal_headers = new self();
|
70 |
+
$missing_keys = [];
|
71 |
+
foreach ( $header_keys as $property => $key ) {
|
72 |
if ( ! isset( $headers[ $key ] ) ) {
|
73 |
$key = str_replace( '-', '_', $key );
|
74 |
$key = strtoupper( $key );
|
79 |
}
|
80 |
|
81 |
if ( isset( $headers[ $key ] ) ) {
|
82 |
+
$paypal_headers->{$property} = $headers[ $key ];
|
83 |
} else {
|
84 |
+
$missing_keys[] = $key;
|
85 |
}
|
86 |
}
|
87 |
|
88 |
+
if ( ! empty( $missing_keys ) ) {
|
89 |
tribe( 'logger' )->log_error(
|
90 |
sprintf(
|
91 |
+
// Translators: %s: The missing keys and header information.
|
92 |
__( 'Missing PayPal webhook header: %s', 'event-tickets' ),
|
93 |
json_encode( [
|
94 |
+
'missing_keys' => $missing_keys,
|
95 |
'headers' => $headers,
|
96 |
] )
|
97 |
),
|
101 |
throw new Exception( "Missing PayPal header: $key" );
|
102 |
}
|
103 |
|
104 |
+
return $paypal_headers;
|
105 |
}
|
106 |
}
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{EventListener.php → Event_Listener.php}
RENAMED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners;
|
4 |
|
5 |
-
interface
|
6 |
|
7 |
/**
|
8 |
* This processes the PayPal Commerce webhook event passed to it.
|
@@ -13,5 +13,5 @@ interface EventListener {
|
|
13 |
*
|
14 |
* @return bool Whether the event was processed successfully.
|
15 |
*/
|
16 |
-
public function
|
17 |
}
|
2 |
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners;
|
4 |
|
5 |
+
interface Event_Listener {
|
6 |
|
7 |
/**
|
8 |
* This processes the PayPal Commerce webhook event passed to it.
|
13 |
*
|
14 |
* @return bool Whether the event was processed successfully.
|
15 |
*/
|
16 |
+
public function process_event( $event );
|
17 |
}
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentCaptureCompleted.php → Payment_Capture_Completed.php}
RENAMED
@@ -9,7 +9,7 @@ namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners;
|
|
9 |
* @package TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners
|
10 |
*
|
11 |
*/
|
12 |
-
class
|
13 |
/**
|
14 |
* The new status to set with successful event.
|
15 |
*
|
9 |
* @package TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners
|
10 |
*
|
11 |
*/
|
12 |
+
class Payment_Capture_Completed extends Payment_Event_Listener {
|
13 |
/**
|
14 |
* The new status to set with successful event.
|
15 |
*
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentCaptureDenied.php → Payment_Capture_Denied.php}
RENAMED
@@ -9,7 +9,7 @@ namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners;
|
|
9 |
* @package TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners
|
10 |
*
|
11 |
*/
|
12 |
-
class
|
13 |
/**
|
14 |
* The new status to set with successful event.
|
15 |
*
|
9 |
* @package TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners
|
10 |
*
|
11 |
*/
|
12 |
+
class Payment_Capture_Denied extends Payment_Event_Listener {
|
13 |
/**
|
14 |
* The new status to set with successful event.
|
15 |
*
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentCaptureRefunded.php → Payment_Capture_Refunded.php}
RENAMED
@@ -9,7 +9,7 @@ namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners;
|
|
9 |
*
|
10 |
* @since 5.1.6
|
11 |
*/
|
12 |
-
class
|
13 |
/**
|
14 |
* The new status to set with successful event.
|
15 |
*
|
9 |
*
|
10 |
* @since 5.1.6
|
11 |
*/
|
12 |
+
class Payment_Capture_Refunded extends Payment_Event_Listener {
|
13 |
/**
|
14 |
* The new status to set with successful event.
|
15 |
*
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentCaptureReversed.php → Payment_Capture_Reversed.php}
RENAMED
@@ -9,7 +9,7 @@ namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners;
|
|
9 |
*
|
10 |
* @since 5.1.6
|
11 |
*/
|
12 |
-
class
|
13 |
/**
|
14 |
* The new status to set with successful event.
|
15 |
*
|
9 |
*
|
10 |
* @since 5.1.6
|
11 |
*/
|
12 |
+
class Payment_Capture_Reversed extends Payment_Event_Listener {
|
13 |
/**
|
14 |
* The new status to set with successful event.
|
15 |
*
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/Listeners/{PaymentEventListener.php → Payment_Event_Listener.php}
RENAMED
@@ -2,9 +2,9 @@
|
|
2 |
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners;
|
4 |
|
5 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\
|
8 |
use WP_Post;
|
9 |
|
10 |
/**
|
@@ -14,27 +14,27 @@ use WP_Post;
|
|
14 |
* @package TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners
|
15 |
*
|
16 |
*/
|
17 |
-
abstract class
|
18 |
/**
|
19 |
* @since 5.1.6
|
20 |
*
|
21 |
-
* @var
|
22 |
*/
|
23 |
-
private $
|
24 |
|
25 |
/**
|
26 |
* @since 5.1.6
|
27 |
*
|
28 |
* @var Webhooks
|
29 |
*/
|
30 |
-
private $
|
31 |
|
32 |
/**
|
33 |
* @since 5.1.6
|
34 |
*
|
35 |
-
* @var
|
36 |
*/
|
37 |
-
private $
|
38 |
|
39 |
/**
|
40 |
* The new status to set with successful event.
|
@@ -59,14 +59,14 @@ abstract class PaymentEventListener implements EventListener {
|
|
59 |
*
|
60 |
* @since 5.1.6
|
61 |
*
|
62 |
-
* @param
|
63 |
-
* @param
|
64 |
-
* @param Webhooks
|
65 |
*/
|
66 |
-
public function __construct(
|
67 |
-
$this->
|
68 |
-
$this->
|
69 |
-
$this->
|
70 |
}
|
71 |
|
72 |
/**
|
@@ -78,7 +78,7 @@ abstract class PaymentEventListener implements EventListener {
|
|
78 |
*
|
79 |
* @return bool Whether the event was processed successfully.
|
80 |
*/
|
81 |
-
public function
|
82 |
// No status set.
|
83 |
if ( ! $this->new_status ) {
|
84 |
return false;
|
@@ -93,7 +93,7 @@ abstract class PaymentEventListener implements EventListener {
|
|
93 |
if ( $this->event_type !== $event->event_type ) {
|
94 |
tribe( 'logger' )->log_debug(
|
95 |
sprintf(
|
96 |
-
|
97 |
__( 'Mismatched event type for webhook event: %s', 'event-tickets' ),
|
98 |
json_encode( $event )
|
99 |
),
|
@@ -103,12 +103,12 @@ abstract class PaymentEventListener implements EventListener {
|
|
103 |
return false;
|
104 |
}
|
105 |
|
106 |
-
$
|
107 |
|
108 |
-
if ( ! $
|
109 |
tribe( 'logger' )->log_debug(
|
110 |
sprintf(
|
111 |
-
|
112 |
__( 'Missing PayPal payment for webhook event: %s', 'event-tickets' ),
|
113 |
json_encode( $event )
|
114 |
),
|
@@ -118,15 +118,15 @@ abstract class PaymentEventListener implements EventListener {
|
|
118 |
return false;
|
119 |
}
|
120 |
|
121 |
-
$payment = $this->
|
122 |
|
123 |
// If there's no matching payment then it's not tracked by Tickets Commerce.
|
124 |
if ( ! $payment ) {
|
125 |
tribe( 'logger' )->log_debug(
|
126 |
sprintf(
|
127 |
-
|
128 |
__( 'Missing order for PayPal payment from webhook: %s', 'event-tickets' ),
|
129 |
-
$
|
130 |
),
|
131 |
'tickets-commerce-paypal-commerce'
|
132 |
);
|
@@ -149,10 +149,10 @@ abstract class PaymentEventListener implements EventListener {
|
|
149 |
|
150 |
tribe( 'logger' )->log_debug(
|
151 |
sprintf(
|
152 |
-
|
153 |
__( 'Change %1$s in PayPal from webhook: %2$s', 'event-tickets' ),
|
154 |
$this->new_status,
|
155 |
-
sprintf( '[Order ID: %s; PayPal Payment ID: %s]', $payment->ID, $
|
156 |
),
|
157 |
'tickets-commerce-paypal-commerce'
|
158 |
);
|
@@ -163,22 +163,22 @@ abstract class PaymentEventListener implements EventListener {
|
|
163 |
* @since 5.1.6
|
164 |
*
|
165 |
* @param WP_Post $payment The payment object.
|
166 |
-
* @param string $
|
167 |
* @param object $event The PayPal webhook event.
|
168 |
* @param string $new_status The new order status.
|
169 |
*/
|
170 |
-
do_action( 'tribe_tickets_commerce_gateways_paypal_commerce_webhooks_listeners', $payment, $
|
171 |
|
172 |
/**
|
173 |
* Allow hooking into the listener status for the new status.
|
174 |
*
|
175 |
* @since 5.1.6
|
176 |
*
|
177 |
-
* @param WP_Post $payment
|
178 |
-
* @param string $
|
179 |
-
* @param object $event
|
180 |
*/
|
181 |
-
do_action( "tribe_tickets_commerce_gateways_paypal_commerce_webhooks_listeners_{$this->new_status}", $payment, $
|
182 |
|
183 |
return true;
|
184 |
}
|
@@ -192,7 +192,7 @@ abstract class PaymentEventListener implements EventListener {
|
|
192 |
*
|
193 |
* @return \WP_Post|null The matching order or null if not found.
|
194 |
*/
|
195 |
-
public function
|
196 |
$orm = tribe_tickets_orders( 'tribe-commerce' );
|
197 |
|
198 |
return $orm->by( 'id', $id )->first();
|
@@ -207,7 +207,7 @@ abstract class PaymentEventListener implements EventListener {
|
|
207 |
*
|
208 |
* @return string|false The parent payment ID or false if not found.
|
209 |
*/
|
210 |
-
private function
|
211 |
$link = current( array_filter( $payment->links, static function ( $link ) {
|
212 |
return $link->rel === 'up';
|
213 |
} ) );
|
@@ -216,19 +216,17 @@ abstract class PaymentEventListener implements EventListener {
|
|
216 |
return false;
|
217 |
}
|
218 |
|
219 |
-
$accountDetails = $this->merchantDetails->getDetails();
|
220 |
-
|
221 |
$request = wp_remote_request( $link->href, [
|
222 |
'method' => $link->method,
|
223 |
'headers' => [
|
224 |
'Content-Type' => 'application/json',
|
225 |
-
'Authorization' => "Bearer {$
|
226 |
],
|
227 |
] );
|
228 |
|
229 |
if ( is_wp_error( $request ) ) {
|
230 |
tribe( 'logger' )->log_error( sprintf(
|
231 |
-
|
232 |
__( 'PayPal capture request error: %s', 'event-tickets' ),
|
233 |
$request->get_error_message()
|
234 |
), 'tickets-commerce-paypal-commerce' );
|
2 |
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners;
|
4 |
|
5 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
6 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Repositories\Webhooks;
|
7 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Webhook_Register;
|
8 |
use WP_Post;
|
9 |
|
10 |
/**
|
14 |
* @package TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners
|
15 |
*
|
16 |
*/
|
17 |
+
abstract class Payment_Event_Listener implements Event_Listener {
|
18 |
/**
|
19 |
* @since 5.1.6
|
20 |
*
|
21 |
+
* @var Merchant
|
22 |
*/
|
23 |
+
private $merchant;
|
24 |
|
25 |
/**
|
26 |
* @since 5.1.6
|
27 |
*
|
28 |
* @var Webhooks
|
29 |
*/
|
30 |
+
private $webhook_repository;
|
31 |
|
32 |
/**
|
33 |
* @since 5.1.6
|
34 |
*
|
35 |
+
* @var Webhook_Register
|
36 |
*/
|
37 |
+
private $webhook_register;
|
38 |
|
39 |
/**
|
40 |
* The new status to set with successful event.
|
59 |
*
|
60 |
* @since 5.1.6
|
61 |
*
|
62 |
+
* @param Merchant $merchant
|
63 |
+
* @param Webhook_Register $register
|
64 |
+
* @param Webhooks $webhook_repository
|
65 |
*/
|
66 |
+
public function __construct( Merchant $merchant, Webhook_Register $register, Webhooks $webhook_repository ) {
|
67 |
+
$this->merchant = $merchant;
|
68 |
+
$this->webhook_register = $register;
|
69 |
+
$this->webhook_repository = $webhook_repository;
|
70 |
}
|
71 |
|
72 |
/**
|
78 |
*
|
79 |
* @return bool Whether the event was processed successfully.
|
80 |
*/
|
81 |
+
public function process_event( $event ) {
|
82 |
// No status set.
|
83 |
if ( ! $this->new_status ) {
|
84 |
return false;
|
93 |
if ( $this->event_type !== $event->event_type ) {
|
94 |
tribe( 'logger' )->log_debug(
|
95 |
sprintf(
|
96 |
+
// Translators: %s: The PayPal payment event.
|
97 |
__( 'Mismatched event type for webhook event: %s', 'event-tickets' ),
|
98 |
json_encode( $event )
|
99 |
),
|
103 |
return false;
|
104 |
}
|
105 |
|
106 |
+
$payment_id = $this->get_parent_payment_id_from_payment( $event->resource );
|
107 |
|
108 |
+
if ( ! $payment_id ) {
|
109 |
tribe( 'logger' )->log_debug(
|
110 |
sprintf(
|
111 |
+
// Translators: %s: The PayPal payment event.
|
112 |
__( 'Missing PayPal payment for webhook event: %s', 'event-tickets' ),
|
113 |
json_encode( $event )
|
114 |
),
|
118 |
return false;
|
119 |
}
|
120 |
|
121 |
+
$payment = $this->get_order_by_payment_id( $payment_id );
|
122 |
|
123 |
// If there's no matching payment then it's not tracked by Tickets Commerce.
|
124 |
if ( ! $payment ) {
|
125 |
tribe( 'logger' )->log_debug(
|
126 |
sprintf(
|
127 |
+
// Translators: %s: The PayPal payment ID.
|
128 |
__( 'Missing order for PayPal payment from webhook: %s', 'event-tickets' ),
|
129 |
+
$payment_id
|
130 |
),
|
131 |
'tickets-commerce-paypal-commerce'
|
132 |
);
|
149 |
|
150 |
tribe( 'logger' )->log_debug(
|
151 |
sprintf(
|
152 |
+
// Translators: %1$s: The status name; %2$s: The payment information.
|
153 |
__( 'Change %1$s in PayPal from webhook: %2$s', 'event-tickets' ),
|
154 |
$this->new_status,
|
155 |
+
sprintf( '[Order ID: %s; PayPal Payment ID: %s]', $payment->ID, $payment_id )
|
156 |
),
|
157 |
'tickets-commerce-paypal-commerce'
|
158 |
);
|
163 |
* @since 5.1.6
|
164 |
*
|
165 |
* @param WP_Post $payment The payment object.
|
166 |
+
* @param string $payment_id The PayPal payment ID.
|
167 |
* @param object $event The PayPal webhook event.
|
168 |
* @param string $new_status The new order status.
|
169 |
*/
|
170 |
+
do_action( 'tribe_tickets_commerce_gateways_paypal_commerce_webhooks_listeners', $payment, $payment_id, $event, $this->new_status );
|
171 |
|
172 |
/**
|
173 |
* Allow hooking into the listener status for the new status.
|
174 |
*
|
175 |
* @since 5.1.6
|
176 |
*
|
177 |
+
* @param WP_Post $payment The payment object.
|
178 |
+
* @param string $payment_id The PayPal payment ID.
|
179 |
+
* @param object $event The PayPal webhook event.
|
180 |
*/
|
181 |
+
do_action( "tribe_tickets_commerce_gateways_paypal_commerce_webhooks_listeners_{$this->new_status}", $payment, $payment_id, $event );
|
182 |
|
183 |
return true;
|
184 |
}
|
192 |
*
|
193 |
* @return \WP_Post|null The matching order or null if not found.
|
194 |
*/
|
195 |
+
public function get_order_by_payment_id( $id ) {
|
196 |
$orm = tribe_tickets_orders( 'tribe-commerce' );
|
197 |
|
198 |
return $orm->by( 'id', $id )->first();
|
207 |
*
|
208 |
* @return string|false The parent payment ID or false if not found.
|
209 |
*/
|
210 |
+
private function get_parent_payment_id_from_payment( $payment ) {
|
211 |
$link = current( array_filter( $payment->links, static function ( $link ) {
|
212 |
return $link->rel === 'up';
|
213 |
} ) );
|
216 |
return false;
|
217 |
}
|
218 |
|
|
|
|
|
219 |
$request = wp_remote_request( $link->href, [
|
220 |
'method' => $link->method,
|
221 |
'headers' => [
|
222 |
'Content-Type' => 'application/json',
|
223 |
+
'Authorization' => "Bearer {$this->merchant->get_access_token()}",
|
224 |
],
|
225 |
] );
|
226 |
|
227 |
if ( is_wp_error( $request ) ) {
|
228 |
tribe( 'logger' )->log_error( sprintf(
|
229 |
+
// Translators: %s: The error message.
|
230 |
__( 'PayPal capture request error: %s', 'event-tickets' ),
|
231 |
$request->get_error_message()
|
232 |
), 'tickets-commerce-paypal-commerce' );
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/WebhookChecker.php
DELETED
@@ -1,104 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks;
|
4 |
-
|
5 |
-
use Exception;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models\MerchantDetail;
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\Webhooks;
|
8 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\WebhooksRoute;
|
9 |
-
|
10 |
-
class WebhookChecker {
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @since 5.1.6
|
14 |
-
*
|
15 |
-
* @var Webhooks
|
16 |
-
*/
|
17 |
-
private $webhooksRepository;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* @since 5.1.6
|
21 |
-
*
|
22 |
-
* @var WebhooksRoute
|
23 |
-
*/
|
24 |
-
private $webhooksRoute;
|
25 |
-
|
26 |
-
/**
|
27 |
-
* @since 5.1.6
|
28 |
-
*
|
29 |
-
* @var WebhookRegister
|
30 |
-
*/
|
31 |
-
private $webhookRegister;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* @since 5.1.6
|
35 |
-
*
|
36 |
-
* @var MerchantDetail
|
37 |
-
*/
|
38 |
-
private $merchantDetails;
|
39 |
-
|
40 |
-
/**
|
41 |
-
* WebhookChecker constructor.
|
42 |
-
*
|
43 |
-
* @since 5.1.6
|
44 |
-
*
|
45 |
-
* @param Webhooks $webhooksRepository
|
46 |
-
* @param MerchantDetail $merchantDetails
|
47 |
-
* @param WebhooksRoute $webhooksRoute
|
48 |
-
* @param WebhookRegister $webhookRegister
|
49 |
-
*/
|
50 |
-
public function __construct( Webhooks $webhooksRepository, MerchantDetail $merchantDetails, WebhooksRoute $webhooksRoute, WebhookRegister $webhookRegister ) {
|
51 |
-
$this->webhooksRepository = $webhooksRepository;
|
52 |
-
$this->merchantDetails = $merchantDetails;
|
53 |
-
$this->webhooksRoute = $webhooksRoute;
|
54 |
-
$this->webhookRegister = $webhookRegister;
|
55 |
-
}
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Checks whether the webhook configuration has changed. If it has, then update the webhook with PayPal.
|
59 |
-
*
|
60 |
-
* @since 5.1.6
|
61 |
-
*/
|
62 |
-
public function checkWebhookCriteria() {
|
63 |
-
if ( wp_doing_ajax() || wp_doing_cron() ) {
|
64 |
-
return;
|
65 |
-
}
|
66 |
-
|
67 |
-
if ( ! $this->merchantDetails->accessToken ) {
|
68 |
-
return;
|
69 |
-
}
|
70 |
-
|
71 |
-
$webhookConfig = $this->webhooksRepository->getWebhookConfig();
|
72 |
-
|
73 |
-
if ( $webhookConfig === null ) {
|
74 |
-
return;
|
75 |
-
}
|
76 |
-
|
77 |
-
$webhookUrl = $this->webhooksRoute->getRouteUrl();
|
78 |
-
$registeredEvents = $this->webhookRegister->getRegisteredEvents();
|
79 |
-
|
80 |
-
$missingEvents = array_merge(
|
81 |
-
array_diff( $registeredEvents, $webhookConfig->events ),
|
82 |
-
array_diff( $webhookConfig->events, $registeredEvents )
|
83 |
-
);
|
84 |
-
$hasMissingEvents = ! empty( $missingEvents );
|
85 |
-
|
86 |
-
// Update the webhook if the return url or events have changed
|
87 |
-
if ( $webhookUrl !== $webhookConfig->returnUrl || $hasMissingEvents ) {
|
88 |
-
try {
|
89 |
-
$this->webhooksRepository->updateWebhook( $this->merchantDetails->accessToken, $webhookConfig->id );
|
90 |
-
|
91 |
-
$webhookConfig->returnUrl = $webhookUrl;
|
92 |
-
$webhookConfig->events = $registeredEvents;
|
93 |
-
|
94 |
-
$this->webhooksRepository->saveWebhookConfig( $webhookConfig );
|
95 |
-
} catch ( Exception $exception ) {
|
96 |
-
// @todo Replace this with a notice / log.
|
97 |
-
tribe( 'logger' )->log_error(
|
98 |
-
__( 'There was a problem updating your PayPal Payments webhook. Please disconnect your account and reconnect it.', 'event-tickets' ),
|
99 |
-
'tickets-commerce-paypal-commerce'
|
100 |
-
);
|
101 |
-
}
|
102 |
-
}
|
103 |
-
}
|
104 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/Webhook_Checker.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks;
|
4 |
+
|
5 |
+
use Exception;
|
6 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
7 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Repositories\Webhooks;
|
8 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Webhooks_Route;
|
9 |
+
|
10 |
+
class Webhook_Checker {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @since 5.1.6
|
14 |
+
*
|
15 |
+
* @var Webhooks
|
16 |
+
*/
|
17 |
+
private $webhooks_repository;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @since 5.1.6
|
21 |
+
*
|
22 |
+
* @var Webhooks_Route
|
23 |
+
*/
|
24 |
+
private $webhooks_route;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @since 5.1.6
|
28 |
+
*
|
29 |
+
* @var Webhook_Register
|
30 |
+
*/
|
31 |
+
private $webhook_register;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @since 5.1.6
|
35 |
+
*
|
36 |
+
* @var Merchant
|
37 |
+
*/
|
38 |
+
private $merchant;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Webhook_Checker constructor.
|
42 |
+
*
|
43 |
+
* @since 5.1.6
|
44 |
+
*
|
45 |
+
* @param Webhooks $webhooks_repository
|
46 |
+
* @param Merchant $merchant
|
47 |
+
* @param Webhooks_Route $webhooks_route
|
48 |
+
* @param Webhook_Register $webhook_register
|
49 |
+
*/
|
50 |
+
public function __construct( Webhooks $webhooks_repository, Merchant $merchant, Webhooks_Route $webhooks_route, Webhook_Register $webhook_register ) {
|
51 |
+
$this->webhooks_repository = $webhooks_repository;
|
52 |
+
$this->merchant = $merchant;
|
53 |
+
$this->webhooks_route = $webhooks_route;
|
54 |
+
$this->webhook_register = $webhook_register;
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Checks whether the webhook configuration has changed. If it has, then update the webhook with PayPal.
|
59 |
+
*
|
60 |
+
* @since 5.1.6
|
61 |
+
*/
|
62 |
+
public function check_webhook_criteria() {
|
63 |
+
if ( wp_doing_ajax() || wp_doing_cron() ) {
|
64 |
+
return;
|
65 |
+
}
|
66 |
+
|
67 |
+
if ( ! $this->merchant->get_access_token() ) {
|
68 |
+
return;
|
69 |
+
}
|
70 |
+
|
71 |
+
$webhook_config = $this->webhooks_repository->get_webhook_config();
|
72 |
+
|
73 |
+
if ( $webhook_config === null ) {
|
74 |
+
return;
|
75 |
+
}
|
76 |
+
|
77 |
+
$webhook_url = $this->webhooks_route->get_route_url();
|
78 |
+
$registered_events = $this->webhook_register->get_registered_events();
|
79 |
+
|
80 |
+
$missing_events = array_merge(
|
81 |
+
array_diff( $registered_events, $webhook_config->events ),
|
82 |
+
array_diff( $webhook_config->events, $registered_events )
|
83 |
+
);
|
84 |
+
$has_missing_events = ! empty( $missing_events );
|
85 |
+
|
86 |
+
// Update the webhook if the return url or events have changed
|
87 |
+
if ( $webhook_url !== $webhook_config->return_url || $has_missing_events ) {
|
88 |
+
try {
|
89 |
+
$this->webhooks_repository->update_webhook( $this->merchant->get_access_token(), $webhook_config->id );
|
90 |
+
|
91 |
+
$webhook_config->return_url = $webhook_url;
|
92 |
+
$webhook_config->events = $registered_events;
|
93 |
+
|
94 |
+
$this->webhooks_repository->save_webhook_config( $webhook_config );
|
95 |
+
} catch ( Exception $exception ) {
|
96 |
+
// @todo Replace this with a notice / log.
|
97 |
+
tribe( 'logger' )->log_error(
|
98 |
+
__( 'There was a problem updating your PayPal Payments webhook. Please disconnect your account and reconnect it.', 'event-tickets' ),
|
99 |
+
'tickets-commerce-paypal-commerce'
|
100 |
+
);
|
101 |
+
}
|
102 |
+
}
|
103 |
+
}
|
104 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/{WebhookRegister.php → Webhook_Register.php}
RENAMED
@@ -3,13 +3,13 @@
|
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks;
|
4 |
|
5 |
use InvalidArgumentException;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\
|
8 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\
|
9 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\
|
10 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\
|
11 |
|
12 |
-
class
|
13 |
|
14 |
/**
|
15 |
* Array of the PayPal webhook event handlers. Add-ons can use the registerEventHandler method
|
@@ -21,11 +21,11 @@ class WebhookRegister {
|
|
21 |
*
|
22 |
* @var string[]
|
23 |
*/
|
24 |
-
private $
|
25 |
-
'PAYMENT.CAPTURE.COMPLETED' =>
|
26 |
-
'PAYMENT.CAPTURE.DENIED' =>
|
27 |
-
'PAYMENT.CAPTURE.REFUNDED' =>
|
28 |
-
'PAYMENT.CAPTURE.REVERSED' =>
|
29 |
];
|
30 |
|
31 |
/**
|
@@ -33,21 +33,21 @@ class WebhookRegister {
|
|
33 |
*
|
34 |
* @since 5.1.6
|
35 |
*
|
36 |
-
* @param string $
|
37 |
-
* @param string $
|
38 |
*
|
39 |
* @return $this
|
40 |
*/
|
41 |
-
public function
|
42 |
-
if ( isset( $this->
|
43 |
throw new InvalidArgumentException( 'Cannot register an already registered event' );
|
44 |
}
|
45 |
|
46 |
-
if ( ! is_subclass_of( $
|
47 |
-
throw new InvalidArgumentException( 'Listener must be a subclass of ' .
|
48 |
}
|
49 |
|
50 |
-
$this->
|
51 |
|
52 |
return $this;
|
53 |
}
|
@@ -59,9 +59,9 @@ class WebhookRegister {
|
|
59 |
*
|
60 |
* @param array $handlers = [ 'PAYPAL.EVENT' => EventHandler::class ]
|
61 |
*/
|
62 |
-
public function
|
63 |
foreach ( $handlers as $event => $handler ) {
|
64 |
-
$this->
|
65 |
}
|
66 |
}
|
67 |
|
@@ -72,10 +72,10 @@ class WebhookRegister {
|
|
72 |
*
|
73 |
* @param string $event
|
74 |
*
|
75 |
-
* @return
|
76 |
*/
|
77 |
-
public function
|
78 |
-
return tribe( $this->
|
79 |
}
|
80 |
|
81 |
/**
|
@@ -87,8 +87,8 @@ class WebhookRegister {
|
|
87 |
*
|
88 |
* @return bool
|
89 |
*/
|
90 |
-
public function
|
91 |
-
return isset( $this->
|
92 |
}
|
93 |
|
94 |
/**
|
@@ -98,7 +98,7 @@ class WebhookRegister {
|
|
98 |
*
|
99 |
* @return string[]
|
100 |
*/
|
101 |
-
public function
|
102 |
-
return array_keys( $this->
|
103 |
}
|
104 |
}
|
3 |
namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks;
|
4 |
|
5 |
use InvalidArgumentException;
|
6 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\Event_Listener;
|
7 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\Payment_Capture_Completed;
|
8 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\Payment_Capture_Denied;
|
9 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\Payment_Capture_Refunded;
|
10 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Listeners\Payment_Capture_Reversed;
|
11 |
|
12 |
+
class Webhook_Register {
|
13 |
|
14 |
/**
|
15 |
* Array of the PayPal webhook event handlers. Add-ons can use the registerEventHandler method
|
21 |
*
|
22 |
* @var string[]
|
23 |
*/
|
24 |
+
private $event_handlers = [
|
25 |
+
'PAYMENT.CAPTURE.COMPLETED' => Payment_Capture_Completed::class,
|
26 |
+
'PAYMENT.CAPTURE.DENIED' => Payment_Capture_Denied::class,
|
27 |
+
'PAYMENT.CAPTURE.REFUNDED' => Payment_Capture_Refunded::class,
|
28 |
+
'PAYMENT.CAPTURE.REVERSED' => Payment_Capture_Reversed::class,
|
29 |
];
|
30 |
|
31 |
/**
|
33 |
*
|
34 |
* @since 5.1.6
|
35 |
*
|
36 |
+
* @param string $paypal_event PayPal event to listen for, i.e. CHECKOUT.ORDER.APPROVED
|
37 |
+
* @param string $event_handler The FQCN of the event handler
|
38 |
*
|
39 |
* @return $this
|
40 |
*/
|
41 |
+
public function register_event_handler( $paypal_event, $event_handler ) {
|
42 |
+
if ( isset( $this->event_handlers[ $paypal_event ] ) ) {
|
43 |
throw new InvalidArgumentException( 'Cannot register an already registered event' );
|
44 |
}
|
45 |
|
46 |
+
if ( ! is_subclass_of( $event_handler, Event_Listener::class ) ) {
|
47 |
+
throw new InvalidArgumentException( 'Listener must be a subclass of ' . Event_Listener::class );
|
48 |
}
|
49 |
|
50 |
+
$this->event_handlers[ $paypal_event ] = $event_handler;
|
51 |
|
52 |
return $this;
|
53 |
}
|
59 |
*
|
60 |
* @param array $handlers = [ 'PAYPAL.EVENT' => EventHandler::class ]
|
61 |
*/
|
62 |
+
public function register_event_handlers( array $handlers ) {
|
63 |
foreach ( $handlers as $event => $handler ) {
|
64 |
+
$this->register_event_handler( $event, $handler );
|
65 |
}
|
66 |
}
|
67 |
|
72 |
*
|
73 |
* @param string $event
|
74 |
*
|
75 |
+
* @return Event_Listener
|
76 |
*/
|
77 |
+
public function get_event_handler( $event ) {
|
78 |
+
return tribe( $this->event_handlers[ $event ] );
|
79 |
}
|
80 |
|
81 |
/**
|
87 |
*
|
88 |
* @return bool
|
89 |
*/
|
90 |
+
public function has_event_registered( $event ) {
|
91 |
+
return isset( $this->event_handlers[ $event ] );
|
92 |
}
|
93 |
|
94 |
/**
|
98 |
*
|
99 |
* @return string[]
|
100 |
*/
|
101 |
+
public function get_registered_events() {
|
102 |
+
return array_keys( $this->event_handlers );
|
103 |
}
|
104 |
}
|
src/Tickets/Commerce/Gateways/PayPal/Webhooks/{WebhooksRoute.php → Webhooks_Route.php}
RENAMED
@@ -4,47 +4,46 @@ namespace TEC\Tickets\Commerce\Gateways\PayPal\Webhooks;
|
|
4 |
|
5 |
use Exception;
|
6 |
use TEC\Tickets\Commerce\Gateways\PayPal\REST;
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
8 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
9 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
10 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\
|
11 |
-
use Tribe\Tickets\REST\V1\Endpoints\Commerce\PayPal_Webhook;
|
12 |
|
13 |
-
class
|
14 |
/**
|
15 |
* @since 5.1.6
|
16 |
*
|
17 |
-
* @var
|
18 |
*/
|
19 |
-
private $
|
20 |
|
21 |
/**
|
22 |
* @since 5.1.6
|
23 |
*
|
24 |
* @var Webhooks
|
25 |
*/
|
26 |
-
private $
|
27 |
|
28 |
/**
|
29 |
* @since 5.1.6
|
30 |
*
|
31 |
-
* @var
|
32 |
*/
|
33 |
-
private $
|
34 |
|
35 |
/**
|
36 |
-
*
|
37 |
*
|
38 |
* @since 5.1.6
|
39 |
*
|
40 |
-
* @param
|
41 |
-
* @param
|
42 |
-
* @param Webhooks
|
43 |
*/
|
44 |
-
public function __construct(
|
45 |
-
$this->
|
46 |
-
$this->
|
47 |
-
$this->
|
48 |
}
|
49 |
|
50 |
/**
|
@@ -54,14 +53,12 @@ class WebhooksRoute {
|
|
54 |
*
|
55 |
* @return string The REST API route URL.
|
56 |
*/
|
57 |
-
public function
|
58 |
/** @var REST $rest */
|
59 |
-
$rest
|
|
|
60 |
|
61 |
-
|
62 |
-
$endpoint = tribe( PayPal_Webhook::class );
|
63 |
-
|
64 |
-
return rest_url( '/' . $rest->namespace . $endpoint->path, 'https' );
|
65 |
}
|
66 |
|
67 |
/**
|
@@ -70,20 +67,20 @@ class WebhooksRoute {
|
|
70 |
*
|
71 |
* @since 5.1.6
|
72 |
*
|
73 |
-
* @
|
|
|
74 |
* @param array $headers The list of HTTP headers for the request.
|
75 |
*
|
|
|
|
|
76 |
* @return bool Whether the event was processed.
|
77 |
*
|
78 |
-
* @throws Exception
|
79 |
*/
|
80 |
public function handle( $event, $headers = [] ) {
|
81 |
-
if ( ! $this->
|
82 |
return false;
|
83 |
}
|
84 |
|
85 |
-
$merchantDetails = $this->merchantRepository->getDetails();
|
86 |
-
|
87 |
// Try to decode the event.
|
88 |
if ( ! is_object( $event ) ) {
|
89 |
$event = @json_decode( $event );
|
@@ -95,10 +92,10 @@ class WebhooksRoute {
|
|
95 |
}
|
96 |
|
97 |
// If we receive an event that we're not expecting, just ignore it
|
98 |
-
if ( ! $this->
|
99 |
tribe( 'logger' )->log_debug(
|
100 |
sprintf(
|
101 |
-
|
102 |
__( 'PayPal webhook event type not registered or supported: %s', 'event-tickets' ),
|
103 |
$event->event_type
|
104 |
),
|
@@ -110,32 +107,32 @@ class WebhooksRoute {
|
|
110 |
|
111 |
tribe( 'logger' )->log_debug(
|
112 |
sprintf(
|
113 |
-
|
114 |
__( 'Received PayPal webhook event for type: %s', 'event-tickets' ),
|
115 |
$event->event_type
|
116 |
),
|
117 |
'tickets-commerce-paypal-commerce'
|
118 |
);
|
119 |
|
120 |
-
$
|
121 |
|
122 |
-
if ( ! $this->
|
123 |
tribe( 'logger' )->log_error( __( 'Failed PayPal webhook event verification', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
124 |
|
125 |
throw new Exception( 'Failed event verification' );
|
126 |
}
|
127 |
|
128 |
try {
|
129 |
-
return $this->
|
130 |
-
->
|
131 |
-
->
|
132 |
} catch ( Exception $exception ) {
|
133 |
-
$
|
134 |
|
135 |
tribe( 'logger' )->log_error( sprintf(
|
136 |
-
|
137 |
__( 'Error processing webhook: %s', 'event-tickets' ),
|
138 |
-
$
|
139 |
), 'tickets-commerce-paypal-commerce' );
|
140 |
|
141 |
throw $exception;
|
4 |
|
5 |
use Exception;
|
6 |
use TEC\Tickets\Commerce\Gateways\PayPal\REST;
|
7 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
8 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Repositories\Webhooks;
|
9 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Headers;
|
10 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Webhook_Register;
|
|
|
11 |
|
12 |
+
class Webhooks_Route {
|
13 |
/**
|
14 |
* @since 5.1.6
|
15 |
*
|
16 |
+
* @var Merchant
|
17 |
*/
|
18 |
+
private $merchant;
|
19 |
|
20 |
/**
|
21 |
* @since 5.1.6
|
22 |
*
|
23 |
* @var Webhooks
|
24 |
*/
|
25 |
+
private $webhook_repository;
|
26 |
|
27 |
/**
|
28 |
* @since 5.1.6
|
29 |
*
|
30 |
+
* @var Webhook_Register
|
31 |
*/
|
32 |
+
private $webhook_register;
|
33 |
|
34 |
/**
|
35 |
+
* Webhooks_Route constructor.
|
36 |
*
|
37 |
* @since 5.1.6
|
38 |
*
|
39 |
+
* @param Merchant $merchant
|
40 |
+
* @param Webhook_Register $register
|
41 |
+
* @param Webhooks $webhook_repository
|
42 |
*/
|
43 |
+
public function __construct( Merchant $merchant, Webhook_Register $register, Webhooks $webhook_repository ) {
|
44 |
+
$this->merchant = $merchant;
|
45 |
+
$this->webhook_register = $register;
|
46 |
+
$this->webhook_repository = $webhook_repository;
|
47 |
}
|
48 |
|
49 |
/**
|
53 |
*
|
54 |
* @return string The REST API route URL.
|
55 |
*/
|
56 |
+
public function get_route_url() {
|
57 |
/** @var REST $rest */
|
58 |
+
$rest = tribe( REST::class );
|
59 |
+
$endpoint = tribe( REST\Webhook::class );
|
60 |
|
61 |
+
return rest_url( '/' . $rest->namespace . $endpoint->get_endpoint_path(), 'https' );
|
|
|
|
|
|
|
62 |
}
|
63 |
|
64 |
/**
|
67 |
*
|
68 |
* @since 5.1.6
|
69 |
*
|
70 |
+
* @throws Exception
|
71 |
+
*
|
72 |
* @param array $headers The list of HTTP headers for the request.
|
73 |
*
|
74 |
+
* @param string|object $event The PayPal payment event object.
|
75 |
+
*
|
76 |
* @return bool Whether the event was processed.
|
77 |
*
|
|
|
78 |
*/
|
79 |
public function handle( $event, $headers = [] ) {
|
80 |
+
if ( ! $this->merchant->account_is_connected() ) {
|
81 |
return false;
|
82 |
}
|
83 |
|
|
|
|
|
84 |
// Try to decode the event.
|
85 |
if ( ! is_object( $event ) ) {
|
86 |
$event = @json_decode( $event );
|
92 |
}
|
93 |
|
94 |
// If we receive an event that we're not expecting, just ignore it
|
95 |
+
if ( ! $this->webhook_register->has_event_registered( $event->event_type ) ) {
|
96 |
tribe( 'logger' )->log_debug(
|
97 |
sprintf(
|
98 |
+
// Translators: %s: The event type.
|
99 |
__( 'PayPal webhook event type not registered or supported: %s', 'event-tickets' ),
|
100 |
$event->event_type
|
101 |
),
|
107 |
|
108 |
tribe( 'logger' )->log_debug(
|
109 |
sprintf(
|
110 |
+
// Translators: %s: The event type.
|
111 |
__( 'Received PayPal webhook event for type: %s', 'event-tickets' ),
|
112 |
$event->event_type
|
113 |
),
|
114 |
'tickets-commerce-paypal-commerce'
|
115 |
);
|
116 |
|
117 |
+
$paypal_headers = Headers::from_headers( $headers );
|
118 |
|
119 |
+
if ( ! $this->webhook_repository->verify_event_signature( $this->merchant->get_access_token(), $event, $paypal_headers ) ) {
|
120 |
tribe( 'logger' )->log_error( __( 'Failed PayPal webhook event verification', 'event-tickets' ), 'tickets-commerce-paypal-commerce' );
|
121 |
|
122 |
throw new Exception( 'Failed event verification' );
|
123 |
}
|
124 |
|
125 |
try {
|
126 |
+
return $this->webhook_register
|
127 |
+
->get_event_handler( $event->event_type )
|
128 |
+
->process_event( $event );
|
129 |
} catch ( Exception $exception ) {
|
130 |
+
$event_type = empty( $event->event_type ) ? 'Unknown' : $event->event_type;
|
131 |
|
132 |
tribe( 'logger' )->log_error( sprintf(
|
133 |
+
// Translators: %s: The event type.
|
134 |
__( 'Error processing webhook: %s', 'event-tickets' ),
|
135 |
+
$event_type
|
136 |
), 'tickets-commerce-paypal-commerce' );
|
137 |
|
138 |
throw $exception;
|
src/Tickets/Commerce/Gateways/PayPal/WhoDat.php
ADDED
@@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\REST\On_Boarding_Endpoint;
|
6 |
+
use Tribe__Utils__Array as Arr;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Connect_Client
|
10 |
+
*
|
11 |
+
* @since 5.1.6
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
14 |
+
*/
|
15 |
+
class WhoDat {
|
16 |
+
/**
|
17 |
+
* The API URL.
|
18 |
+
*
|
19 |
+
* @since 5.1.6
|
20 |
+
*
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
protected $api_url = 'https://whodat.theeventscalendar.com/commerce/v1/paypal';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Get REST API endpoint URL for requests.
|
27 |
+
*
|
28 |
+
* @since 5.1.9
|
29 |
+
*
|
30 |
+
*
|
31 |
+
* @param string $endpoint The endpoint path.
|
32 |
+
* @param array $query_args Query args appended to the URL.
|
33 |
+
*
|
34 |
+
* @return string The API URL.
|
35 |
+
*/
|
36 |
+
public function get_api_url( $endpoint, array $query_args = [] ) {
|
37 |
+
return add_query_arg( $query_args, "{$this->api_url}/{$endpoint}" );
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Fetch the signup link from PayPal.
|
42 |
+
*
|
43 |
+
* @since 5.1.9
|
44 |
+
*
|
45 |
+
* @return array|string
|
46 |
+
*/
|
47 |
+
public function get_seller_signup_data( $hash ) {
|
48 |
+
if ( empty( $hash ) ) {
|
49 |
+
$hash = tribe( Signup::class )->generate_unique_signup_hash();
|
50 |
+
}
|
51 |
+
|
52 |
+
$return_url = tribe( On_Boarding_Endpoint::class )->get_return_url( $hash );
|
53 |
+
$query_args = [
|
54 |
+
'mode' => tribe( Merchant::class )->get_mode(),
|
55 |
+
'nonce' => $hash,
|
56 |
+
'tracking_id' => urlencode( tribe( Signup::class )->generate_unique_tracking_id() ),
|
57 |
+
'return_url' => esc_url( $return_url ),
|
58 |
+
];
|
59 |
+
|
60 |
+
return $this->get( 'seller/signup', $query_args );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Fetch the seller referral Data from WhoDat/PayPal.
|
65 |
+
*
|
66 |
+
* @since 5.1.9
|
67 |
+
*
|
68 |
+
* @param string $url Which URL WhoDat needs to request.
|
69 |
+
*
|
70 |
+
* @return array
|
71 |
+
*/
|
72 |
+
public function get_seller_referral_data( $url ) {
|
73 |
+
$query_args = [
|
74 |
+
'mode' => tribe( Merchant::class )->get_mode(),
|
75 |
+
'url' => $url
|
76 |
+
];
|
77 |
+
|
78 |
+
return $this->get( 'seller/referral-data', $query_args );
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Verify if the seller was successfully onboarded.
|
83 |
+
*
|
84 |
+
* @since 5.1.9
|
85 |
+
*
|
86 |
+
* @param string $saved_merchant_id The ID we are looking at Paypal with.
|
87 |
+
*
|
88 |
+
* @return array
|
89 |
+
*/
|
90 |
+
public function get_seller_status( $saved_merchant_id ) {
|
91 |
+
$query_args = [
|
92 |
+
'mode' => tribe( Merchant::class )->get_mode(),
|
93 |
+
'merchant_id' => $saved_merchant_id
|
94 |
+
];
|
95 |
+
|
96 |
+
return $this->post( 'seller/status', $query_args );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Get seller rest API credentials
|
101 |
+
*
|
102 |
+
* @since 5.1.9
|
103 |
+
*
|
104 |
+
* @param string $access_token
|
105 |
+
*
|
106 |
+
* @return array|null
|
107 |
+
*/
|
108 |
+
public function get_seller_credentials( $access_token ) {
|
109 |
+
$query_args = [
|
110 |
+
'mode' => tribe( Merchant::class )->get_mode(),
|
111 |
+
'access_token' => $access_token,
|
112 |
+
];
|
113 |
+
|
114 |
+
return $this->post( 'seller/credentials', $query_args );
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Send a GET request to WhoDat.
|
119 |
+
*
|
120 |
+
* @since 5.1.9
|
121 |
+
*
|
122 |
+
* @param string $endpoint
|
123 |
+
* @param array $query_args
|
124 |
+
*
|
125 |
+
* @return mixed|null
|
126 |
+
*/
|
127 |
+
public function get( $endpoint, array $query_args ) {
|
128 |
+
$url = $this->get_api_url( $endpoint, $query_args );
|
129 |
+
|
130 |
+
$request = wp_remote_get( $url );
|
131 |
+
|
132 |
+
if ( is_wp_error( $request ) ) {
|
133 |
+
$this->log_error( 'WhoDat request error:', $request->get_error_message(), $url );
|
134 |
+
|
135 |
+
return null;
|
136 |
+
}
|
137 |
+
|
138 |
+
$body = wp_remote_retrieve_body( $request );
|
139 |
+
$body = json_decode( $body, true );
|
140 |
+
|
141 |
+
return $body;
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Send a POST request to WhoDat.
|
146 |
+
*
|
147 |
+
* @since 5.1.9
|
148 |
+
*
|
149 |
+
* @param string $endpoint
|
150 |
+
* @param array $query_args
|
151 |
+
* @param array $request_arguments
|
152 |
+
*
|
153 |
+
* @return array|null
|
154 |
+
*/
|
155 |
+
public function post( $endpoint, array $query_args = [], array $request_arguments = [] ) {
|
156 |
+
$url = $this->get_api_url( $endpoint, $query_args );
|
157 |
+
|
158 |
+
$default_arguments = [
|
159 |
+
'body' => [],
|
160 |
+
];
|
161 |
+
$request_arguments = array_merge_recursive( $default_arguments, $request_arguments );
|
162 |
+
$request = wp_remote_post( $url, $request_arguments );
|
163 |
+
|
164 |
+
if ( is_wp_error( $request ) ) {
|
165 |
+
$this->log_error( 'WhoDat request error:', $request->get_error_message(), $url );
|
166 |
+
|
167 |
+
return null;
|
168 |
+
}
|
169 |
+
|
170 |
+
$body = wp_remote_retrieve_body( $request );
|
171 |
+
$body = json_decode( $body, true );
|
172 |
+
|
173 |
+
if ( ! is_array( $body ) ) {
|
174 |
+
$this->log_error( 'WhoDat unexpected response:', $body, $url );
|
175 |
+
|
176 |
+
return null;
|
177 |
+
}
|
178 |
+
|
179 |
+
return $body;
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Log WhoDat errors.
|
184 |
+
*
|
185 |
+
* @since 5.1.9
|
186 |
+
*
|
187 |
+
* @param string $type
|
188 |
+
* @param string $message
|
189 |
+
* @param string $url
|
190 |
+
*/
|
191 |
+
protected function log_error( $type, $message, $url ) {
|
192 |
+
$log = sprintf(
|
193 |
+
'[%s] %s %s',
|
194 |
+
$url,
|
195 |
+
$type,
|
196 |
+
$message
|
197 |
+
);
|
198 |
+
tribe( 'logger' )->log_error( $log, 'whodat-connection' );
|
199 |
+
}
|
200 |
+
}
|
src/Tickets/Commerce/Gateways/PayPal/onBoardingRedirectHandler.php
DELETED
@@ -1,487 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace TEC\Tickets\Commerce\Gateways\PayPal;
|
4 |
-
|
5 |
-
use Exception;
|
6 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Models\MerchantDetail;
|
7 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\PayPalAuth;
|
8 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\MerchantDetails;
|
9 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\SDK\Repositories\Webhooks;
|
10 |
-
use Tribe__Settings;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Class PayPalOnBoardingRedirectHandler
|
14 |
-
*
|
15 |
-
* @since 5.1.6
|
16 |
-
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
17 |
-
*
|
18 |
-
*/
|
19 |
-
class onBoardingRedirectHandler {
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @since 5.1.6
|
23 |
-
*
|
24 |
-
* @var PayPalAuth
|
25 |
-
*/
|
26 |
-
private $payPalAuth;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @since 5.1.6
|
30 |
-
*
|
31 |
-
* @var Webhooks
|
32 |
-
*/
|
33 |
-
private $webhooksRepository;
|
34 |
-
|
35 |
-
/**
|
36 |
-
* @since 5.1.6
|
37 |
-
*
|
38 |
-
* @var MerchantDetails
|
39 |
-
*/
|
40 |
-
private $merchantRepository;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* @since 5.1.6
|
44 |
-
*
|
45 |
-
* @var Settings
|
46 |
-
*/
|
47 |
-
private $settings;
|
48 |
-
|
49 |
-
/**
|
50 |
-
* onBoardingRedirectHandler constructor.
|
51 |
-
*
|
52 |
-
* @since 5.1.6
|
53 |
-
*
|
54 |
-
* @param Webhooks $webhooks
|
55 |
-
* @param MerchantDetails $merchantRepository
|
56 |
-
* @param Settings $settings
|
57 |
-
* @param PayPalAuth $payPalAuth
|
58 |
-
*/
|
59 |
-
public function __construct( Webhooks $webhooks, MerchantDetails $merchantRepository, Settings $settings, PayPalAuth $payPalAuth ) {
|
60 |
-
$this->webhooksRepository = $webhooks;
|
61 |
-
$this->merchantRepository = $merchantRepository;
|
62 |
-
$this->settings = $settings;
|
63 |
-
$this->payPalAuth = $payPalAuth;
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Bootstrap class
|
68 |
-
*
|
69 |
-
* @since 5.1.6
|
70 |
-
*/
|
71 |
-
public function boot() {
|
72 |
-
if ( $this->isPayPalUserRedirected() ) {
|
73 |
-
$merchantId = tribe_get_request_var( 'merchantId' );
|
74 |
-
$merchantIdInPayPal = tribe_get_request_var( 'merchantIdInPayPal' );
|
75 |
-
|
76 |
-
$details = $this->savePayPalMerchantDetails( $merchantId, $merchantIdInPayPal );
|
77 |
-
|
78 |
-
$this->setUpWebhook( $details );
|
79 |
-
$this->redirectAccountConnected();
|
80 |
-
|
81 |
-
return;
|
82 |
-
}
|
83 |
-
|
84 |
-
if ( $this->werePayPalAccountDetailsSaved() ) {
|
85 |
-
$this->registerPayPalSSLNotice();
|
86 |
-
$this->registerPayPalAccountConnectedNotice();
|
87 |
-
}
|
88 |
-
|
89 |
-
if ( $this->isStatusRefresh() ) {
|
90 |
-
$this->refreshAccountStatus();
|
91 |
-
$this->redirectAccountConnected();
|
92 |
-
|
93 |
-
return;
|
94 |
-
}
|
95 |
-
}
|
96 |
-
|
97 |
-
/**
|
98 |
-
* Save PayPal merchant details
|
99 |
-
*
|
100 |
-
* @since 5.1.6
|
101 |
-
*
|
102 |
-
* @param string $merchantId The merchant ID.
|
103 |
-
* @param string $merchantIdInPayPal The merchant ID in PayPal.
|
104 |
-
*
|
105 |
-
* @return MerchantDetail
|
106 |
-
*/
|
107 |
-
private function savePayPalMerchantDetails( $merchantId, $merchantIdInPayPal ) {
|
108 |
-
$partnerLinkInfo = $this->settings->get_partner_link_details();
|
109 |
-
$tokenInfo = $this->settings->get_access_token();
|
110 |
-
|
111 |
-
$payPalAccount = [
|
112 |
-
'merchantId' => $merchantId,
|
113 |
-
'merchantIdInPayPal' => $merchantIdInPayPal,
|
114 |
-
];
|
115 |
-
|
116 |
-
$errors = [];
|
117 |
-
|
118 |
-
if ( empty( $payPalAccount['merchantIdInPayPal'] ) ) {
|
119 |
-
$errors[] = [
|
120 |
-
'type' => 'url',
|
121 |
-
'message' => esc_html__( 'There was a problem with PayPal return url and we could not find valid merchant ID. Paypal return URL is:', 'event-tickets' ) . "\n",
|
122 |
-
'value' => urlencode( $_SERVER['QUERY_STRING'] ),
|
123 |
-
];
|
124 |
-
|
125 |
-
// Log error messages.
|
126 |
-
array_map( static function( $errorMessage ) {
|
127 |
-
$errorMessage = is_array( $errorMessage ) ? $errorMessage['message'] . ' ' . $errorMessage['value'] : $errorMessage;
|
128 |
-
tribe( 'logger' )->log_error( $errorMessage, 'tickets-commerce-paypal-commerce' );
|
129 |
-
}, $errors );
|
130 |
-
|
131 |
-
$this->merchantRepository->saveAccountErrors( $errors );
|
132 |
-
|
133 |
-
$this->redirectWhenOnBoardingFail();
|
134 |
-
}
|
135 |
-
|
136 |
-
$restApiCredentials = (array) $this->payPalAuth->getSellerRestAPICredentials( $tokenInfo ? $tokenInfo['access_token'] : '' );
|
137 |
-
|
138 |
-
$this->didWeGetValidSellerRestApiCredentials( $restApiCredentials );
|
139 |
-
|
140 |
-
$tokenInfo = $this->payPalAuth->getTokenFromClientCredentials( $restApiCredentials['client_id'], $restApiCredentials['client_secret'] );
|
141 |
-
//$this->settings->update_access_token( $tokenInfo );
|
142 |
-
|
143 |
-
$payPalAccount['clientId'] = $restApiCredentials['client_id'];
|
144 |
-
$payPalAccount['clientSecret'] = $restApiCredentials['client_secret'];
|
145 |
-
$payPalAccount['token'] = $tokenInfo;
|
146 |
-
$payPalAccount['supportsCustomPayments'] = 'PPCP' === $partnerLinkInfo['product'];
|
147 |
-
$payPalAccount['accountIsReady'] = true;
|
148 |
-
$payPalAccount['accountCountry'] = $this->settings->get_account_country();
|
149 |
-
|
150 |
-
$merchantDetails = MerchantDetail::fromArray( $payPalAccount );
|
151 |
-
$this->merchantRepository->save( $merchantDetails );
|
152 |
-
|
153 |
-
return $merchantDetails;
|
154 |
-
}
|
155 |
-
|
156 |
-
/**
|
157 |
-
* Redirects the user to the account connected url
|
158 |
-
*
|
159 |
-
* @since 5.1.6
|
160 |
-
*/
|
161 |
-
private function redirectAccountConnected() {
|
162 |
-
$this->refreshAccountStatus();
|
163 |
-
|
164 |
-
/** @var Tribe__Settings $settings */
|
165 |
-
$settings = tribe( 'settings' );
|
166 |
-
|
167 |
-
// Get link to Tickets Tab.
|
168 |
-
$settings_url = $settings->get_url(
|
169 |
-
[
|
170 |
-
'page' => 'tribe-common',
|
171 |
-
'tab' => 'event-tickets',
|
172 |
-
'paypal-commerce-account-connected' => '1',
|
173 |
-
]
|
174 |
-
) . '#tribe-field-tickets-commerce-paypal-commerce';
|
175 |
-
|
176 |
-
wp_redirect( $settings_url );
|
177 |
-
die();
|
178 |
-
}
|
179 |
-
|
180 |
-
/**
|
181 |
-
* Sets up the webhook for the connected account
|
182 |
-
*
|
183 |
-
* @since 5.1.6
|
184 |
-
*
|
185 |
-
* @param MerchantDetail $merchant_details
|
186 |
-
*/
|
187 |
-
private function setUpWebhook( MerchantDetail $merchant_details ) {
|
188 |
-
if ( ! is_ssl() ) {
|
189 |
-
return;
|
190 |
-
}
|
191 |
-
|
192 |
-
try {
|
193 |
-
$webhookConfig = $this->webhooksRepository->createWebhook( $merchant_details->accessToken );
|
194 |
-
|
195 |
-
$this->webhooksRepository->saveWebhookConfig( $webhookConfig );
|
196 |
-
} catch ( Exception $ex ) {
|
197 |
-
tribe( 'logger' )->log_error( $ex->getMessage(), 'tickets-commerce-paypal-commerce' );
|
198 |
-
|
199 |
-
$errors = [];
|
200 |
-
|
201 |
-
$errors[] = esc_html__( 'There was a problem with creating webhook on PayPal. A gateway error log also added to get details information about PayPal response.', 'event-tickets' );
|
202 |
-
|
203 |
-
// Log error messages.
|
204 |
-
array_map( static function( $errorMessage ) {
|
205 |
-
$errorMessage = is_array( $errorMessage ) ? $errorMessage['message'] . ' ' . $errorMessage['value'] : $errorMessage;
|
206 |
-
tribe( 'logger' )->log_error( $errorMessage, 'tickets-commerce-paypal-commerce' );
|
207 |
-
}, $errors );
|
208 |
-
|
209 |
-
$this->merchantRepository->saveAccountErrors( $errors );
|
210 |
-
$this->redirectWhenOnBoardingFail();
|
211 |
-
}
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* Register notice if account connect success fully.
|
216 |
-
*
|
217 |
-
* @since 5.1.6
|
218 |
-
*/
|
219 |
-
private function registerPayPalAccountConnectedNotice() {
|
220 |
-
tribe_notice(
|
221 |
-
'paypal-commerce-account-connected',
|
222 |
-
sprintf(
|
223 |
-
'<p>%s</p>',
|
224 |
-
esc_html__( 'PayPal Commerce account connected successfully.', 'event-tickets' )
|
225 |
-
),
|
226 |
-
[
|
227 |
-
'type' => 'success',
|
228 |
-
]
|
229 |
-
);
|
230 |
-
}
|
231 |
-
|
232 |
-
/**
|
233 |
-
* Check whether we are on the settings page.
|
234 |
-
*
|
235 |
-
* @since 5.1.6
|
236 |
-
*
|
237 |
-
* @return bool Whether we are on the settings page.
|
238 |
-
*/
|
239 |
-
private function isSettingsPage() {
|
240 |
-
$page = tribe_get_request_var( 'page' );
|
241 |
-
$tab = tribe_get_request_var( 'tab' );
|
242 |
-
|
243 |
-
return 'tribe-common' === $page && 'event-tickets' === $tab;
|
244 |
-
}
|
245 |
-
|
246 |
-
/**
|
247 |
-
* Returns whether or not the current request is for refreshing the account status
|
248 |
-
*
|
249 |
-
* @since 5.1.6
|
250 |
-
*
|
251 |
-
* @return bool
|
252 |
-
*/
|
253 |
-
private function isStatusRefresh() {
|
254 |
-
return isset( $_GET['paypalStatusCheck'] ) && $this->isSettingsPage();
|
255 |
-
}
|
256 |
-
|
257 |
-
/**
|
258 |
-
* Return whether or not PayPal user redirect to setting page after successful onboarding.
|
259 |
-
*
|
260 |
-
* @since 5.1.6
|
261 |
-
*
|
262 |
-
* @return bool
|
263 |
-
*/
|
264 |
-
private function isPayPalUserRedirected() {
|
265 |
-
return isset( $_GET['merchantIdInPayPal'] ) && $this->isSettingsPage();
|
266 |
-
}
|
267 |
-
|
268 |
-
/**
|
269 |
-
* Return whether or not PayPal account details were saved.
|
270 |
-
*
|
271 |
-
* @since 5.1.6
|
272 |
-
*
|
273 |
-
* @return bool
|
274 |
-
*/
|
275 |
-
private function werePayPalAccountDetailsSaved() {
|
276 |
-
return isset( $_GET['paypal-commerce-account-connected'] ) && $this->isSettingsPage();
|
277 |
-
}
|
278 |
-
|
279 |
-
/**
|
280 |
-
* validate rest api credential.
|
281 |
-
*
|
282 |
-
* @since 5.1.6
|
283 |
-
*
|
284 |
-
* @param array $array
|
285 |
-
*
|
286 |
-
*/
|
287 |
-
private function didWeGetValidSellerRestApiCredentials( $array ) {
|
288 |
-
$required = [ 'client_id', 'client_secret' ];
|
289 |
-
$array = array_filter( $array ); // Remove empty values.
|
290 |
-
|
291 |
-
$errors = [];
|
292 |
-
|
293 |
-
if ( array_diff( $required, array_keys( $array ) ) ) {
|
294 |
-
$errors[] = [
|
295 |
-
'type' => 'json',
|
296 |
-
'message' => esc_html__( 'PayPal client access token API request response is:', 'event-tickets' ),
|
297 |
-
'value' => wp_json_encode( $this->settings->get_access_token() ),
|
298 |
-
];
|
299 |
-
|
300 |
-
$errors[] = [
|
301 |
-
'type' => 'json',
|
302 |
-
'message' => esc_html__( 'PayPal client rest api credentials API request response is:', 'event-tickets' ),
|
303 |
-
'value' => wp_json_encode( $array ),
|
304 |
-
];
|
305 |
-
|
306 |
-
$errors[] = esc_html__( 'There was a problem with PayPal client rest API request and we could not find valid client id and secret.', 'event-tickets' );
|
307 |
-
|
308 |
-
// Log error messages.
|
309 |
-
array_map( static function( $errorMessage ) {
|
310 |
-
$errorMessage = is_array( $errorMessage ) ? $errorMessage['message'] . ' ' . $errorMessage['value'] : $errorMessage;
|
311 |
-
tribe( 'logger' )->log_error( $errorMessage, 'tickets-commerce-paypal-commerce' );
|
312 |
-
}, $errors );
|
313 |
-
|
314 |
-
$this->merchantRepository->saveAccountErrors( $errors );
|
315 |
-
$this->redirectWhenOnBoardingFail();
|
316 |
-
}
|
317 |
-
}
|
318 |
-
|
319 |
-
/**
|
320 |
-
* Handles the request for refreshing the account status
|
321 |
-
*
|
322 |
-
* @since 5.1.6
|
323 |
-
*/
|
324 |
-
private function refreshAccountStatus() {
|
325 |
-
$merchantDetails = $this->merchantRepository->getDetails();
|
326 |
-
|
327 |
-
$statusErrors = $this->isAdminSuccessfullyOnBoarded( $merchantDetails->merchantIdInPayPal, $merchantDetails->accessToken, $merchantDetails->supportsCustomPayments );
|
328 |
-
if ( $statusErrors !== true ) {
|
329 |
-
$merchantDetails->accountIsReady = false;
|
330 |
-
$this->merchantRepository->saveAccountErrors( $statusErrors );
|
331 |
-
} else {
|
332 |
-
$merchantDetails->accountIsReady = true;
|
333 |
-
$this->merchantRepository->deleteAccountErrors();
|
334 |
-
}
|
335 |
-
|
336 |
-
$this->merchantRepository->save( $merchantDetails );
|
337 |
-
|
338 |
-
$details = $this->savePayPalMerchantDetails( $merchantDetails->merchantId, $merchantDetails->merchantIdInPayPal );
|
339 |
-
|
340 |
-
$this->setUpWebhook( $details );
|
341 |
-
}
|
342 |
-
|
343 |
-
/**
|
344 |
-
* Validate seller on Boarding status
|
345 |
-
*
|
346 |
-
* @since 5.1.6
|
347 |
-
*
|
348 |
-
* @param string $merchantId
|
349 |
-
* @param string $accessToken
|
350 |
-
* @param bool $usesCustomPayments
|
351 |
-
*
|
352 |
-
* @return true|string[]
|
353 |
-
*/
|
354 |
-
private function isAdminSuccessfullyOnBoarded( $merchantId, $accessToken, $usesCustomPayments ) {
|
355 |
-
$onBoardedData = (array) $this->payPalAuth->getSellerOnBoardingDetailsFromPayPal( $merchantId, $accessToken );
|
356 |
-
$onBoardedData = array_filter( $onBoardedData ); // Remove empty values.
|
357 |
-
$errorMessages[] = [
|
358 |
-
'type' => 'json',
|
359 |
-
'message' => esc_html__( 'PayPal merchant status check API request response is:', 'event-tickets' ),
|
360 |
-
'value' => wp_json_encode( $onBoardedData ),
|
361 |
-
];
|
362 |
-
|
363 |
-
if ( ! is_ssl() ) {
|
364 |
-
$errorMessages[] = esc_html__( 'A valid SSL certificate is required to accept payments and set up your PayPal account. Once a
|
365 |
-
certificate is installed and the site is using https, please disconnect and reconnect your account.', 'event-tickets' );
|
366 |
-
}
|
367 |
-
|
368 |
-
if ( array_diff( [ 'payments_receivable', 'primary_email_confirmed' ], array_keys( $onBoardedData ) ) ) {
|
369 |
-
$errorMessages[] = esc_html__( 'There was a problem with the status check for your account. Please try disconnecting and connecting again. If the problem persists, please contact support.', 'event-tickets' );
|
370 |
-
|
371 |
-
// Log error messages.
|
372 |
-
array_map( static function( $errorMessage ) {
|
373 |
-
$errorMessage = is_array( $errorMessage ) ? $errorMessage['message'] . ' ' . $errorMessage['value'] : $errorMessage;
|
374 |
-
tribe( 'logger' )->log_error( $errorMessage, 'tickets-commerce-paypal-commerce' );
|
375 |
-
}, $errorMessages );
|
376 |
-
|
377 |
-
// Return here since the rest of the validations will definitely fail
|
378 |
-
return $errorMessages;
|
379 |
-
}
|
380 |
-
|
381 |
-
if ( ! $onBoardedData['payments_receivable'] ) {
|
382 |
-
$errorMessages[] = esc_html__( 'Set up an account to receive payment from PayPal', 'event-tickets' );
|
383 |
-
}
|
384 |
-
|
385 |
-
if ( ! $onBoardedData['primary_email_confirmed'] ) {
|
386 |
-
$errorMessage[] = esc_html__( 'Confirm your primary email address', 'event-tickets' );
|
387 |
-
}
|
388 |
-
|
389 |
-
if ( ! $usesCustomPayments ) {
|
390 |
-
return count( $errorMessages ) > 1 ? $errorMessages : true;
|
391 |
-
}
|
392 |
-
|
393 |
-
if ( array_diff( [ 'products', 'capabilities' ], array_keys( $onBoardedData ) ) ) {
|
394 |
-
$errorMessages[] = esc_html__( 'Your account was expected to be able to accept custom payments, but is not. Please make sure your
|
395 |
-
account country matches the country setting. If the problem persists, please contact PayPal.', 'event-tickets' );
|
396 |
-
|
397 |
-
// Return here since the rest of the validations will definitely fail
|
398 |
-
return $errorMessages;
|
399 |
-
}
|
400 |
-
|
401 |
-
// Grab the PPCP_CUSTOM product from the status data
|
402 |
-
$customProduct = current(
|
403 |
-
array_filter(
|
404 |
-
$onBoardedData['products'],
|
405 |
-
static function ( $product ) {
|
406 |
-
return 'PPCP_CUSTOM' === $product['name'];
|
407 |
-
}
|
408 |
-
)
|
409 |
-
);
|
410 |
-
|
411 |
-
if ( empty( $customProduct ) || $customProduct['vetting_status'] !== 'SUBSCRIBED' ) {
|
412 |
-
$errorMessages[] = esc_html__( 'Reach out to PayPal to enable PPCP_CUSTOM for your account', 'event-tickets' );
|
413 |
-
}
|
414 |
-
|
415 |
-
// Loop through the capabilities and see if any are not active
|
416 |
-
$invalidCapabilities = [];
|
417 |
-
foreach ( $onBoardedData['capabilities'] as $capability ) {
|
418 |
-
if ( $capability['status'] !== 'ACTIVE' ) {
|
419 |
-
$invalidCapabilities[] = $capability['name'];
|
420 |
-
}
|
421 |
-
}
|
422 |
-
|
423 |
-
if ( ! empty( $invalidCapabilities ) ) {
|
424 |
-
$errorMessages[] = esc_html__( 'Reach out to PayPal to resolve the following capabilities:', 'event-tickets' ) . ' ' . implode( ', ', $invalidCapabilities );
|
425 |
-
}
|
426 |
-
|
427 |
-
// If there were errors then redirect the user with notices
|
428 |
-
return count( $errorMessages ) > 1 ? $errorMessages : true;
|
429 |
-
}
|
430 |
-
|
431 |
-
/**
|
432 |
-
* Redirect admin to setting section with error.
|
433 |
-
*
|
434 |
-
* @since 5.1.6
|
435 |
-
*/
|
436 |
-
private function redirectWhenOnBoardingFail() {
|
437 |
-
/** @var Tribe__Settings $settings */
|
438 |
-
$settings = tribe( 'settings' );
|
439 |
-
|
440 |
-
// Get link to Tickets Tab.
|
441 |
-
$settings_url = $settings->get_url( [
|
442 |
-
'page' => 'tribe-common',
|
443 |
-
'tab' => 'event-tickets',
|
444 |
-
'paypal-error' => '1',
|
445 |
-
] ) . '#tribe-field-tickets-commerce-paypal-commerce';
|
446 |
-
|
447 |
-
wp_redirect( $settings_url );
|
448 |
-
die();
|
449 |
-
}
|
450 |
-
|
451 |
-
/**
|
452 |
-
* Displays a notice of the site is not using SSL
|
453 |
-
*
|
454 |
-
* @since 5.1.6
|
455 |
-
*/
|
456 |
-
private function registerPayPalSSLNotice() {
|
457 |
-
if ( ! is_ssl() || ! empty( $this->webhooksRepository->getWebhookConfig() ) ) {
|
458 |
-
return;
|
459 |
-
}
|
460 |
-
|
461 |
-
/** @var Tribe__Settings $settings */
|
462 |
-
$settings = tribe( 'settings' );
|
463 |
-
|
464 |
-
// Get link to Help page.
|
465 |
-
$log_url = $settings->get_url( [
|
466 |
-
'page' => 'tribe-help',
|
467 |
-
] ) . '#tribe-event-log';
|
468 |
-
|
469 |
-
$logLink = sprintf(
|
470 |
-
'<a href="%1$s">%2$s</a>',
|
471 |
-
$log_url,
|
472 |
-
esc_html__( 'logged data', 'event-tickets' )
|
473 |
-
);
|
474 |
-
|
475 |
-
tribe_error(
|
476 |
-
'paypal-webhook-error',
|
477 |
-
sprintf(
|
478 |
-
// Translators: %1$s: The logged data link.
|
479 |
-
esc_html__( 'There was a problem setting up the webhooks for your PayPal account. Please try disconnecting and reconnecting your PayPal account. If the problem persists, please contact support and provide them with the latest %1$s', 'event-tickets' ),
|
480 |
-
$logLink
|
481 |
-
),
|
482 |
-
[
|
483 |
-
'type' => 'error',
|
484 |
-
]
|
485 |
-
);
|
486 |
-
}
|
487 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/Tickets/Commerce/Hooks.php
CHANGED
@@ -18,6 +18,7 @@
|
|
18 |
namespace TEC\Tickets\Commerce;
|
19 |
|
20 |
use \tad_DI52_ServiceProvider;
|
|
|
21 |
use Tribe\Tickets\Shortcodes\Tribe_Tickets_Checkout;
|
22 |
|
23 |
/**
|
@@ -45,7 +46,31 @@ class Hooks extends tad_DI52_ServiceProvider {
|
|
45 |
* @since 5.1.6
|
46 |
*/
|
47 |
protected function add_actions() {
|
|
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
/**
|
@@ -55,9 +80,261 @@ class Hooks extends tad_DI52_ServiceProvider {
|
|
55 |
*/
|
56 |
protected function add_filters() {
|
57 |
add_filter( 'tribe_shortcodes', [ $this, 'filter_register_shortcodes' ] );
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
}
|
60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
/**
|
63 |
* Register shortcodes.
|
@@ -71,20 +348,50 @@ class Hooks extends tad_DI52_ServiceProvider {
|
|
71 |
* @return array
|
72 |
*/
|
73 |
public function filter_register_shortcodes( array $shortcodes ) {
|
74 |
-
$shortcodes[
|
|
|
75 |
|
76 |
return $shortcodes;
|
77 |
}
|
78 |
|
79 |
-
|
80 |
/**
|
81 |
-
*
|
|
|
82 |
*
|
83 |
-
* @
|
84 |
*
|
85 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
86 |
*/
|
87 |
-
public function
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
90 |
}
|
18 |
namespace TEC\Tickets\Commerce;
|
19 |
|
20 |
use \tad_DI52_ServiceProvider;
|
21 |
+
use TEC\Tickets\Commerce\Status\Completed;
|
22 |
use Tribe\Tickets\Shortcodes\Tribe_Tickets_Checkout;
|
23 |
|
24 |
/**
|
46 |
* @since 5.1.6
|
47 |
*/
|
48 |
protected function add_actions() {
|
49 |
+
add_action( 'tribe_settings_do_tabs', [ $this, 'register_payments_tab' ], 15 );
|
50 |
|
51 |
+
add_action( 'init', [ $this, 'register_post_types' ] );
|
52 |
+
add_action( 'init', [ $this, 'register_order_statuses' ], 11 );
|
53 |
+
add_action( 'tribe_common_loaded', [ $this, 'load_commerce_module' ] );
|
54 |
+
|
55 |
+
add_action( 'template_redirect', [ $this, 'do_cart_parse_request' ] );
|
56 |
+
add_action( 'template_redirect', [ $this, 'do_checkout_parse_request' ] );
|
57 |
+
|
58 |
+
add_action( 'event_tickets_attendee_update', [ $this, 'update_attendee_data' ], 10, 3 );
|
59 |
+
add_action( 'event_tickets_after_attendees_update', [ $this, 'maybe_send_tickets_after_status_change' ] );
|
60 |
+
|
61 |
+
add_action( 'wp_loaded', [ $this, 'maybe_delete_expired_products' ], 0 );
|
62 |
+
add_action( 'wp_loaded', [ $this, 'maybe_redirect_to_attendees_registration_screen' ], 1 );
|
63 |
+
|
64 |
+
add_action( 'tribe_events_tickets_metabox_edit_advanced', [ $this, 'include_metabox_advanced_options' ], 10, 2 );
|
65 |
+
|
66 |
+
add_action( 'tribe_events_tickets_attendees_event_details_top', [ $this, 'setup_attendance_totals' ] );
|
67 |
+
add_action( 'trashed_post', [ $this, 'maybe_redirect_to_attendees_report' ] );
|
68 |
+
add_action( 'tickets_tpp_ticket_deleted', [ $this, 'update_stock_after_deletion' ], 10, 3 );
|
69 |
+
|
70 |
+
add_action( 'transition_post_status', [ $this, 'transition_order_post_status_hooks' ], 10, 3 );
|
71 |
+
|
72 |
+
// This needs to run earlier than our page setup.
|
73 |
+
add_action( 'admin_init', [ $this, 'maybe_trigger_process_action' ], 5 );
|
74 |
}
|
75 |
|
76 |
/**
|
80 |
*/
|
81 |
protected function add_filters() {
|
82 |
add_filter( 'tribe_shortcodes', [ $this, 'filter_register_shortcodes' ] );
|
83 |
+
|
84 |
+
add_filter( 'tribe_attendee_registration_form_classes', [ $this, 'filter_registration_form_class' ] );
|
85 |
+
add_filter( 'tribe_attendee_registration_cart_provider', [ $this, 'filter_registration_cart_provider' ], 10, 2 );
|
86 |
+
|
87 |
+
add_filter( 'tribe_tickets_get_default_module', [ $this, 'filter_de_prioritize_module' ], 5, 2 );
|
88 |
+
|
89 |
+
add_filter( 'tribe_tickets_checkout_urls', [ $this, 'filter_js_include_checkout_url' ] );
|
90 |
+
add_filter( 'tribe_tickets_cart_urls', [ $this, 'filter_js_include_cart_url' ] );
|
91 |
+
|
92 |
+
add_filter( 'event_tickets_attendees_tc_checkin_stati', [ $this, 'filter_checkin_statuses' ] );
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Initializes the Module Class.
|
97 |
+
*
|
98 |
+
* @since 5.1.9
|
99 |
+
*/
|
100 |
+
public function load_commerce_module() {
|
101 |
+
$this->container->make( Module::class );
|
102 |
+
}
|
103 |
+
|
104 |
+
public function register_payments_tab() {
|
105 |
+
$this->container->make( Settings::class )->register_tab();
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Register all Commerce Post Types in WordPress.
|
110 |
+
*
|
111 |
+
* @since 5.1.9
|
112 |
+
*/
|
113 |
+
public function register_post_types() {
|
114 |
+
$this->container->make( Attendee::class )->register_post_type();
|
115 |
+
$this->container->make( Order::class )->register_post_type();
|
116 |
+
$this->container->make( Ticket::class )->register_post_type();
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Register all Order Statuses with WP.
|
121 |
+
*
|
122 |
+
* @since 5.1.9
|
123 |
+
*/
|
124 |
+
public function register_order_statuses() {
|
125 |
+
$this->container->make( Status\Status_Handler::class )->register_order_statuses();
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Depending on which page, tab and if an action is present we trigger the processing.
|
130 |
+
*
|
131 |
+
* @since 5.1.9
|
132 |
+
*/
|
133 |
+
public function maybe_trigger_process_action() {
|
134 |
+
$page = tribe_get_request_var( 'page' );
|
135 |
+
if ( \Tribe__Settings::instance()->adminSlug !== $page ) {
|
136 |
+
return;
|
137 |
+
}
|
138 |
+
|
139 |
+
$tab = tribe_get_request_var( 'tab' );
|
140 |
+
if ( 'payments' !== $tab ) {
|
141 |
+
return;
|
142 |
+
}
|
143 |
+
|
144 |
+
$action = (string) tribe_get_request_var( 'tc-action' );
|
145 |
+
if ( empty( $action ) ) {
|
146 |
+
return;
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Process Tickets Commerce actions when in the Payments Tab.
|
151 |
+
*
|
152 |
+
* @since 5.1.9
|
153 |
+
*
|
154 |
+
* @param string $action Which action we are processing.
|
155 |
+
*/
|
156 |
+
do_action( 'tec_tickets_commerce_admin_process_action', $action );
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Process Tickets Commerce actions when in the Payments Tab.
|
160 |
+
*
|
161 |
+
* @since 5.1.9
|
162 |
+
*/
|
163 |
+
do_action( "tec_tickets_commerce_admin_process_action:{$action}" );
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Fires when a post is transitioned from one status to another so that we can make another hook that is namespaced.
|
168 |
+
*
|
169 |
+
* @since 5.1.9
|
170 |
+
*
|
171 |
+
* @param string $new_status New post status.
|
172 |
+
* @param string $old_status Old post status.
|
173 |
+
* @param \WP_Post $post Post object.
|
174 |
+
*/
|
175 |
+
public function transition_order_post_status_hooks( $new_status, $old_status, $post ) {
|
176 |
+
$this->container->make( Status\Status_Handler::class )->transition_order_post_status_hooks( $new_status, $old_status, $post );
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Filters the array of statuses that will mark an ticket attendee as eligible for check-in.
|
181 |
+
*
|
182 |
+
* @todo TribeCommerceLegacy: Move this into a Check In Handler class.
|
183 |
+
*
|
184 |
+
* @since 5.1.9
|
185 |
+
*
|
186 |
+
* @param array $statuses An array of statuses that should mark an ticket attendee as
|
187 |
+
* available for check-in.
|
188 |
+
*
|
189 |
+
* @return array The original array plus the 'yes' status.
|
190 |
+
*/
|
191 |
+
public function filter_checkin_statuses( array $statuses = [] ) {
|
192 |
+
$statuses[] = tribe( Completed::class )->get_wp_slug();
|
193 |
+
|
194 |
+
return array_unique( $statuses );
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Parse the cart request, and possibly redirect, so it happens on `template_redirect`.
|
199 |
+
*
|
200 |
+
* @since 5.1.9
|
201 |
+
*/
|
202 |
+
public function do_cart_parse_request() {
|
203 |
+
$this->container->make( Cart::class )->parse_request();
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Parse the checkout request.
|
208 |
+
*
|
209 |
+
* @since 5.1.9
|
210 |
+
*/
|
211 |
+
public function do_checkout_parse_request() {
|
212 |
+
$this->container->make( Checkout::class )->parse_request();
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Backwards compatibility to update stock after deletion of Ticket.
|
217 |
+
*
|
218 |
+
* @todo Determine if this is still required.
|
219 |
+
*
|
220 |
+
* @since 5.1.9
|
221 |
+
*
|
222 |
+
* @param int $ticket_id the attendee id being deleted
|
223 |
+
* @param int $post_id the post or event id for the attendee
|
224 |
+
* @param int $product_id the ticket-product id in Tribe Commerce
|
225 |
+
*/
|
226 |
+
public function update_stock_after_deletion( $ticket_id, $post_id, $product_id ) {
|
227 |
+
$this->container->make( Ticket::class )->update_stock_after_deletion( $ticket_id, $post_id, $product_id );
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Sets up the Attendance Totals Class report with the Attendee Screen
|
232 |
+
*
|
233 |
+
* @since 5.1.9
|
234 |
+
*/
|
235 |
+
public function setup_attendance_totals() {
|
236 |
+
$this->container->make( Reports\Attendance_Totals::class )->integrate_with_attendee_screen();
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Redirect the user after deleting trashing an Attendee to the Reports page.
|
241 |
+
*
|
242 |
+
* @since 5.1.94
|
243 |
+
*
|
244 |
+
* @param int $post_id WP_Post ID
|
245 |
+
*/
|
246 |
+
public function maybe_redirect_to_attendees_report( $post_id ) {
|
247 |
+
$this->container->make( Attendee::class )->maybe_redirect_to_attendees_report( $post_id );
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Includes the metabox advanced options for Tickets Commerce.
|
252 |
+
*
|
253 |
+
* @since 5.1.9
|
254 |
+
*
|
255 |
+
* @param int $post_id Which post we are attaching the metabox to.
|
256 |
+
* @param null|int $ticket_id Ticket we are rendering the metabox for.
|
257 |
+
*/
|
258 |
+
public function include_metabox_advanced_options( $post_id, $ticket_id = null ) {
|
259 |
+
$this->container->make( Editor\Metabox::class )->include_metabox_advanced_options( $post_id, $ticket_id );
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Updates the Attendee metadata after insertion.
|
264 |
+
*
|
265 |
+
* @since 5.1.9
|
266 |
+
*
|
267 |
+
* @param array $attendee_data Information that we are trying to save.
|
268 |
+
* @param int $attendee_id The attendee ID.
|
269 |
+
* @param int $post_id The event/post ID.
|
270 |
+
*
|
271 |
+
*/
|
272 |
+
public function update_attendee_data( $attendee_data, $attendee_id, $post_id ) {
|
273 |
+
$this->container->make( Attendee::class )->update_attendee_data( $attendee_data, $attendee_id, $post_id );
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Fully here for compatibility initially to reduce complexity on the Module.
|
278 |
+
*
|
279 |
+
* @since 5.1.9
|
280 |
+
*
|
281 |
+
* @param int $event_id Which ID we are triggering changes to.
|
282 |
+
*
|
283 |
+
*/
|
284 |
+
public function maybe_send_tickets_after_status_change( $event_id ) {
|
285 |
+
$this->container->make( Attendee::class )->maybe_send_tickets_after_status_change( $event_id );
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Redirect to the Attendees registration page when trying to add tickets.
|
290 |
+
*
|
291 |
+
* @todo Needs to move to the Checkout page and out of the module.
|
292 |
+
*
|
293 |
+
* @since 5.1.9
|
294 |
+
*/
|
295 |
+
public function maybe_redirect_to_attendees_registration_screen() {
|
296 |
+
$this->container->make( Module::class )->maybe_redirect_to_attendees_registration_screen();
|
297 |
}
|
298 |
|
299 |
+
/**
|
300 |
+
* Delete expired cart items.
|
301 |
+
*
|
302 |
+
* @todo Needs to move to the Cart page and out of the module.
|
303 |
+
*
|
304 |
+
* @since 5.1.9
|
305 |
+
*/
|
306 |
+
public function maybe_delete_expired_products() {
|
307 |
+
$this->container->make( Cart::class )->maybe_delete_expired_products();
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Add the HTML Classes to the registration form for this module.
|
312 |
+
*
|
313 |
+
* @todo Determine what this is used for.
|
314 |
+
*
|
315 |
+
* @since 5.1.9
|
316 |
+
*
|
317 |
+
* @param $classes
|
318 |
+
*
|
319 |
+
* @return array
|
320 |
+
*/
|
321 |
+
public function filter_registration_form_class( $classes ) {
|
322 |
+
return $this->container->make( Attendee::class )->registration_form_class( $classes );
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Included here for Event Tickets Plus compatibility.
|
327 |
+
*
|
328 |
+
* @since 5.1.9
|
329 |
+
*
|
330 |
+
* @param object $provider_obj
|
331 |
+
* @param string $provider
|
332 |
+
*
|
333 |
+
* @return object
|
334 |
+
*/
|
335 |
+
public function filter_registration_cart_provider( $provider_obj, $provider ) {
|
336 |
+
return $this->container->make( Attendee::class )->registration_cart_provider( $provider_obj, $provider );
|
337 |
+
}
|
338 |
|
339 |
/**
|
340 |
* Register shortcodes.
|
348 |
* @return array
|
349 |
*/
|
350 |
public function filter_register_shortcodes( array $shortcodes ) {
|
351 |
+
$shortcodes[ Shortcodes\Checkout_Shortcode::get_wp_slug() ] = Shortcodes\Checkout_Shortcode::class;
|
352 |
+
$shortcodes[ Shortcodes\Success_Shortcode::get_wp_slug() ] = Shortcodes\Success_Shortcode::class;
|
353 |
|
354 |
return $shortcodes;
|
355 |
}
|
356 |
|
|
|
357 |
/**
|
358 |
+
* If other modules are active, we should de prioritize this one (we want other commerce
|
359 |
+
* modules to take priority over this one).
|
360 |
*
|
361 |
+
* @todo Determine if this is still needed.
|
362 |
*
|
363 |
+
* @since 5.1.9
|
364 |
+
*
|
365 |
+
* @param string $default_module
|
366 |
+
* @param string[] $available_modules
|
367 |
+
*
|
368 |
+
* @return string
|
369 |
*/
|
370 |
+
public function filter_de_prioritize_module( $default_module, array $available_modules ) {
|
371 |
+
$tribe_commerce_module = get_class( $this );
|
372 |
+
|
373 |
+
// If this isn't the default (or if there isn't a choice), no need to de prioritize.
|
374 |
+
if (
|
375 |
+
$default_module !== $tribe_commerce_module
|
376 |
+
|| count( $available_modules ) < 2
|
377 |
+
|| reset( $available_modules ) !== $tribe_commerce_module
|
378 |
+
) {
|
379 |
+
return $default_module;
|
380 |
+
}
|
381 |
+
|
382 |
+
return next( $available_modules );
|
383 |
+
}
|
384 |
+
|
385 |
+
public function filter_js_include_cart_url( $urls ) {
|
386 |
+
$urls[ Module::class ] = tribe( Cart::class )->get_url();
|
387 |
+
|
388 |
+
return $urls;
|
389 |
+
}
|
390 |
+
|
391 |
+
public function filter_js_include_checkout_url( $urls ) {
|
392 |
+
// Note the checkout needs to pass by the cart URL first for AR modal.
|
393 |
+
$urls[ Module::class ] = tribe( Cart::class )->get_url();
|
394 |
+
|
395 |
+
return $urls;
|
396 |
}
|
397 |
}
|
src/Tickets/Commerce/Models/Attendee_Model.php
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Models an Tickets Commerce Attendee.
|
4 |
+
*
|
5 |
+
* @since 5.1.9
|
6 |
+
*
|
7 |
+
* @package TEC\Tickets\Commerce\Models
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace TEC\Tickets\Commerce\Models;
|
11 |
+
|
12 |
+
use DateInterval;
|
13 |
+
use DatePeriod;
|
14 |
+
use DateTimeZone;
|
15 |
+
use TEC\Tickets\Commerce\Module;
|
16 |
+
use Tribe\Models\Post_Types\Base;
|
17 |
+
use TEC\Tickets\Commerce\Attendee;
|
18 |
+
use Tribe\Utils\Lazy_Collection;
|
19 |
+
use Tribe\Utils\Lazy_String;
|
20 |
+
use Tribe\Utils\Post_Thumbnail;
|
21 |
+
use Tribe__Date_Utils as Dates;
|
22 |
+
use Tribe__Utils__Array as Arr;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Class Attendee.
|
26 |
+
*
|
27 |
+
* @since 5.1.9
|
28 |
+
*
|
29 |
+
* @package TEC\Tickets\Commerce\Models
|
30 |
+
*/
|
31 |
+
class Attendee_Model extends Base {
|
32 |
+
/**
|
33 |
+
* {@inheritDoc}
|
34 |
+
*/
|
35 |
+
protected function build_properties( $filter ) {
|
36 |
+
try {
|
37 |
+
$cache_this = $this->get_caching_callback( $filter );
|
38 |
+
|
39 |
+
$post_id = $this->post->ID;
|
40 |
+
|
41 |
+
$post_meta = get_post_meta( $post_id );
|
42 |
+
|
43 |
+
$ticket_id = Arr::get( $post_meta, [ Attendee::$ticket_relation_meta_key, 0 ] );
|
44 |
+
$order_id = Arr::get( $post_meta, [ Attendee::$order_relation_meta_key, 0 ] );
|
45 |
+
$event_id = Arr::get( $post_meta, [ Attendee::$event_relation_meta_key, 0 ] );
|
46 |
+
$user_id = Arr::get( $post_meta, [ Attendee::$user_relation_meta_key, 0 ] );
|
47 |
+
|
48 |
+
$ticket = tec_tc_get_ticket( $ticket_id );
|
49 |
+
$order = tec_tc_get_order( $order_id );
|
50 |
+
|
51 |
+
$is_product_deleted = empty( $ticket ) && ! $ticket instanceof \WP_Post;
|
52 |
+
|
53 |
+
$checked_in = Arr::get( $post_meta, [ Attendee::$checked_in_meta_key, 0 ] );
|
54 |
+
$security = Arr::get( $post_meta, [ Attendee::$security_code_meta_key, 0 ] );
|
55 |
+
$opt_out = tribe_is_truthy( Arr::get( $post_meta, [ Attendee::$optout_meta_key, 0 ] ) );
|
56 |
+
$status = Arr::get( $post_meta, [ Attendee::$status_meta_key, 0 ] );
|
57 |
+
$ticket_sent = (int) Arr::get( $post_meta, [ Attendee::$ticket_sent_meta_key, 0 ] );
|
58 |
+
$deleted_ticket_title = Arr::get( $post_meta, [ Attendee::$deleted_ticket_meta_key, 0 ] );
|
59 |
+
$first_name = Arr::get( $post_meta, [ Attendee::$first_name_meta_key, 0 ] );
|
60 |
+
$last_name = Arr::get( $post_meta, [ Attendee::$last_name_meta_key, 0 ] );
|
61 |
+
$full_name = $first_name . ' ' . $last_name;
|
62 |
+
$email = Arr::get( $post_meta, [ Attendee::$email_meta_key, 0 ] );
|
63 |
+
$is_subscribed = tribe_is_truthy( Arr::get( $post_meta, [ Attendee::$subscribed_meta_key, 0 ] ) );
|
64 |
+
|
65 |
+
// Tries to determine an Attendee Unique ID.
|
66 |
+
$ticket_unique_id = Arr::get( $post_meta, [ '_unique_id', 0 ] );
|
67 |
+
$ticket_unique_id = empty( $ticket_unique_id ) ? $post_id : $ticket_unique_id;
|
68 |
+
|
69 |
+
$ticket_title = ( $is_product_deleted ? $ticket->post_title : $deleted_ticket_title . ' ' . __( '(deleted)', 'event-tickets' ) );
|
70 |
+
|
71 |
+
$is_purchaser = $email === $order->purchaser_email;
|
72 |
+
|
73 |
+
$properties = [
|
74 |
+
'optout' => $opt_out,
|
75 |
+
'ticket' => $ticket_title,
|
76 |
+
'attendee_id' => $post_id,
|
77 |
+
'security' => $security,
|
78 |
+
'product_id' => $ticket_id,
|
79 |
+
'check_in' => $checked_in,
|
80 |
+
'order_status' => $status,
|
81 |
+
'user_id' => $user_id,
|
82 |
+
'ticket_sent' => $ticket_sent,
|
83 |
+
|
84 |
+
// Fields for Email Tickets.
|
85 |
+
'event_id' => $event_id,
|
86 |
+
'ticket_name' => $ticket_title,
|
87 |
+
'holder_name' => $full_name,
|
88 |
+
'holder_email' => $email,
|
89 |
+
'order_id' => $order_id,
|
90 |
+
'ticket_id' => $ticket_unique_id,
|
91 |
+
'qr_ticket_id' => $post_id,
|
92 |
+
'security_code' => $security,
|
93 |
+
|
94 |
+
// Attendee Meta, should be populated later by ET+
|
95 |
+
'attendee_meta' => [],
|
96 |
+
|
97 |
+
// Handle initial Attendee flags.
|
98 |
+
'is_subscribed' => $is_subscribed,
|
99 |
+
'is_purchaser' => $is_purchaser,
|
100 |
+
];
|
101 |
+
} catch ( \Exception $e ) {
|
102 |
+
return [];
|
103 |
+
}
|
104 |
+
|
105 |
+
return $properties;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* {@inheritDoc}
|
110 |
+
*/
|
111 |
+
protected function get_cache_slug() {
|
112 |
+
return 'tc_attendees';
|
113 |
+
}
|
114 |
+
}
|
src/Tickets/Commerce/Models/Order_Model.php
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Models an Tickets Commerce Orders.
|
4 |
+
*
|
5 |
+
* @since 5.1.9
|
6 |
+
*
|
7 |
+
* @package TEC\Tickets\Commerce\Models
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace TEC\Tickets\Commerce\Models;
|
11 |
+
|
12 |
+
use TEC\Tickets\Commerce;
|
13 |
+
use TEC\Tickets\Commerce\Module;
|
14 |
+
use TEC\Tickets\Commerce\Order;
|
15 |
+
use Tribe\Models\Post_Types\Base;
|
16 |
+
use Tribe\Utils\Lazy_Collection;
|
17 |
+
use Tribe\Utils\Lazy_String;
|
18 |
+
use Tribe\Utils\Post_Thumbnail;
|
19 |
+
use Tribe__Date_Utils as Dates;
|
20 |
+
use Tribe__Utils__Array as Arr;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Class Order.
|
24 |
+
*
|
25 |
+
* @since 5.1.9
|
26 |
+
*
|
27 |
+
* @package TEC\Tickets\Commerce\Models
|
28 |
+
*/
|
29 |
+
class Order_Model extends Base {
|
30 |
+
|
31 |
+
/**
|
32 |
+
* {@inheritDoc}
|
33 |
+
*/
|
34 |
+
protected function build_properties( $filter ) {
|
35 |
+
try {
|
36 |
+
$cache_this = $this->get_caching_callback( $filter );
|
37 |
+
|
38 |
+
$post_id = $this->post->ID;
|
39 |
+
|
40 |
+
$post_meta = get_post_meta( $post_id );
|
41 |
+
|
42 |
+
$cart_items = maybe_unserialize( Arr::get( $post_meta, [ Order::$cart_items_meta_key, 0 ] ) );
|
43 |
+
$total_value = Arr::get( $post_meta, [ Order::$total_value_meta_key, 0 ] );
|
44 |
+
$currency = Arr::get( $post_meta, [ Order::$currency_meta_key, 0 ], 'USD' );
|
45 |
+
$gateway_slug = Arr::get( $post_meta, [ Order::$gateway_meta_key, 0 ] );
|
46 |
+
$gateway_order_id = Arr::get( $post_meta, [ Order::$gateway_order_id_meta_key, 0 ] );
|
47 |
+
$gateway_payload = $this->get_gateway_payloads( $post_meta );
|
48 |
+
|
49 |
+
$purchaser_full_name = Arr::get( $post_meta, [ Order::$purchaser_full_name_meta_key, 0 ] );
|
50 |
+
$purchaser_first_name = Arr::get( $post_meta, [ Order::$purchaser_first_name_meta_key, 0 ] );
|
51 |
+
$purchaser_last_name = Arr::get( $post_meta, [ Order::$purchaser_last_name_meta_key, 0 ] );
|
52 |
+
$purchaser_email = Arr::get( $post_meta, [ Order::$purchaser_email_meta_key, 0 ] );
|
53 |
+
|
54 |
+
$events_in_order = Arr::get( $post_meta, [ Order::$events_in_order_meta_key ] );
|
55 |
+
$tickets_in_order = Arr::get( $post_meta, [ Order::$tickets_in_order_meta_key ] );
|
56 |
+
|
57 |
+
$properties = [
|
58 |
+
'provider' => Module::class,
|
59 |
+
'provider_slug' => Commerce::ABBR,
|
60 |
+
'gateway' => $gateway_slug,
|
61 |
+
'gateway_order_id' => $gateway_order_id,
|
62 |
+
'gateway_payload' => $gateway_payload,
|
63 |
+
'total_value' => $total_value,
|
64 |
+
'currency' => $currency,
|
65 |
+
'purchaser' => [
|
66 |
+
'user_id' => $this->post->post_author,
|
67 |
+
'first_name' => $purchaser_first_name,
|
68 |
+
'last_name' => $purchaser_last_name,
|
69 |
+
'full_name' => $purchaser_full_name,
|
70 |
+
'email' => $purchaser_email,
|
71 |
+
],
|
72 |
+
'cart_items' => $cart_items,
|
73 |
+
'events_in_order' => $events_in_order,
|
74 |
+
'tickets_in_order' => $tickets_in_order,
|
75 |
+
];
|
76 |
+
} catch ( \Exception $e ) {
|
77 |
+
return [];
|
78 |
+
}
|
79 |
+
|
80 |
+
return $properties;
|
81 |
+
}
|
82 |
+
|
83 |
+
protected function get_gateway_payloads( $post_meta ) {
|
84 |
+
$statuses = tribe( Commerce\Status\Status_Handler::class )->get_all();
|
85 |
+
$meta = [];
|
86 |
+
|
87 |
+
foreach ( $statuses as $status ) {
|
88 |
+
$status_payloads = Arr::get( $post_meta, [ Order::get_gateway_payload_meta_key( $status ) ], [] );
|
89 |
+
|
90 |
+
$meta[ $status->get_slug() ] = $status_payloads;
|
91 |
+
}
|
92 |
+
|
93 |
+
return array_filter( $meta );
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* {@inheritDoc}
|
98 |
+
*/
|
99 |
+
protected function get_cache_slug() {
|
100 |
+
return 'tc_orders';
|
101 |
+
}
|
102 |
+
|
103 |
+
}
|
src/Tickets/Commerce/Models/Ticket_Model.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Models an Tickets Commerce Ticket.
|
4 |
+
*
|
5 |
+
* @since 5.1.9
|
6 |
+
*
|
7 |
+
* @package TEC\Tickets\Commerce\Models
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace TEC\Tickets\Commerce\Models;
|
11 |
+
|
12 |
+
use DateInterval;
|
13 |
+
use DatePeriod;
|
14 |
+
use DateTimeZone;
|
15 |
+
use Tribe\Models\Post_Types\Base;
|
16 |
+
use TEC\Tickets\Commerce\Ticket;
|
17 |
+
use Tribe\Utils\Lazy_Collection;
|
18 |
+
use Tribe\Utils\Lazy_String;
|
19 |
+
use Tribe\Utils\Post_Thumbnail;
|
20 |
+
use Tribe__Date_Utils as Dates;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Class Attendee.
|
24 |
+
*
|
25 |
+
* @since 5.1.9
|
26 |
+
*
|
27 |
+
* @package TEC\Tickets\Commerce\Models
|
28 |
+
*/
|
29 |
+
class Ticket_Model extends Base {
|
30 |
+
/**
|
31 |
+
* {@inheritDoc}
|
32 |
+
*/
|
33 |
+
protected function build_properties( $filter ) {
|
34 |
+
try {
|
35 |
+
$cache_this = $this->get_caching_callback( $filter );
|
36 |
+
|
37 |
+
$post_id = $this->post->ID;
|
38 |
+
|
39 |
+
$post_meta = get_post_meta( $post_id );
|
40 |
+
|
41 |
+
// $total_value = isset( $post_meta[ Ticket::$total_value_meta_key ][0] ) ? $post_meta[ Ticket::$total_value_meta_key ][0] : null;
|
42 |
+
|
43 |
+
$properties = [
|
44 |
+
|
45 |
+
];
|
46 |
+
} catch ( \Exception $e ) {
|
47 |
+
return [];
|
48 |
+
}
|
49 |
+
|
50 |
+
return $properties;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* {@inheritDoc}
|
55 |
+
*/
|
56 |
+
protected function get_cache_slug() {
|
57 |
+
return 'tc_tickets';
|
58 |
+
}
|
59 |
+
}
|
src/Tickets/Commerce/Module.php
ADDED
@@ -0,0 +1,615 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce;
|
6 |
+
use TEC\Tickets\Commerce\Status\Completed;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Tickets Provider class for Tickets Commerce
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Gateways\PayPal
|
14 |
+
*/
|
15 |
+
class Module extends \Tribe__Tickets__Tickets {
|
16 |
+
|
17 |
+
public function __construct() {
|
18 |
+
// This needs to happen before parent construct.
|
19 |
+
$this->plugin_name = __( 'Tickets Commerce', 'event-tickets' );
|
20 |
+
|
21 |
+
parent::__construct();
|
22 |
+
|
23 |
+
$this->attendee_object = Attendee::POSTTYPE;
|
24 |
+
|
25 |
+
$this->attendee_ticket_sent = '_tribe_tpp_attendee_ticket_sent';
|
26 |
+
|
27 |
+
$this->attendee_optout_key = Attendee::$optout_meta_key;
|
28 |
+
|
29 |
+
$this->attendee_tpp_key = Attendee::$status_meta_key;
|
30 |
+
|
31 |
+
$this->ticket_object = Ticket::POSTTYPE;
|
32 |
+
|
33 |
+
$this->event_key = Attendee::$event_relation_meta_key;
|
34 |
+
|
35 |
+
$this->checkin_key = Attendee::$checked_in_meta_key;
|
36 |
+
|
37 |
+
$this->order_key = Attendee::$order_relation_meta_key;
|
38 |
+
|
39 |
+
$this->refund_order_key = '_tribe_tpp_refund_order';
|
40 |
+
|
41 |
+
$this->security_code = Attendee::$security_code_meta_key;
|
42 |
+
|
43 |
+
$this->full_name = '_tribe_tpp_full_name';
|
44 |
+
|
45 |
+
$this->email = Attendee::$purchaser_email_meta_key;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* {@inheritdoc}
|
50 |
+
*/
|
51 |
+
public $orm_provider = \TEC\Tickets\Commerce::PROVIDER;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Name of the CPT that holds Attendees (tickets holders).
|
55 |
+
*
|
56 |
+
* @since 5.1.9
|
57 |
+
*
|
58 |
+
* @var string
|
59 |
+
*/
|
60 |
+
const ATTENDEE_OBJECT = Attendee::POSTTYPE;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Name of the CPT that holds Orders
|
64 |
+
*
|
65 |
+
* @since 5.1.9
|
66 |
+
*
|
67 |
+
* @var string
|
68 |
+
*/
|
69 |
+
const ORDER_OBJECT = Order::POSTTYPE;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Meta key that relates Attendees and Events.
|
73 |
+
*
|
74 |
+
* @since 5.1.9
|
75 |
+
*
|
76 |
+
* @var string
|
77 |
+
*/
|
78 |
+
const ATTENDEE_EVENT_KEY = '_tec_tickets_commerce_event';
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Meta key that relates Attendees and Products.
|
82 |
+
*
|
83 |
+
* @since 5.1.9
|
84 |
+
*
|
85 |
+
* @var string
|
86 |
+
*/
|
87 |
+
const ATTENDEE_PRODUCT_KEY = '_tec_tickets_commerce_product';
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Meta key that relates Attendees and Orders.
|
91 |
+
*
|
92 |
+
* @since 5.1.9
|
93 |
+
*
|
94 |
+
* @var string
|
95 |
+
*/
|
96 |
+
const ATTENDEE_ORDER_KEY = '_tec_tickets_commerce_order';
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Indicates if a ticket for this attendee was sent out via email.
|
100 |
+
*
|
101 |
+
* @since 5.1.9
|
102 |
+
*
|
103 |
+
* @var string
|
104 |
+
*/
|
105 |
+
public $attendee_ticket_sent;
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Meta key that if this attendee wants to show on the attendee list
|
109 |
+
*
|
110 |
+
* @since 5.1.9
|
111 |
+
*
|
112 |
+
* @var string
|
113 |
+
*/
|
114 |
+
public $attendee_optout_key;
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Meta key that if this attendee PayPal status
|
118 |
+
*
|
119 |
+
* @since 5.1.9
|
120 |
+
*
|
121 |
+
* @var string
|
122 |
+
*/
|
123 |
+
public $attendee_tpp_key;
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Name of the CPT that holds Tickets
|
127 |
+
*
|
128 |
+
* @since 5.1.9
|
129 |
+
*
|
130 |
+
* @var string
|
131 |
+
*/
|
132 |
+
public $ticket_object;
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Meta key that relates Products and Events
|
136 |
+
*
|
137 |
+
* @since 5.1.9
|
138 |
+
*
|
139 |
+
* @var string
|
140 |
+
*/
|
141 |
+
public $event_key;
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Meta key that stores if an attendee has checked in to an event
|
145 |
+
*
|
146 |
+
* @since 5.1.9
|
147 |
+
*
|
148 |
+
* @var string
|
149 |
+
*/
|
150 |
+
public $checkin_key;
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Meta key that ties attendees together by order
|
154 |
+
*
|
155 |
+
* @since 5.1.9
|
156 |
+
*
|
157 |
+
* @var string
|
158 |
+
*/
|
159 |
+
public $order_key;
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Meta key that ties attendees together by refunded order
|
163 |
+
*
|
164 |
+
* @since 5.1.9
|
165 |
+
*
|
166 |
+
* @var string
|
167 |
+
*/
|
168 |
+
public $refund_order_key;
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Meta key that holds the security code that's printed in the tickets
|
172 |
+
*
|
173 |
+
* @since 5.1.9
|
174 |
+
*
|
175 |
+
* @var string
|
176 |
+
*/
|
177 |
+
public $security_code;
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Meta key that holds the full name of the tickets PayPal "buyer"
|
181 |
+
*
|
182 |
+
* @since 5.1.9
|
183 |
+
*
|
184 |
+
* @var string
|
185 |
+
*/
|
186 |
+
public $full_name;
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Meta key that holds the email of the tickets PayPal "buyer"
|
190 |
+
*
|
191 |
+
* @since 5.1.9
|
192 |
+
*
|
193 |
+
* @var string
|
194 |
+
*/
|
195 |
+
public $email;
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Meta key that holds the name of a ticket to be used in reports if the Product is deleted
|
199 |
+
*
|
200 |
+
* @since 5.1.9
|
201 |
+
*
|
202 |
+
* @var string
|
203 |
+
*/
|
204 |
+
public $deleted_product = '_tribe_deleted_product_name';
|
205 |
+
|
206 |
+
/**
|
207 |
+
* A variable holder if PayPal is loaded
|
208 |
+
*
|
209 |
+
* @since 5.1.9
|
210 |
+
*
|
211 |
+
* @var boolean
|
212 |
+
*/
|
213 |
+
protected $is_loaded = false;
|
214 |
+
|
215 |
+
/**
|
216 |
+
* This method is required for the module to properly load.
|
217 |
+
*
|
218 |
+
* @since 5.1.9
|
219 |
+
|
220 |
+
* @return static
|
221 |
+
*/
|
222 |
+
public static function get_instance() {
|
223 |
+
return tribe( static::class );
|
224 |
+
}
|
225 |
+
/**
|
226 |
+
* Registers all actions/filters
|
227 |
+
*
|
228 |
+
* @since 5.1.9
|
229 |
+
*/
|
230 |
+
public function hooks() {
|
231 |
+
// if the hooks have already been bound, don't do it again
|
232 |
+
if ( $this->is_loaded ) {
|
233 |
+
return false;
|
234 |
+
}
|
235 |
+
|
236 |
+
// add_filter( 'post_updated_messages', [ $this, 'updated_messages' ] );
|
237 |
+
|
238 |
+
// add_action( 'init', tribe_callback( 'tickets.commerce.paypal.orders.report', 'hook' ) );
|
239 |
+
// add_action( 'tribe_tickets_attendees_page_inside', tribe_callback( 'tickets.commerce.paypal.orders.tabbed-view', 'render' ) );
|
240 |
+
// add_filter( 'tribe_tickets_stock_message_available_quantity', tribe_callback( 'tickets.commerce.paypal.orders.sales', 'filter_available' ), 10, 4 );
|
241 |
+
// add_action( 'admin_init', tribe_callback( 'tickets.commerce.paypal.oversell.request', 'handle' ) );```
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Send tickets email for attendees.
|
246 |
+
*
|
247 |
+
* @since 5.1.9
|
248 |
+
*
|
249 |
+
* @param array $attendees List of attendees.
|
250 |
+
* @param array $args {
|
251 |
+
* The list of arguments to use for sending ticket emails.
|
252 |
+
*
|
253 |
+
* @type string $subject The email subject.
|
254 |
+
* @type string $content The email content.
|
255 |
+
* @type string $from_name The name to send tickets from.
|
256 |
+
* @type string $from_email The email to send tickets from.
|
257 |
+
* @type array|string $headers The list of headers to send.
|
258 |
+
* @type array $attachments The list of attachments to send.
|
259 |
+
* @type string $provider The provider slug (rsvp, tpp, woo, edd).
|
260 |
+
* @type int $post_id The post/event ID to send the emails for.
|
261 |
+
* @type string|int $order_id The order ID to send the emails for.
|
262 |
+
* }
|
263 |
+
*
|
264 |
+
* @return int The number of emails sent successfully.
|
265 |
+
*/
|
266 |
+
public function send_tickets_email_for_attendees( $attendees, $args = [] ) {
|
267 |
+
$args = array_merge(
|
268 |
+
[
|
269 |
+
'subject' => tribe_get_option( Settings::$option_confirmation_email_subject, false ),
|
270 |
+
'from_name' => tribe_get_option( Settings::$option_confirmation_email_sender_name, false ),
|
271 |
+
'from_email' => tribe_get_option( Settings::$option_confirmation_email_sender_email, false ),
|
272 |
+
'provider' => Commerce::ABBR,
|
273 |
+
],
|
274 |
+
$args
|
275 |
+
);
|
276 |
+
|
277 |
+
return parent::send_tickets_email_for_attendees( $attendees, $args );
|
278 |
+
}
|
279 |
+
|
280 |
+
/**
|
281 |
+
* Shows the tickets form in the front end
|
282 |
+
*
|
283 |
+
* @since 5.1.9
|
284 |
+
*
|
285 |
+
* @param $content
|
286 |
+
*
|
287 |
+
* @return void
|
288 |
+
*/
|
289 |
+
public function front_end_tickets_form( $content ) {
|
290 |
+
|
291 |
+
$post = $GLOBALS['post'];
|
292 |
+
$tickets = $this->get_tickets( $post->ID );
|
293 |
+
|
294 |
+
foreach ( $tickets as $index => $ticket ) {
|
295 |
+
if ( __CLASS__ !== $ticket->provider_class ) {
|
296 |
+
unset( $tickets[ $index ] );
|
297 |
+
}
|
298 |
+
}
|
299 |
+
|
300 |
+
if ( empty( $tickets ) ) {
|
301 |
+
return;
|
302 |
+
}
|
303 |
+
|
304 |
+
tribe( Tickets_View::class )->get_tickets_block( $post->ID );
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Indicates if we currently require users to be logged in before they can obtain
|
309 |
+
* tickets.
|
310 |
+
*
|
311 |
+
* @since 5.1.9
|
312 |
+
*
|
313 |
+
* @return bool
|
314 |
+
*/
|
315 |
+
public function login_required() {
|
316 |
+
$requirements = (array) tribe_get_option( 'ticket-authentication-requirements', array() );
|
317 |
+
|
318 |
+
return in_array( 'event-tickets_all', $requirements, true );
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Get attendees by id and associated post type
|
323 |
+
* or default to using $post_id
|
324 |
+
*
|
325 |
+
* @since 5.1.9
|
326 |
+
*
|
327 |
+
* @param $post_id
|
328 |
+
* @param null $post_type
|
329 |
+
*
|
330 |
+
* @return array|mixed
|
331 |
+
*/
|
332 |
+
public function get_attendees_by_id( $post_id, $post_type = null ) {
|
333 |
+
if ( ! $post_type ) {
|
334 |
+
$post_type = get_post_type( $post_id );
|
335 |
+
}
|
336 |
+
|
337 |
+
switch ( $post_type ) {
|
338 |
+
case $this->attendee_object:
|
339 |
+
return $this->get_attendees_by_attendee_id( $post_id );
|
340 |
+
|
341 |
+
break;
|
342 |
+
case 'tpp_order_hash':
|
343 |
+
return $this->get_attendees_by_order_id( $post_id );
|
344 |
+
|
345 |
+
break;
|
346 |
+
case $this->ticket_object:
|
347 |
+
return $this->get_attendees_by_ticket_id( $post_id );
|
348 |
+
|
349 |
+
break;
|
350 |
+
default:
|
351 |
+
return $this->get_attendees_by_post_id( $post_id );
|
352 |
+
|
353 |
+
break;
|
354 |
+
}
|
355 |
+
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Returns the value of a key defined by the class.
|
360 |
+
*
|
361 |
+
* @since 5.1.9
|
362 |
+
*
|
363 |
+
* @param string $key
|
364 |
+
*
|
365 |
+
* @return string The key value or an empty string if not defined.
|
366 |
+
*/
|
367 |
+
public static function get_key( $key ) {
|
368 |
+
$instance = self::get_instance();
|
369 |
+
$key = strtolower( $key );
|
370 |
+
|
371 |
+
$constant_map = [
|
372 |
+
'attendee_event_key' => $instance->attendee_event_key,
|
373 |
+
'attendee_product_key' => $instance->attendee_product_key,
|
374 |
+
'attendee_order_key' => $instance->order_key,
|
375 |
+
'attendee_optout_key' => $instance->attendee_optout_key,
|
376 |
+
'attendee_tpp_key' => $instance->attendee_tpp_key,
|
377 |
+
'event_key' => $instance->get_event_key(),
|
378 |
+
'checkin_key' => $instance->checkin_key,
|
379 |
+
'order_key' => $instance->order_key,
|
380 |
+
];
|
381 |
+
|
382 |
+
return \Tribe__Utils__Array::get( $constant_map, $key, '' );
|
383 |
+
}
|
384 |
+
|
385 |
+
/**
|
386 |
+
* Indicates if global stock support is enabled for this provider.
|
387 |
+
*
|
388 |
+
* @since 5.1.9
|
389 |
+
*
|
390 |
+
* @return bool
|
391 |
+
*/
|
392 |
+
public function supports_global_stock() {
|
393 |
+
/**
|
394 |
+
* Allows the declaration of global stock support for Tribe Commerce tickets
|
395 |
+
* to be overridden.
|
396 |
+
*
|
397 |
+
* @param bool $enable_global_stock_support
|
398 |
+
*/
|
399 |
+
return (bool) apply_filters( 'tec_tickets_commerce_enable_global_stock', true );
|
400 |
+
}
|
401 |
+
|
402 |
+
/**
|
403 |
+
* All the methods below here were created merely as a backwards compatibility piece for our old Code that
|
404 |
+
* depends so much on the concept of a Main class handling all kinds of integration pieces.
|
405 |
+
*
|
406 |
+
* ! DO NOT INTRODUCE MORE LOGIC OR COMPLEXITY ON THESE METHODS !
|
407 |
+
*
|
408 |
+
* The methods are all focused on routing functionality to their correct handlers.
|
409 |
+
*/
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Get's the product price html
|
413 |
+
*
|
414 |
+
* @since 5.1.9
|
415 |
+
*
|
416 |
+
* @param int|object $product
|
417 |
+
* @param array|boolean $attendee
|
418 |
+
*
|
419 |
+
* @return string
|
420 |
+
*/
|
421 |
+
public function get_price_html( $product, $attendee = false ) {
|
422 |
+
return tribe( Ticket::class )->get_price_html( $product, $attendee );
|
423 |
+
}
|
424 |
+
|
425 |
+
/**
|
426 |
+
* Gets the product price value
|
427 |
+
*
|
428 |
+
* @since 5.1.9
|
429 |
+
*
|
430 |
+
* @param int|\WP_Post $product
|
431 |
+
*
|
432 |
+
* @return string
|
433 |
+
*/
|
434 |
+
public function get_price_value( $product ) {
|
435 |
+
return tribe( Ticket::class )->get_price_value( $product );
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* Whether a specific attendee is valid toward inventory decrease or not.
|
440 |
+
*
|
441 |
+
* By default only attendees generated as part of a Completed order will count toward
|
442 |
+
* an inventory decrease but, if the option to reserve stock for Pending Orders is activated,
|
443 |
+
* then those attendees generated as part of a Pending Order will, for a limited time after the
|
444 |
+
* order creation, cause the inventory to be decreased.
|
445 |
+
*
|
446 |
+
* @since 5.1.9
|
447 |
+
*
|
448 |
+
* @param array $attendee
|
449 |
+
*
|
450 |
+
* @return bool
|
451 |
+
*/
|
452 |
+
public function attendee_decreases_inventory( array $attendee ) {
|
453 |
+
tribe( Attendee::class )->decreases_inventory( $attendee );
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* {@inheritdoc}
|
458 |
+
*/
|
459 |
+
public function get_attendee( $attendee, $post_id = 0 ) {
|
460 |
+
return tec_tc_get_attendee( $attendee, ARRAY_A );
|
461 |
+
}
|
462 |
+
|
463 |
+
/**
|
464 |
+
* Event Tickets Plus Admin Reports page will use this data from this method.
|
465 |
+
*
|
466 |
+
* @since 5.1.9
|
467 |
+
*
|
468 |
+
*
|
469 |
+
* @param string|int $order_id
|
470 |
+
*
|
471 |
+
* @return array
|
472 |
+
*/
|
473 |
+
public function get_order_data( $order_id ) {
|
474 |
+
return tec_tc_get_order( $order_id, ARRAY_A );
|
475 |
+
}
|
476 |
+
|
477 |
+
/**
|
478 |
+
* Renders the advanced fields in the new/edit ticket form.
|
479 |
+
* Using the method, providers can add as many fields as
|
480 |
+
* they want, specific to their implementation.
|
481 |
+
*
|
482 |
+
* @since 5.1.9
|
483 |
+
*
|
484 |
+
* @param int $post_id
|
485 |
+
* @param int $ticket_id
|
486 |
+
*/
|
487 |
+
public function do_metabox_capacity_options( $post_id, $ticket_id ) {
|
488 |
+
tribe( Editor\Metabox::class )->do_metabox_capacity_options( $post_id, $ticket_id );
|
489 |
+
}
|
490 |
+
|
491 |
+
/**
|
492 |
+
* Maps to the Cart Class method to get the cart.
|
493 |
+
*
|
494 |
+
* @since 5.1.9
|
495 |
+
*
|
496 |
+
* @return string
|
497 |
+
*/
|
498 |
+
public function get_cart_url() {
|
499 |
+
return tribe( Cart::class )->get_url();
|
500 |
+
}
|
501 |
+
|
502 |
+
/**
|
503 |
+
* Generate and store all the attendees information for a new order.
|
504 |
+
*
|
505 |
+
* @since 5.1.9
|
506 |
+
*
|
507 |
+
* @param string $payment_status The tickets payment status, defaults to completed.
|
508 |
+
* @param bool $redirect Whether the client should be redirected or not.
|
509 |
+
*/
|
510 |
+
public function generate_tickets( $payment_status = 'completed', $redirect = true ) {
|
511 |
+
tribe( Order::class )->generate_order( $payment_status, $redirect );
|
512 |
+
}
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Gets an individual ticket.
|
516 |
+
*
|
517 |
+
* @since 5.1.9
|
518 |
+
*
|
519 |
+
* @param int|\WP_Post $post_id
|
520 |
+
* @param int|\WP_Post $ticket_id
|
521 |
+
*
|
522 |
+
* @return null|\Tribe__Tickets__Ticket_Object
|
523 |
+
*/
|
524 |
+
public function get_ticket( $post_id, $ticket_id ) {
|
525 |
+
return tribe( Ticket::class )->get_ticket( $ticket_id );
|
526 |
+
}
|
527 |
+
|
528 |
+
/**
|
529 |
+
* Saves a Tickets Commerce ticket.
|
530 |
+
*
|
531 |
+
* @since 5.1.9
|
532 |
+
*
|
533 |
+
* @param int $post_id Post ID.
|
534 |
+
* @param \Tribe__Tickets__Ticket_Object $ticket Ticket object.
|
535 |
+
* @param array $raw_data Ticket data.
|
536 |
+
*
|
537 |
+
* @return int|false The updated/created ticket post ID or false if no ticket ID.
|
538 |
+
*/
|
539 |
+
public function save_ticket( $post_id, $ticket, $raw_data = [] ) {
|
540 |
+
// Run anything we might need on parent method.
|
541 |
+
parent::save_ticket( $post_id, $ticket, $raw_data );
|
542 |
+
|
543 |
+
/**
|
544 |
+
* Important, do not add anything above this method.
|
545 |
+
* Our goal is to reduce the amount of load on the `Module`, relegate these behaviors to the correct models.
|
546 |
+
*/
|
547 |
+
return tribe( Ticket::class )->save( $post_id, $ticket, $raw_data );
|
548 |
+
}
|
549 |
+
|
550 |
+
/**
|
551 |
+
* Deletes a ticket.
|
552 |
+
*
|
553 |
+
* @since 5.1.9
|
554 |
+
*
|
555 |
+
* @param $event_id
|
556 |
+
* @param $ticket_id
|
557 |
+
*
|
558 |
+
* @return bool
|
559 |
+
*/
|
560 |
+
public function delete_ticket( $event_id, $ticket_id ) {
|
561 |
+
/**
|
562 |
+
* Important, do not add anything above this method.
|
563 |
+
* Our goal is to reduce the amount of load on the `Module`, relegate these behaviors to the correct models.
|
564 |
+
*/
|
565 |
+
$deleted = tribe( Ticket::class )->delete( $event_id, $ticket_id );
|
566 |
+
|
567 |
+
if ( ! $deleted ) {
|
568 |
+
return $deleted;
|
569 |
+
}
|
570 |
+
|
571 |
+
// Run anything we might need on parent method.
|
572 |
+
parent::delete_ticket( $event_id, $ticket_id );
|
573 |
+
|
574 |
+
return $deleted;
|
575 |
+
}
|
576 |
+
|
577 |
+
/**
|
578 |
+
* Return whether we're currently on the checkout page for Tickets Commerce.
|
579 |
+
*
|
580 |
+
* @since 5.1.9
|
581 |
+
*
|
582 |
+
* @return bool
|
583 |
+
*/
|
584 |
+
public function is_checkout_page() {
|
585 |
+
return tribe( Checkout::class )->is_current_page();
|
586 |
+
}
|
587 |
+
|
588 |
+
/**
|
589 |
+
* Links to sales report for all tickets for this event.
|
590 |
+
*
|
591 |
+
* @since 5.1.9
|
592 |
+
*
|
593 |
+
* @param int $event_id
|
594 |
+
* @param bool $url_only
|
595 |
+
*
|
596 |
+
* @return string
|
597 |
+
*/
|
598 |
+
public function get_event_reports_link( $event_id, $url_only = false ) {
|
599 |
+
return tribe( Commerce\Reports\Event::class )->get_link( $event_id, $url_only );
|
600 |
+
}
|
601 |
+
|
602 |
+
/**
|
603 |
+
* Links to the sales report for this product.
|
604 |
+
*
|
605 |
+
* @since 5.1.9
|
606 |
+
*
|
607 |
+
* @param $event_id
|
608 |
+
* @param $ticket_id
|
609 |
+
*
|
610 |
+
* @return string
|
611 |
+
*/
|
612 |
+
public function get_ticket_reports_link( $event_id, $ticket_id ) {
|
613 |
+
return tribe( Commerce\Reports\Event::class )->get_link( $event_id, $ticket_id );
|
614 |
+
}
|
615 |
+
}
|
src/Tickets/Commerce/Order.php
ADDED
@@ -0,0 +1,642 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce;
|
6 |
+
use TEC\Tickets\Commerce\Utils\Price;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Order
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce
|
14 |
+
*/
|
15 |
+
class Order {
|
16 |
+
/**
|
17 |
+
* Tickets Commerce Order Post Type slug.
|
18 |
+
*
|
19 |
+
* @since 5.1.9
|
20 |
+
*
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
const POSTTYPE = 'tec_tc_order';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Which meta holds which gateway was used on this order.
|
27 |
+
*
|
28 |
+
* @since 5.1.9
|
29 |
+
*
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
public static $gateway_meta_key = '_tec_tc_order_gateway';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Which meta holds which gateway order id was used on this order.
|
36 |
+
*
|
37 |
+
* @since 5.1.9
|
38 |
+
*
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
public static $gateway_order_id_meta_key = '_tec_tc_order_gateway_order_id';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Normally when dealing with the gateways we have a payload from the original creation of the Order on their side
|
45 |
+
* of the API, we should store that whole Payload with this meta key so that this data can be used in the future.
|
46 |
+
*
|
47 |
+
* @since 5.1.9
|
48 |
+
*
|
49 |
+
* @var string
|
50 |
+
*/
|
51 |
+
public static $gateway_payload_meta_key = '_tec_tc_order_gateway_payload';
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Which meta holds the cart items used to setup this order.
|
55 |
+
*
|
56 |
+
* @since 5.1.9
|
57 |
+
*
|
58 |
+
* @var string
|
59 |
+
*/
|
60 |
+
public static $cart_items_meta_key = '_tec_tc_order_cart_items';
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Which meta holds the tickets in a given order, they are added as individual meta items, allowing them to be
|
64 |
+
* selected in a meta query.
|
65 |
+
*
|
66 |
+
* @since 5.1.9
|
67 |
+
*
|
68 |
+
* @var string
|
69 |
+
*/
|
70 |
+
public static $tickets_in_order_meta_key = '_tec_tc_order_tickets_in_order';
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Which meta holds the events in a given order, they are added as individual meta items, allowing them to be
|
74 |
+
* selected in a meta query.
|
75 |
+
*
|
76 |
+
* @since 5.1.9
|
77 |
+
*
|
78 |
+
* @var string
|
79 |
+
*/
|
80 |
+
public static $events_in_order_meta_key = '_tec_tc_order_events_in_order';
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Which meta holds the cart items used to setup this order.
|
84 |
+
*
|
85 |
+
* @since 5.1.9
|
86 |
+
*
|
87 |
+
* @var string
|
88 |
+
*/
|
89 |
+
public static $total_value_meta_key = '_tec_tc_order_total_value';
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Which meta holds the cart items used to setup this order.
|
93 |
+
*
|
94 |
+
* @since 5.1.9
|
95 |
+
*
|
96 |
+
* @var string
|
97 |
+
*/
|
98 |
+
public static $currency_meta_key = '_tec_tc_order_currency';
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Which meta holds the purchaser full name.
|
102 |
+
*
|
103 |
+
* @since 5.1.9
|
104 |
+
*
|
105 |
+
* @var string
|
106 |
+
*/
|
107 |
+
public static $purchaser_full_name_meta_key = '_tec_tc_order_purchaser_full_name';
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Which meta holds the purchaser first name.
|
111 |
+
*
|
112 |
+
* @since 5.1.9
|
113 |
+
*
|
114 |
+
* @var string
|
115 |
+
*/
|
116 |
+
public static $purchaser_first_name_meta_key = '_tec_tc_order_purchaser_first_name';
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Which meta holds the purchaser last name.
|
120 |
+
*
|
121 |
+
* @since 5.1.9
|
122 |
+
*
|
123 |
+
* @var string
|
124 |
+
*/
|
125 |
+
public static $purchaser_last_name_meta_key = '_tec_tc_order_purchaser_last_name';
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Which meta holds the cart items used to setup this order.
|
129 |
+
*
|
130 |
+
* @since 5.1.9
|
131 |
+
*
|
132 |
+
* @var string
|
133 |
+
*/
|
134 |
+
public static $purchaser_email_meta_key = '_tec_tc_order_purchaser_email';
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Register this Class post type into WP.
|
138 |
+
*
|
139 |
+
* @since 5.1.9
|
140 |
+
*/
|
141 |
+
public function register_post_type() {
|
142 |
+
$post_type_args = [
|
143 |
+
'label' => __( 'Orders', 'event-tickets' ),
|
144 |
+
'public' => false,
|
145 |
+
'show_ui' => false,
|
146 |
+
'show_in_menu' => false,
|
147 |
+
'query_var' => false,
|
148 |
+
'rewrite' => false,
|
149 |
+
'capability_type' => 'post',
|
150 |
+
'has_archive' => false,
|
151 |
+
'hierarchical' => false,
|
152 |
+
];
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Filter the arguments that craft the order post type.
|
156 |
+
*
|
157 |
+
* @see register_post_type
|
158 |
+
*
|
159 |
+
* @since 5.1.9
|
160 |
+
*
|
161 |
+
* @param array $post_type_args Post type arguments, passed to register_post_type()
|
162 |
+
*/
|
163 |
+
$post_type_args = apply_filters( 'tec_tickets_commerce_order_post_type_args', $post_type_args );
|
164 |
+
|
165 |
+
register_post_type( static::POSTTYPE, $post_type_args );
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Gets the meta Key for a given Order Status gateway_payload.
|
170 |
+
*
|
171 |
+
* @since 5.1.9
|
172 |
+
*
|
173 |
+
* @param Status\Status_Interface $status
|
174 |
+
*
|
175 |
+
* @return string
|
176 |
+
*/
|
177 |
+
public static function get_gateway_payload_meta_key( Commerce\Status\Status_Interface $status ) {
|
178 |
+
return static::$gateway_payload_meta_key . '_' . $status->get_slug();
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Modify the status of a given order based on Slug.
|
183 |
+
*
|
184 |
+
* @since 5.1.9
|
185 |
+
*
|
186 |
+
* @throws \Tribe__Repository__Usage_Error
|
187 |
+
*
|
188 |
+
* @param int $order_id Which order ID will be updated.
|
189 |
+
* @param string $status_slug Which Order Status we are modifying to.
|
190 |
+
* @param array $extra_args Extra repository arguments.
|
191 |
+
*
|
192 |
+
* @return bool|\WP_Error
|
193 |
+
*/
|
194 |
+
public function modify_status( $order_id, $status_slug, array $extra_args = [] ) {
|
195 |
+
$status = tribe( Commerce\Status\Status_Handler::class )->get_by_slug( $status_slug );
|
196 |
+
|
197 |
+
if ( ! $status ) {
|
198 |
+
return false;
|
199 |
+
}
|
200 |
+
|
201 |
+
$can_apply = $status->can_apply_to( $order_id );
|
202 |
+
if ( ! $can_apply ) {
|
203 |
+
return $can_apply;
|
204 |
+
}
|
205 |
+
|
206 |
+
$args = array_merge( $extra_args, [ 'status' => $status->get_wp_slug() ] );
|
207 |
+
|
208 |
+
$updated = tec_tc_orders()->by_args( [
|
209 |
+
'status' => 'any',
|
210 |
+
'id' => $order_id,
|
211 |
+
] )->set_args( $args )->save();
|
212 |
+
|
213 |
+
return (bool) $updated;
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* @todo WIP
|
218 |
+
*
|
219 |
+
* @since 5.1.9
|
220 |
+
*
|
221 |
+
* @throws \Tribe__Repository__Usage_Error
|
222 |
+
*
|
223 |
+
* @return false|\WP_Post
|
224 |
+
*/
|
225 |
+
public function create_from_cart( Commerce\Gateways\Interface_Gateway $gateway, $purchaser = null ) {
|
226 |
+
$cart = tribe( Cart::class );
|
227 |
+
|
228 |
+
$items = $cart->get_items_in_cart();
|
229 |
+
$items = array_map( static function ( $item ) {
|
230 |
+
$ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
|
231 |
+
$item['sub_total'] = Price::sub_total( $ticket->price, $item['quantity'] );
|
232 |
+
|
233 |
+
return $item;
|
234 |
+
}, $items );
|
235 |
+
$sub_totals = array_filter( wp_list_pluck( $items, 'sub_total' ) );
|
236 |
+
$total = Price::total( $sub_totals );
|
237 |
+
|
238 |
+
$order_args = [
|
239 |
+
'title' => $this->generate_order_title( $items, $cart->get_cart_hash() ),
|
240 |
+
'total_value' => $total,
|
241 |
+
'cart_items' => $items,
|
242 |
+
'gateway' => $gateway::get_key(),
|
243 |
+
];
|
244 |
+
|
245 |
+
// When purchaser data-set is not passed we pull from the current user.
|
246 |
+
if ( empty( $purchaser ) && is_user_logged_in() && $user = wp_get_current_user() ) {
|
247 |
+
$order_args['author'] = $user->ID;
|
248 |
+
$order_args['purchaser_full_name'] = $user->first_name . ' ' . $user->last_name;
|
249 |
+
$order_args['purchaser_first_name'] = $user->first_name;
|
250 |
+
$order_args['purchaser_last_name'] = $user->last_name;
|
251 |
+
$order_args['purchaser_email'] = $user->user_email;
|
252 |
+
}
|
253 |
+
|
254 |
+
$order = tec_tc_orders()->set_args( $order_args )->create();
|
255 |
+
|
256 |
+
// We were unable to create the order bail from here.
|
257 |
+
if ( ! $order ) {
|
258 |
+
return false;
|
259 |
+
}
|
260 |
+
|
261 |
+
return $order;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Generates a title based on Cart Hash, items in the cart.
|
266 |
+
*
|
267 |
+
* @since 5.1.9
|
268 |
+
*
|
269 |
+
* @param array $items List of events form
|
270 |
+
*
|
271 |
+
* @return string
|
272 |
+
*/
|
273 |
+
public function generate_order_title( $items, $hash = null ) {
|
274 |
+
$title = [ 'TEC-TC' ];
|
275 |
+
if ( $hash ) {
|
276 |
+
$title[] = $hash;
|
277 |
+
}
|
278 |
+
$title[] = 'T';
|
279 |
+
|
280 |
+
$tickets = array_filter( wp_list_pluck( $items, 'ticket_id' ) );
|
281 |
+
$title = array_merge( $title, $tickets );
|
282 |
+
|
283 |
+
return implode( '-', $title );
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Redirects to the source post after a recoverable (logic) error.
|
288 |
+
*
|
289 |
+
* @todo Determine if redirecting should be something relegated to some other method, and here we just actually
|
290 |
+
* generate the order/Attendees.
|
291 |
+
*
|
292 |
+
* @see \Tribe__Tickets__Commerce__PayPal__Errors for error codes translations.
|
293 |
+
* @since 5.1.9
|
294 |
+
*
|
295 |
+
* @param bool $redirect Whether to really redirect or not.
|
296 |
+
* @param int $post_id A post ID
|
297 |
+
*
|
298 |
+
* @param int $error_code The current error code
|
299 |
+
*
|
300 |
+
*/
|
301 |
+
protected function redirect_after_error( $error_code, $redirect, $post_id ) {
|
302 |
+
$url = add_query_arg( 'tpp_error', $error_code, get_permalink( $post_id ) );
|
303 |
+
if ( $redirect ) {
|
304 |
+
wp_redirect( esc_url_raw( $url ) );
|
305 |
+
}
|
306 |
+
tribe_exit();
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Generate and store all the attendees information for a new order.
|
311 |
+
*
|
312 |
+
* @since 5.1.9
|
313 |
+
*
|
314 |
+
* @param string $payment_status The tickets payment status, defaults to completed.
|
315 |
+
* @param bool $redirect Whether the client should be redirected or not.
|
316 |
+
*
|
317 |
+
*/
|
318 |
+
public function generate_order( $payment_status = 'completed', $redirect = true ) {
|
319 |
+
/*
|
320 |
+
* This method might run during a POST (IPN) PayPal request hence the
|
321 |
+
* purchasing user ID, if any, will be stored in a custom PayPal var.
|
322 |
+
* Let's fallback on the current user ID for GET requests (PDT); it will be always `0`
|
323 |
+
* during a PayPal POST (IPN) request.
|
324 |
+
*/
|
325 |
+
$attendee_user_id = ! isset( $custom['user_id'] ) ? get_current_user_id() : absint( $custom['user_id'] );
|
326 |
+
|
327 |
+
$attendee_full_name = empty( $transaction_data['first_name'] ) && empty( $transaction_data['last_name'] )
|
328 |
+
? ''
|
329 |
+
: sanitize_text_field( "{$transaction_data['first_name']} {$transaction_data['last_name']}" );
|
330 |
+
|
331 |
+
$attendee_email = empty( $transaction_data['payer_email'] ) ? null : sanitize_email( $transaction_data['payer_email'] );
|
332 |
+
$attendee_email = is_email( $attendee_email ) ? $attendee_email : null;
|
333 |
+
|
334 |
+
if ( ! empty( $attendee_user_id ) ) {
|
335 |
+
$attendee = get_user_by( 'id', $attendee_user_id );
|
336 |
+
|
337 |
+
// Check if the user was found.
|
338 |
+
if ( $attendee ) {
|
339 |
+
// Check if the user has an email address.
|
340 |
+
if ( $attendee->user_email ) {
|
341 |
+
$attendee_email = $attendee->user_email;
|
342 |
+
}
|
343 |
+
|
344 |
+
$user_full_name = trim( "{$attendee->first_name} {$attendee->last_name}" );
|
345 |
+
|
346 |
+
// Check if the user has first/last name.
|
347 |
+
if ( ! empty( $user_full_name ) ) {
|
348 |
+
$attendee_full_name = $user_full_name;
|
349 |
+
}
|
350 |
+
}
|
351 |
+
}
|
352 |
+
|
353 |
+
/**
|
354 |
+
* This is an array of tickets IDs for which the user decided to opt-out.
|
355 |
+
*
|
356 |
+
* @see \Tribe__Tickets_Plus__Commerce__PayPal__Attendees::register_optout_choice()
|
357 |
+
*/
|
358 |
+
$attendee_optouts = \Tribe__Utils__Array::get( $custom, 'oo', [] );
|
359 |
+
|
360 |
+
if ( ! $attendee_email || ! $attendee_full_name ) {
|
361 |
+
$this->redirect_after_error( 101, $redirect, $post_id );
|
362 |
+
|
363 |
+
return;
|
364 |
+
}
|
365 |
+
|
366 |
+
// Iterate over each product
|
367 |
+
foreach ( (array) $transaction_data['items'] as $item ) {
|
368 |
+
$order_attendee_id = 0;
|
369 |
+
|
370 |
+
if ( empty( $item['ticket'] ) ) {
|
371 |
+
continue;
|
372 |
+
}
|
373 |
+
|
374 |
+
/** @var \Tribe__Tickets__Ticket_Object $ticket_type */
|
375 |
+
$ticket_type = $item['ticket'];
|
376 |
+
$product_id = $ticket_type->ID;
|
377 |
+
|
378 |
+
// Get the event this tickets is for
|
379 |
+
$post = $ticket_type->get_event();
|
380 |
+
|
381 |
+
if ( empty( $post ) ) {
|
382 |
+
continue;
|
383 |
+
}
|
384 |
+
|
385 |
+
$post_id = $post->ID;
|
386 |
+
|
387 |
+
// if there were no PayPal tickets for the product added to the cart, continue
|
388 |
+
if ( empty( $item['quantity'] ) ) {
|
389 |
+
continue;
|
390 |
+
}
|
391 |
+
|
392 |
+
// get the PayPal status `decrease_stock_by` value
|
393 |
+
$status_stock_size = 1;
|
394 |
+
|
395 |
+
$ticket_qty = (int) $item['quantity'];
|
396 |
+
|
397 |
+
// to avoid tickets from not being created on a status stock size of 0
|
398 |
+
// let's take the status stock size into account and create a number of tickets
|
399 |
+
// at least equal to the number of tickets the user requested
|
400 |
+
$ticket_qty = $status_stock_size < 1 ? $ticket_qty : $status_stock_size * $ticket_qty;
|
401 |
+
|
402 |
+
$qty = max( $ticket_qty, 0 );
|
403 |
+
|
404 |
+
// Throw an error if Qty is bigger then Remaining
|
405 |
+
if ( $payment_status === tribe( Commerce\Status\Completed::class )->get_wp_slug() && $ticket_type->managing_stock() ) {
|
406 |
+
add_action( 'tec_tickets_commerce_pending_stock_ignore', '__return_true' );
|
407 |
+
$inventory = (int) $ticket_type->inventory();
|
408 |
+
remove_action( 'tec_tickets_commerce_pending_stock_ignore', '__return_true' );
|
409 |
+
|
410 |
+
$inventory_is_not_unlimited = - 1 !== $inventory;
|
411 |
+
|
412 |
+
if ( $inventory_is_not_unlimited && $qty > $inventory ) {
|
413 |
+
if ( ! $order->was_pending() ) {
|
414 |
+
$this->redirect_after_error( 102, $redirect, $post_id );
|
415 |
+
|
416 |
+
return;
|
417 |
+
}
|
418 |
+
|
419 |
+
/** @var \Tribe__Tickets__Commerce__PayPal__Oversell__Policies $oversell_policies */
|
420 |
+
$oversell_policies = tribe( 'tickets.commerce.paypal.oversell.policies' );
|
421 |
+
$oversell_policy = $oversell_policies->for_post_ticket_order( $post_id, $ticket_type->ID, $order_id );
|
422 |
+
|
423 |
+
$qty = $oversell_policy->modify_quantity( $qty, $inventory );
|
424 |
+
|
425 |
+
if ( ! $oversell_policy->allows_overselling() ) {
|
426 |
+
$oversold_attendees = tribe( Module::class )->get_attendees_by_order_id( $order_id );
|
427 |
+
$oversell_policy->handle_oversold_attendees( $oversold_attendees );
|
428 |
+
$this->redirect_after_error( 102, $redirect, $post_id );
|
429 |
+
|
430 |
+
return;
|
431 |
+
}
|
432 |
+
}
|
433 |
+
}
|
434 |
+
|
435 |
+
if ( $qty === 0 ) {
|
436 |
+
$this->redirect_after_error( 103, $redirect, $post_id );
|
437 |
+
|
438 |
+
return;
|
439 |
+
}
|
440 |
+
|
441 |
+
$has_tickets = true;
|
442 |
+
|
443 |
+
/**
|
444 |
+
* PayPal specific action fired just before a PayPal-driven attendee ticket for an event is generated
|
445 |
+
*
|
446 |
+
* @since 4.7
|
447 |
+
*
|
448 |
+
* @param int $post_id ID of event
|
449 |
+
* @param string $ticket_type Ticket Type object for the product
|
450 |
+
* @param array $data Parsed PayPal transaction data
|
451 |
+
*/
|
452 |
+
do_action( 'tribe_tickets_tpp_before_attendee_ticket_creation', $post_id, $ticket_type, $transaction_data );
|
453 |
+
|
454 |
+
$existing_attendees = tribe( Module::class )->get_attendees_by_order_id( $order_id );
|
455 |
+
|
456 |
+
$has_generated_new_tickets = false;
|
457 |
+
|
458 |
+
/** @var \Tribe__Tickets__Commerce__Currency $currency */
|
459 |
+
$currency = tribe( 'tickets.commerce.currency' );
|
460 |
+
$currency_symbol = $currency->get_currency_symbol( $product_id, true );
|
461 |
+
|
462 |
+
// Iterate over all the amount of tickets purchased (for this product)
|
463 |
+
for ( $i = 0; $i < $qty; $i ++ ) {
|
464 |
+
$attendee_id = null;
|
465 |
+
$updating_attendee = false;
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Allow filtering the individual attendee name used when creating a new attendee.
|
469 |
+
*
|
470 |
+
* @since 5.0.3
|
471 |
+
*
|
472 |
+
* @param string $individual_attendee_name The attendee full name.
|
473 |
+
* @param int|null $attendee_number The attendee number index value from the order, starting with zero.
|
474 |
+
* @param int $order_id The order ID.
|
475 |
+
* @param int $ticket_id The ticket ID.
|
476 |
+
* @param int $post_id The ID of the post associated to the ticket.
|
477 |
+
* @param \Tribe__Tickets__Tickets $provider The current ticket provider object.
|
478 |
+
*/
|
479 |
+
$individual_attendee_name = apply_filters( 'tribe_tickets_attendee_create_individual_name', $attendee_full_name, $i, $order_id, $product_id, $post_id, $this );
|
480 |
+
|
481 |
+
/**
|
482 |
+
* Allow filtering the individual attendee email used when creating a new attendee.
|
483 |
+
*
|
484 |
+
* @since 5.0.3
|
485 |
+
*
|
486 |
+
* @param string $individual_attendee_email The attendee email.
|
487 |
+
* @param int|null $attendee_number The attendee number index value from the order, starting with zero.
|
488 |
+
* @param int $order_id The order ID.
|
489 |
+
* @param int $ticket_id The ticket ID.
|
490 |
+
* @param int $post_id The ID of the post associated to the ticket.
|
491 |
+
* @param \Tribe__Tickets__Tickets $provider The current ticket provider object.
|
492 |
+
*/
|
493 |
+
$individual_attendee_email = apply_filters( 'tribe_tickets_attendee_create_individual_email', $attendee_email, $i, $order_id, $product_id, $post_id, $this );
|
494 |
+
|
495 |
+
// check if we already have an attendee or not
|
496 |
+
$post_title = $individual_attendee_name . ' | ' . ( $i + 1 );
|
497 |
+
$criteria = [ 'post_title' => $post_title, 'product_id' => $product_id, 'event_id' => $post_id ];
|
498 |
+
$existing_attendee = wp_list_filter( $existing_attendees, $criteria );
|
499 |
+
|
500 |
+
if ( ! empty( $existing_attendee ) ) {
|
501 |
+
$existing_attendee = reset( $existing_attendee );
|
502 |
+
$updating_attendee = true;
|
503 |
+
$attendee_id = $existing_attendee['attendee_id'];
|
504 |
+
$attendee = [];
|
505 |
+
} else {
|
506 |
+
$attendee = [
|
507 |
+
'post_title' => $post_title,
|
508 |
+
];
|
509 |
+
|
510 |
+
// since we are creating at least one
|
511 |
+
$has_generated_new_tickets = true;
|
512 |
+
}
|
513 |
+
|
514 |
+
$attendee_order_status = trim( strtolower( $payment_status ) );
|
515 |
+
|
516 |
+
$repository = tribe_attendees( $this->orm_provider );
|
517 |
+
|
518 |
+
$data = $attendee;
|
519 |
+
|
520 |
+
$data['order_attendee_id'] = $order_attendee_id;
|
521 |
+
$data['attendee_status'] = $attendee_order_status;
|
522 |
+
|
523 |
+
if ( Order_Statuses::$refunded === $payment_status ) {
|
524 |
+
$refund_order_id = \Tribe__Utils__Array::get( $transaction_data, 'txn_id', '' );
|
525 |
+
|
526 |
+
$data['refund_order_id'] = $refund_order_id;
|
527 |
+
}
|
528 |
+
|
529 |
+
if ( ! $updating_attendee ) {
|
530 |
+
$optout = \Tribe__Utils__Array::get( $attendee_optouts, 'ticket_' . $product_id, false );
|
531 |
+
$optout = filter_var( $optout, FILTER_VALIDATE_BOOLEAN );
|
532 |
+
$optout = $optout ? 'yes' : 'no';
|
533 |
+
|
534 |
+
$data['ticket_id'] = $product_id;
|
535 |
+
$data['post_id'] = $post_id;
|
536 |
+
$data['order_id'] = $order_id;
|
537 |
+
$data['optout'] = $optout;
|
538 |
+
$data['full_name'] = $individual_attendee_name;
|
539 |
+
$data['email'] = $individual_attendee_email;
|
540 |
+
$data['price_paid'] = get_post_meta( $product_id, '_price', true );
|
541 |
+
$data['price_currency'] = $currency_symbol;
|
542 |
+
|
543 |
+
if ( 0 < $attendee_user_id ) {
|
544 |
+
$data['user_id'] = $attendee_user_id;
|
545 |
+
}
|
546 |
+
|
547 |
+
$attendee_object = tribe( Module::class )->create_attendee( $ticket_type, $data );
|
548 |
+
$attendee_id = $attendee_object->ID;
|
549 |
+
|
550 |
+
} else {
|
551 |
+
// Update attendee.
|
552 |
+
tribe( Module::class )->update_attendee( $attendee_id, $data );
|
553 |
+
}
|
554 |
+
|
555 |
+
$order->add_attendee( $attendee_id );
|
556 |
+
|
557 |
+
$order_attendee_id ++;
|
558 |
+
|
559 |
+
if ( ! empty( $existing_attendee ) ) {
|
560 |
+
$existing_attendees = wp_list_filter( $existing_attendees, array( 'attendee_id' => $existing_attendee['attendee_id'] ), 'NOT' );
|
561 |
+
}
|
562 |
+
}
|
563 |
+
|
564 |
+
if ( ! ( empty( $existing_attendees ) || empty( $oversell_policy ) ) ) {
|
565 |
+
// an oversell policy applied: what to do with existing oversold attendees?
|
566 |
+
$oversell_policy->handle_oversold_attendees( $existing_attendees );
|
567 |
+
}
|
568 |
+
|
569 |
+
if ( $has_generated_new_tickets ) {
|
570 |
+
/**
|
571 |
+
* Action fired when a PayPal has had attendee tickets generated for it.
|
572 |
+
*
|
573 |
+
* @since 4.7
|
574 |
+
*
|
575 |
+
* @param int $product_id PayPal ticket post ID
|
576 |
+
* @param string $order_id ID of the PayPal order
|
577 |
+
* @param int $qty Quantity ordered
|
578 |
+
*/
|
579 |
+
do_action( 'event_tickets_tpp_tickets_generated_for_product', $product_id, $order_id, $qty );
|
580 |
+
}
|
581 |
+
|
582 |
+
/**
|
583 |
+
* Action fired when a PayPal has had attendee tickets updated for it.
|
584 |
+
*
|
585 |
+
* This will fire even when tickets are initially created; if you need to hook on the
|
586 |
+
* creation process only use the 'event_tickets_tpp_tickets_generated_for_product' action.
|
587 |
+
*
|
588 |
+
* @since 4.7
|
589 |
+
*
|
590 |
+
* @param int $product_id PayPal ticket post ID
|
591 |
+
* @param string $order_id ID of the PayPal order
|
592 |
+
* @param int $qty Quantity ordered
|
593 |
+
*/
|
594 |
+
do_action( 'event_tickets_tpp_tickets_generated_for_product', $product_id, $order_id, $qty );
|
595 |
+
|
596 |
+
// After Adding the Values we Update the Transient
|
597 |
+
\Tribe__Post_Transient::instance()->delete( $post_id, \Tribe__Tickets__Tickets::ATTENDEES_CACHE );
|
598 |
+
}
|
599 |
+
|
600 |
+
$order->update();
|
601 |
+
|
602 |
+
/**
|
603 |
+
* Fires when an PayPal attendee tickets have been generated.
|
604 |
+
*
|
605 |
+
* @since 4.7
|
606 |
+
*
|
607 |
+
* @param string $order_id ID of the PayPal order
|
608 |
+
* @param int $post_id ID of the post the order was placed for
|
609 |
+
*/
|
610 |
+
do_action( 'event_tickets_tpp_tickets_generated', $order_id, $post_id );
|
611 |
+
|
612 |
+
/**
|
613 |
+
* Filters whether a confirmation email should be sent or not for PayPal tickets.
|
614 |
+
*
|
615 |
+
* This applies to attendance and non attendance emails.
|
616 |
+
*
|
617 |
+
* @since 4.7
|
618 |
+
*
|
619 |
+
* @param bool $send_mail Defaults to `true`.
|
620 |
+
*/
|
621 |
+
$send_mail = apply_filters( 'tribe_tickets_tpp_send_mail', true );
|
622 |
+
|
623 |
+
if (
|
624 |
+
$send_mail
|
625 |
+
&& $has_tickets
|
626 |
+
&& $attendee_order_status === Order_Statuses::$completed
|
627 |
+
) {
|
628 |
+
$this->send_tickets_email( $order_id, $post_id );
|
629 |
+
}
|
630 |
+
|
631 |
+
// Redirect to the same page to prevent double purchase on refresh
|
632 |
+
if ( ! empty( $post_id ) ) {
|
633 |
+
/** @var \Tribe__Tickets__Commerce__PayPal__Endpoints $endpoints */
|
634 |
+
$endpoints = tribe( 'tickets.commerce.paypal.endpoints' );
|
635 |
+
$url = $endpoints->success_url( $order_id, $post_id );
|
636 |
+
if ( $redirect ) {
|
637 |
+
wp_redirect( esc_url_raw( $url ) );
|
638 |
+
}
|
639 |
+
tribe_exit();
|
640 |
+
}
|
641 |
+
}
|
642 |
+
}
|
src/Tickets/Commerce/Provider.php
CHANGED
@@ -10,7 +10,8 @@ namespace TEC\Tickets\Commerce;
|
|
10 |
|
11 |
use tad_DI52_ServiceProvider;
|
12 |
use TEC\Tickets\Commerce\Gateways;
|
13 |
-
use Tribe__Tickets__Main;
|
|
|
14 |
|
15 |
/**
|
16 |
* Service provider for the Tickets Commerce.
|
@@ -35,6 +36,8 @@ class Provider extends tad_DI52_ServiceProvider {
|
|
35 |
$this->register_hooks();
|
36 |
$this->register_assets();
|
37 |
|
|
|
|
|
38 |
$this->register_legacy_compat();
|
39 |
|
40 |
// Register the SP on the container.
|
@@ -44,9 +47,28 @@ class Provider extends tad_DI52_ServiceProvider {
|
|
44 |
// Register all singleton classes.
|
45 |
$this->container->singleton( Gateways\Manager::class, Gateways\Manager::class );
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
// Load any external SPs we might need.
|
48 |
$this->container->register( Gateways\PayPal\Provider::class );
|
49 |
-
// $this->container->register( Gateways\Legacy\Provider::class );
|
50 |
}
|
51 |
|
52 |
/**
|
@@ -61,6 +83,20 @@ class Provider extends tad_DI52_ServiceProvider {
|
|
61 |
$this->container->singleton( Assets::class, $assets );
|
62 |
}
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
/**
|
65 |
* Registers the provider handling all the 1st level filters and actions for Tickets Commerce.
|
66 |
*
|
@@ -72,7 +108,7 @@ class Provider extends tad_DI52_ServiceProvider {
|
|
72 |
|
73 |
// Allow Hooks to be removed, by having the them registered to the container
|
74 |
$this->container->singleton( Hooks::class, $hooks );
|
75 |
-
$this->container->singleton( 'tickets.hooks', $hooks );
|
76 |
}
|
77 |
|
78 |
/**
|
@@ -85,6 +121,6 @@ class Provider extends tad_DI52_ServiceProvider {
|
|
85 |
$v1_compat->register();
|
86 |
|
87 |
$this->container->singleton( Legacy_Compat::class, $v1_compat );
|
88 |
-
$this->container->singleton( 'tickets.legacy-compat', $v1_compat );
|
89 |
}
|
90 |
}
|
10 |
|
11 |
use tad_DI52_ServiceProvider;
|
12 |
use TEC\Tickets\Commerce\Gateways;
|
13 |
+
use \Tribe__Tickets__Main as Tickets_Plugin;
|
14 |
+
|
15 |
|
16 |
/**
|
17 |
* Service provider for the Tickets Commerce.
|
36 |
$this->register_hooks();
|
37 |
$this->register_assets();
|
38 |
|
39 |
+
$this->load_functions();
|
40 |
+
|
41 |
$this->register_legacy_compat();
|
42 |
|
43 |
// Register the SP on the container.
|
47 |
// Register all singleton classes.
|
48 |
$this->container->singleton( Gateways\Manager::class, Gateways\Manager::class );
|
49 |
|
50 |
+
$this->container->singleton( Reports\Attendance_Totals::class );
|
51 |
+
$this->container->singleton( Reports\Event::class );
|
52 |
+
$this->container->singleton( Reports\Ticket::class );
|
53 |
+
|
54 |
+
$this->container->singleton( Editor\Metabox::class );
|
55 |
+
|
56 |
+
$this->container->singleton( Module::class );
|
57 |
+
$this->container->singleton( Attendee::class );
|
58 |
+
$this->container->singleton( Order::class );
|
59 |
+
$this->container->singleton( Ticket::class );
|
60 |
+
$this->container->singleton( Cart::class );
|
61 |
+
$this->container->singleton( Cart\Unmanaged_Cart::class );
|
62 |
+
|
63 |
+
$this->container->singleton( Checkout::class );
|
64 |
+
$this->container->singleton( Settings::class );
|
65 |
+
$this->container->singleton( Tickets_View::class );
|
66 |
+
|
67 |
+
$this->container->register( Status\Status_Handler::class );
|
68 |
+
$this->container->register( Flag_Actions\Flag_Action_Handler::class );
|
69 |
+
|
70 |
// Load any external SPs we might need.
|
71 |
$this->container->register( Gateways\PayPal\Provider::class );
|
|
|
72 |
}
|
73 |
|
74 |
/**
|
83 |
$this->container->singleton( Assets::class, $assets );
|
84 |
}
|
85 |
|
86 |
+
/**
|
87 |
+
* Include All function files.
|
88 |
+
*
|
89 |
+
* @since 5.1.9
|
90 |
+
*/
|
91 |
+
protected function load_functions() {
|
92 |
+
$path = Tickets_Plugin::instance()->plugin_path;
|
93 |
+
|
94 |
+
require_once $path . 'src/functions/commerce/orm.php';
|
95 |
+
require_once $path . 'src/functions/commerce/orders.php';
|
96 |
+
require_once $path . 'src/functions/commerce/attendees.php';
|
97 |
+
require_once $path . 'src/functions/commerce/tickets.php';
|
98 |
+
}
|
99 |
+
|
100 |
/**
|
101 |
* Registers the provider handling all the 1st level filters and actions for Tickets Commerce.
|
102 |
*
|
108 |
|
109 |
// Allow Hooks to be removed, by having the them registered to the container
|
110 |
$this->container->singleton( Hooks::class, $hooks );
|
111 |
+
$this->container->singleton( 'tickets.commerce.hooks', $hooks );
|
112 |
}
|
113 |
|
114 |
/**
|
121 |
$v1_compat->register();
|
122 |
|
123 |
$this->container->singleton( Legacy_Compat::class, $v1_compat );
|
124 |
+
$this->container->singleton( 'tickets.commerce.legacy-compat', $v1_compat );
|
125 |
}
|
126 |
}
|
src/Tickets/Commerce/Reports/Attendance_Totals.php
ADDED
@@ -0,0 +1,237 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Reports;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Calculates Ticket Commerce attendance totals for a specified event (ie, how many
|
7 |
+
* are going, not going, etc).
|
8 |
+
*
|
9 |
+
* Also has the capability to print this information as HTML, intended for
|
10 |
+
* use in the attendee summary screen.
|
11 |
+
*
|
12 |
+
* Note that the totals are calculated upon instantiation, effectively making
|
13 |
+
* the object a snapshot in time. Therefore if the status of PayPal Tickets is modified
|
14 |
+
* or if PayPal Tickets are added/deleted later in the request, it would be necessary
|
15 |
+
* to obtain a new object of this type to get accurate results.
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*
|
19 |
+
* @package TEC\Tickets\Commerce\Reports
|
20 |
+
*/
|
21 |
+
class Attendance_Totals extends \Tribe__Tickets__Abstract_Attendance_Totals {
|
22 |
+
protected $total_paid = 0;
|
23 |
+
protected $total_pending = 0;
|
24 |
+
protected $total_cancelled = 0;
|
25 |
+
protected $total_refunded = 0;
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* {@inheritDoc}
|
30 |
+
*
|
31 |
+
* @since 4.7
|
32 |
+
*/
|
33 |
+
protected function calculate_totals() {
|
34 |
+
$tickets = \Tribe__Tickets__Tickets::get_event_tickets( $this->event_id );
|
35 |
+
|
36 |
+
foreach ( $tickets as $ticket ) {
|
37 |
+
/** @var \Tribe__Tickets__Ticket_Object $ticket */
|
38 |
+
if ( ! $this->should_count( $ticket ) ) {
|
39 |
+
continue;
|
40 |
+
}
|
41 |
+
|
42 |
+
$this->total_paid += $ticket->qty_sold();
|
43 |
+
$this->total_pending += $ticket->qty_pending();
|
44 |
+
$this->total_cancelled += $ticket->qty_cancelled();
|
45 |
+
$this->total_refunded += $ticket->qty_refunded();
|
46 |
+
}
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Indicates if the ticket should be factored into our sales counts.
|
51 |
+
*
|
52 |
+
* @since 4.7
|
53 |
+
*
|
54 |
+
* @param \Tribe__Tickets__Ticket_Object $ticket
|
55 |
+
*
|
56 |
+
* @return bool
|
57 |
+
*/
|
58 |
+
protected function should_count( \Tribe__Tickets__Ticket_Object $ticket ) {
|
59 |
+
$should_count = 'Tribe__Tickets__RSVP' !== $ticket->provider_class;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Determine if the provided ticket object should be used when building
|
63 |
+
* sales counts.
|
64 |
+
*
|
65 |
+
* By default, tickets belonging to the Tribe__Tickets__RSVP provider
|
66 |
+
* are not to be counted.
|
67 |
+
*
|
68 |
+
* @since 4.7
|
69 |
+
*
|
70 |
+
* @param bool $should_count
|
71 |
+
* @param \Tribe__Tickets__Ticket_Object $ticket
|
72 |
+
*/
|
73 |
+
return (bool) apply_filters( 'tribe_tickets_should_use_ticket_in_sales_counts', $should_count, $ticket );
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Prints an HTML (unordered) list of attendance totals.
|
78 |
+
*
|
79 |
+
* @since 4.7
|
80 |
+
* @since 4.10.9 Use customizable ticket name functions.
|
81 |
+
*/
|
82 |
+
public function print_totals() {
|
83 |
+
$args = [
|
84 |
+
'total_sold_label' => esc_html( sprintf( _x( 'Total %s:', 'attendee summary', 'event-tickets' ), tribe_get_ticket_label_plural( 'total_sold_label' ) ) ),
|
85 |
+
'total_complete_label' => _x( 'Complete:', 'attendee summary', 'event-tickets' ),
|
86 |
+
'total_cancelled_label' => _x( 'Cancelled:', 'attendee summary', 'event-tickets' ),
|
87 |
+
'total_sold' => $this->get_total_sold(),
|
88 |
+
'total_complete' => $this->get_total_complete(),
|
89 |
+
'total_cancelled' => $this->get_total_cancelled(),
|
90 |
+
'total_refunded' => $this->get_total_refunded(),
|
91 |
+
'total_sold_tooltip' => $this->get_total_sold_tooltip(),
|
92 |
+
'total_completed_tooltip' => $this->get_total_completed_tooltip(),
|
93 |
+
'total_cancelled_tooltip' => $this->get_total_cancelled_tooltip(),
|
94 |
+
'total_refunded_tooltip' => $this->get_total_refunded_tooltip(),
|
95 |
+
];
|
96 |
+
|
97 |
+
tribe( 'tickets.admin.views' )->template( 'attendees-totals-list', $args, true );
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Avoid rendering the total if ET+ is active as this is added by Tribe__Tickets_Plus__Commerce__Attendance_Totals
|
102 |
+
* otherwise go with regular flow provided by the parent.
|
103 |
+
*
|
104 |
+
* @since 4.7.1
|
105 |
+
*/
|
106 |
+
public function integrate_with_attendee_screen() {
|
107 |
+
if ( class_exists( 'Tribe__Tickets_Plus__Commerce__Attendance_Totals' ) ) {
|
108 |
+
return;
|
109 |
+
}
|
110 |
+
|
111 |
+
parent::integrate_with_attendee_screen();
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* The total number of tickets sold for this event.
|
116 |
+
*
|
117 |
+
* @since 4.7
|
118 |
+
*
|
119 |
+
* @return int
|
120 |
+
*/
|
121 |
+
public function get_total_sold() {
|
122 |
+
$total_sold = $this->get_total_paid() + $this->get_total_pending();
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Returns the total tickets sold for an event.
|
126 |
+
*
|
127 |
+
* @since 4.7
|
128 |
+
*
|
129 |
+
* @param int $total_sold Total number of tickets sold.
|
130 |
+
* @param int $original_total_sold Original total number of tickets sold.
|
131 |
+
* @param int $event_id Event ID.
|
132 |
+
*/
|
133 |
+
return (int) apply_filters( 'tribe_tickets_get_total_sold', $total_sold, $total_sold, $this->event_id );
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* The total number of tickets pending further action for this event.
|
138 |
+
*
|
139 |
+
* @since 4.7
|
140 |
+
*
|
141 |
+
* @return int
|
142 |
+
*/
|
143 |
+
public function get_total_pending() {
|
144 |
+
/**
|
145 |
+
* Returns the total tickets pending further action for an event.
|
146 |
+
*
|
147 |
+
* @since 4.7
|
148 |
+
*
|
149 |
+
* @param int $total_pending Total number of tickets pending.
|
150 |
+
* @param int $original_total_pending Original total number of tickets pending.
|
151 |
+
* @param int $event_id Event ID.
|
152 |
+
*/
|
153 |
+
return (int) apply_filters( 'tribe_tickets_get_total_pending', $this->total_pending, $this->total_pending, $this->event_id );
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* The total number of tickets sold and paid for, minus cancelled and refunded, for this event.
|
158 |
+
*
|
159 |
+
* @since 4.7
|
160 |
+
*
|
161 |
+
* @return int
|
162 |
+
*/
|
163 |
+
public function get_total_complete() {
|
164 |
+
$total_complete = $this->get_total_paid() - $this->get_total_cancelled() - $this->get_total_refunded();
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Returns the total tickets completed for an event.
|
168 |
+
*
|
169 |
+
* @since 4.10.8
|
170 |
+
*
|
171 |
+
* @param int $total_complete Total number of tickets completed.
|
172 |
+
* @param int $original_total_complete Original total number of tickets completed.
|
173 |
+
* @param int $event_id Event ID.
|
174 |
+
*/
|
175 |
+
return (int) apply_filters( 'tribe_tickets_get_total_complete', $total_complete, $total_complete, $this->event_id );
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* The total number of tickets sold and paid for, for this event.
|
180 |
+
*
|
181 |
+
* @since 4.6
|
182 |
+
*
|
183 |
+
* @return int
|
184 |
+
*/
|
185 |
+
public function get_total_paid() {
|
186 |
+
/**
|
187 |
+
* Returns the total tickets sold and paid for, for an event.
|
188 |
+
*
|
189 |
+
* @since 4.7
|
190 |
+
*
|
191 |
+
* @param int $total_paid Total number of tickets paid.
|
192 |
+
* @param int $original_total_paid Original total number of tickets paid.
|
193 |
+
* @param int $event_id Event ID.
|
194 |
+
*/
|
195 |
+
return (int) apply_filters( 'tribe_tickets_get_total_paid', $this->total_paid, $this->total_paid, $this->event_id );
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* The total number of tickets sold then cancelled, for this event.
|
200 |
+
*
|
201 |
+
* @since 4.10.5
|
202 |
+
*
|
203 |
+
* @return int
|
204 |
+
*/
|
205 |
+
public function get_total_cancelled() {
|
206 |
+
/**
|
207 |
+
* Returns the total tickets cancelled, for an event.
|
208 |
+
*
|
209 |
+
* @since 4.10.5
|
210 |
+
*
|
211 |
+
* @param int $total_cancelled Total number of tickets cancelled.
|
212 |
+
* @param int $original_total_cancelled Original total number of tickets cancelled.
|
213 |
+
* @param int $event_id Event ID.
|
214 |
+
*/
|
215 |
+
return (int) apply_filters( 'tribe_tickets_plus_get_total_cancelled', $this->total_cancelled, $this->total_cancelled, $this->event_id );
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* The total number of tickets sold then refunded, for this event.
|
220 |
+
*
|
221 |
+
* @since 4.10.8
|
222 |
+
*
|
223 |
+
* @return int Total number of tickets refunded.
|
224 |
+
*/
|
225 |
+
public function get_total_refunded() {
|
226 |
+
/**
|
227 |
+
* Returns the total tickets refunded, for an event.
|
228 |
+
*
|
229 |
+
* @since 4.10.8
|
230 |
+
*
|
231 |
+
* @param int $total_refunded Total number of tickets refunded.
|
232 |
+
* @param int $original_total_refunded Original total number of tickets refunded.
|
233 |
+
* @param int $event_id Event ID.
|
234 |
+
*/
|
235 |
+
return (int) apply_filters( 'tribe_tickets_get_total_refunded', $this->total_refunded, $this->total_refunded, $this->event_id );
|
236 |
+
}
|
237 |
+
}
|
src/Tickets/Commerce/Reports/Event.php
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Reports;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Module;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Event Report management.
|
9 |
+
*
|
10 |
+
* @since 5.1.9
|
11 |
+
*
|
12 |
+
* @package TEC\Tickets\Commerce\Reports
|
13 |
+
*/
|
14 |
+
class Event {
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Links to sales report for all tickets for this event.
|
19 |
+
*
|
20 |
+
* @since 5.1.9
|
21 |
+
*
|
22 |
+
* @param int $event_id
|
23 |
+
* @param bool $url_only
|
24 |
+
*
|
25 |
+
* @return string
|
26 |
+
*/
|
27 |
+
public function get_link( $event_id, $url_only = false ) {
|
28 |
+
$ticket_ids = (array) tribe( Module::class )->get_tickets_ids( $event_id );
|
29 |
+
if ( empty( $ticket_ids ) ) {
|
30 |
+
return '';
|
31 |
+
}
|
32 |
+
|
33 |
+
$query = array(
|
34 |
+
'page' => 'tpp-orders',
|
35 |
+
'post_id' => $event_id,
|
36 |
+
);
|
37 |
+
|
38 |
+
$report_url = add_query_arg( $query, admin_url( 'admin.php' ) );
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Filter the PayPal Ticket Orders (Sales) Report URL
|
42 |
+
*
|
43 |
+
* @var string $report_url Report URL
|
44 |
+
* @var int $event_id The post ID
|
45 |
+
* @var array $ticket_ids An array of ticket IDs
|
46 |
+
*
|
47 |
+
* @return string
|
48 |
+
*/
|
49 |
+
$report_url = apply_filters( 'tribe_tickets_paypal_report_url', $report_url, $event_id, $ticket_ids );
|
50 |
+
|
51 |
+
return $url_only
|
52 |
+
? $report_url
|
53 |
+
: '<small> <a href="' . esc_url( $report_url ) . '">' . esc_html__( 'Sales report', 'event-tickets' ) . '</a> </small>';
|
54 |
+
}
|
55 |
+
}
|
src/Tickets/Commerce/Reports/Ticket.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Reports;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Ticket Report management.
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce\Reports
|
11 |
+
*/
|
12 |
+
class Ticket {
|
13 |
+
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Links to the sales report for this product.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @param $event_id
|
21 |
+
* @param $ticket_id
|
22 |
+
*
|
23 |
+
* @return string
|
24 |
+
*/
|
25 |
+
public function get_link( $event_id, $ticket_id ) {
|
26 |
+
if ( empty( $ticket_id ) ) {
|
27 |
+
return '';
|
28 |
+
}
|
29 |
+
|
30 |
+
$query = array(
|
31 |
+
'page' => 'tpp-orders',
|
32 |
+
'product_ids' => $ticket_id,
|
33 |
+
'post_id' => $event_id,
|
34 |
+
);
|
35 |
+
|
36 |
+
$report_url = add_query_arg( $query, admin_url( 'admin.php' ) );
|
37 |
+
|
38 |
+
return '<span><a href="' . esc_url( $report_url ) . '">' . esc_html__( 'Report', 'event-tickets' ) . '</a></span>';
|
39 |
+
}
|
40 |
+
}
|
src/Tickets/Commerce/Repositories/Attendees_Repository.php
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Repositories;
|
4 |
+
|
5 |
+
|
6 |
+
use TEC\Tickets\Commerce;
|
7 |
+
use TEC\Tickets\Commerce\Module;
|
8 |
+
use \Tribe__Repository;
|
9 |
+
use TEC\Tickets\Commerce\Attendee;
|
10 |
+
use Tribe__Repository__Usage_Error as Usage_Error;
|
11 |
+
|
12 |
+
use Tribe__Utils__Array as Arr;
|
13 |
+
use Tribe__Date_Utils as Dates;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Class Attendees Repository.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @package TEC\Tickets\Commerce\Repositories
|
21 |
+
*/
|
22 |
+
class Attendees_Repository extends Tribe__Repository {
|
23 |
+
/**
|
24 |
+
* The unique fragment that will be used to identify this repository filters.
|
25 |
+
*
|
26 |
+
* @since 5.1.9
|
27 |
+
*
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
protected $filter_name = 'tc_attendees';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Key name to use when limiting lists of keys.
|
34 |
+
*
|
35 |
+
* @since 5.1.9
|
36 |
+
*
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
protected $key_name = \TEC\Tickets\Commerce::ABBR;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* {@inheritdoc}
|
43 |
+
*/
|
44 |
+
public function __construct() {
|
45 |
+
parent::__construct();
|
46 |
+
|
47 |
+
// Set the order post type.
|
48 |
+
$this->default_args['post_type'] = Attendee::POSTTYPE;
|
49 |
+
$this->default_args['post_status'] = 'publish';
|
50 |
+
$this->create_args['post_status'] = 'publish';
|
51 |
+
$this->create_args['post_type'] = Attendee::POSTTYPE;
|
52 |
+
|
53 |
+
// Add event specific aliases.
|
54 |
+
$this->update_fields_aliases = array_merge(
|
55 |
+
$this->update_fields_aliases,
|
56 |
+
[
|
57 |
+
'order_id' => 'post_parent',
|
58 |
+
'ticket_id' => Attendee::$ticket_relation_meta_key,
|
59 |
+
'event_id' => Attendee::$event_relation_meta_key,
|
60 |
+
'security_code' => Attendee::$security_code_meta_key,
|
61 |
+
'opt_out' => Attendee::$optout_meta_key,
|
62 |
+
'checked_in' => Attendee::$checked_in_meta_key,
|
63 |
+
'first_name' => Attendee::$first_name_meta_key,
|
64 |
+
'last_name' => Attendee::$last_name_meta_key,
|
65 |
+
'email' => Attendee::$email_meta_key,
|
66 |
+
'is_deleted_ticket' => Attendee::$deleted_ticket_meta_key,
|
67 |
+
'ticket_sent' => Attendee::$ticket_sent_meta_key,
|
68 |
+
'is_subscribed' => Attendee::$subscribed_meta_key,
|
69 |
+
]
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* {@inheritDoc}
|
75 |
+
*/
|
76 |
+
protected function format_item( $id ) {
|
77 |
+
$formatted = null === $this->formatter
|
78 |
+
? tec_tc_get_attendee( $id )
|
79 |
+
: $this->formatter->format_item( $id );
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Filters a single formatted attendee result.
|
83 |
+
*
|
84 |
+
* @since 5.1.9
|
85 |
+
*
|
86 |
+
* @param mixed|\WP_Post $formatted The formatted event result, usually a post object.
|
87 |
+
* @param int $id The formatted post ID.
|
88 |
+
* @param \Tribe__Repository__Interface $this The current repository object.
|
89 |
+
*/
|
90 |
+
$formatted = apply_filters( 'tec_tickets_commerce_repository_attendee_format', $formatted, $id, $this );
|
91 |
+
|
92 |
+
return $formatted;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* {@inheritdoc}
|
97 |
+
*/
|
98 |
+
public function filter_postarr_for_create( array $postarr ) {
|
99 |
+
if ( isset( $postarr['meta_input'] ) ) {
|
100 |
+
$postarr = $this->filter_meta_input( $postarr );
|
101 |
+
}
|
102 |
+
|
103 |
+
return parent::filter_postarr_for_create( $postarr );
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* {@inheritdoc}
|
108 |
+
*/
|
109 |
+
public function filter_postarr_for_update( array $postarr, $post_id ) {
|
110 |
+
if ( isset( $postarr['meta_input'] ) ) {
|
111 |
+
$postarr = $this->filter_meta_input( $postarr, $post_id );
|
112 |
+
}
|
113 |
+
|
114 |
+
return parent::filter_postarr_for_update( $postarr, $post_id );
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Filters and updates the order meta to make sure it makes sense.
|
119 |
+
*
|
120 |
+
* @since 5.1.9
|
121 |
+
*
|
122 |
+
* @param array $postarr The update post array, passed entirely for context purposes.
|
123 |
+
* @param int $post_id The ID of the event that's being updated.
|
124 |
+
*
|
125 |
+
* @return array The filtered postarr array.
|
126 |
+
*/
|
127 |
+
protected function filter_meta_input( array $postarr, $post_id = null ) {
|
128 |
+
// if ( ! empty( $postarr['meta_input']['purchaser'] ) ) {
|
129 |
+
// $postarr = $this->filter_purchaser_input( $postarr, $post_id );
|
130 |
+
// }
|
131 |
+
|
132 |
+
return $postarr;
|
133 |
+
}
|
134 |
+
}
|
src/Tickets/Commerce/Repositories/Order_Repository.php
ADDED
@@ -0,0 +1,486 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Repositories;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce;
|
6 |
+
use TEC\Tickets\Commerce\Module;
|
7 |
+
use \Tribe__Repository;
|
8 |
+
use TEC\Tickets\Commerce\Order;
|
9 |
+
use Tribe__Repository__Usage_Error as Usage_Error;
|
10 |
+
|
11 |
+
use Tribe__Utils__Array as Arr;
|
12 |
+
use Tribe__Date_Utils as Dates;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class Order
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*/
|
19 |
+
class Order_Repository extends Tribe__Repository {
|
20 |
+
/**
|
21 |
+
* The unique fragment that will be used to identify this repository filters.
|
22 |
+
*
|
23 |
+
* @since 5.1.9
|
24 |
+
*
|
25 |
+
* @var string
|
26 |
+
*/
|
27 |
+
protected $filter_name = 'tc_orders';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Key name to use when limiting lists of keys.
|
31 |
+
*
|
32 |
+
* @since 5.1.9
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
protected $key_name = \TEC\Tickets\Commerce::ABBR;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* {@inheritdoc}
|
40 |
+
*/
|
41 |
+
public function __construct() {
|
42 |
+
parent::__construct();
|
43 |
+
|
44 |
+
$insert_status = tribe( Commerce\Status\Status_Handler::class )->get_insert_status();
|
45 |
+
|
46 |
+
// Set the order post type.
|
47 |
+
$this->default_args['post_type'] = Order::POSTTYPE;
|
48 |
+
$this->default_args['post_status'] = $insert_status->get_wp_slug();
|
49 |
+
$this->create_args['post_status'] = $insert_status->get_wp_slug();
|
50 |
+
$this->create_args['post_type'] = Order::POSTTYPE;
|
51 |
+
$this->create_args['currency'] = tribe_get_option( Commerce\Settings::$option_currency_code, 'USD' );
|
52 |
+
|
53 |
+
// Add event specific aliases.
|
54 |
+
$this->update_fields_aliases = array_merge(
|
55 |
+
$this->update_fields_aliases,
|
56 |
+
[
|
57 |
+
'gateway' => Order::$gateway_meta_key,
|
58 |
+
'gateway_order_id' => Order::$gateway_order_id_meta_key,
|
59 |
+
'cart_items' => Order::$cart_items_meta_key,
|
60 |
+
'total_value' => Order::$total_value_meta_key,
|
61 |
+
'currency' => Order::$currency_meta_key,
|
62 |
+
'purchaser_full_name' => Order::$purchaser_full_name_meta_key,
|
63 |
+
'purchaser_first_name' => Order::$purchaser_first_name_meta_key,
|
64 |
+
'purchaser_last_name' => Order::$purchaser_last_name_meta_key,
|
65 |
+
'purchaser_email' => Order::$purchaser_email_meta_key,
|
66 |
+
]
|
67 |
+
);
|
68 |
+
|
69 |
+
$this->schema = array_merge(
|
70 |
+
$this->schema,
|
71 |
+
[
|
72 |
+
'tickets' => [ $this, 'filter_by_tickets' ],
|
73 |
+
'tickets_not' => [ $this, 'filter_by_tickets_not' ],
|
74 |
+
'events' => [ $this, 'filter_by_events' ],
|
75 |
+
'events_not' => [ $this, 'filter_by_events_not' ],
|
76 |
+
]
|
77 |
+
);
|
78 |
+
|
79 |
+
$this->add_simple_meta_schema_entry( 'gateway', Order::$gateway_meta_key, 'meta_equals' );
|
80 |
+
$this->add_simple_meta_schema_entry( 'gateway_order_id', Order::$gateway_order_id_meta_key, 'meta_equals' );
|
81 |
+
$this->add_simple_meta_schema_entry( 'currency', Order::$currency_meta_key, 'meta_equals' );
|
82 |
+
$this->add_simple_meta_schema_entry( 'purchaser_full_name', Order::$purchaser_full_name_meta_key, 'meta_equals' );
|
83 |
+
$this->add_simple_meta_schema_entry( 'purchaser_first_name', Order::$purchaser_first_name_meta_key, 'meta_equals' );
|
84 |
+
$this->add_simple_meta_schema_entry( 'purchaser_last_name', Order::$purchaser_last_name_meta_key, 'meta_equals' );
|
85 |
+
$this->add_simple_meta_schema_entry( 'purchaser_email', Order::$purchaser_email_meta_key, 'meta_equals' );
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* {@inheritDoc}
|
90 |
+
*/
|
91 |
+
protected function format_item( $id ) {
|
92 |
+
$formatted = null === $this->formatter
|
93 |
+
? tec_tc_get_order( $id )
|
94 |
+
: $this->formatter->format_item( $id );
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Filters a single formatted order result.
|
98 |
+
*
|
99 |
+
* @since 5.1.9
|
100 |
+
*
|
101 |
+
* @param mixed|\WP_Post $formatted The formatted event result, usually a post object.
|
102 |
+
* @param int $id The formatted post ID.
|
103 |
+
* @param \Tribe__Repository__Interface $this The current repository object.
|
104 |
+
*/
|
105 |
+
$formatted = apply_filters( 'tec_tickets_commerce_repository_order_format', $formatted, $id, $this );
|
106 |
+
|
107 |
+
return $formatted;
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* {@inheritdoc}
|
112 |
+
*/
|
113 |
+
public function filter_postarr_for_create( array $postarr ) {
|
114 |
+
if ( isset( $postarr['meta_input'] ) ) {
|
115 |
+
$postarr = $this->filter_meta_input( $postarr );
|
116 |
+
}
|
117 |
+
|
118 |
+
if ( ! empty( $postarr['gateway_payload'] ) ) {
|
119 |
+
$payload = $postarr['gateway_payload'];
|
120 |
+
unset( $postarr['gateway_payload'] );
|
121 |
+
|
122 |
+
$status = tribe( Commerce\Status\Status_Handler::class )->get_by_wp_slug( $this->create_args['post_status'] );
|
123 |
+
|
124 |
+
if ( $status ) {
|
125 |
+
$postarr['meta_input'][ Order::get_gateway_payload_meta_key( $status ) ] = $payload;
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
return parent::filter_postarr_for_create( $postarr );
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* {@inheritdoc}
|
134 |
+
*/
|
135 |
+
public function filter_postarr_for_update( array $postarr, $post_id ) {
|
136 |
+
if ( isset( $postarr['meta_input'] ) ) {
|
137 |
+
$postarr = $this->filter_meta_input( $postarr, $post_id );
|
138 |
+
}
|
139 |
+
|
140 |
+
if ( ! empty( $postarr['tickets_in_order'] ) ) {
|
141 |
+
$tickets = array_filter( array_unique( (array) $postarr['tickets_in_order'] ) );
|
142 |
+
unset( $postarr['tickets_in_order'] );
|
143 |
+
|
144 |
+
// Delete all of the previous ones when updating.
|
145 |
+
delete_post_meta( $post_id, Order::$tickets_in_order_meta_key );
|
146 |
+
|
147 |
+
foreach ( $tickets as $ticket_id ) {
|
148 |
+
add_post_meta( $post_id, Order::$tickets_in_order_meta_key, $ticket_id );
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
if ( ! empty( $postarr['events_in_order'] ) ) {
|
153 |
+
$events = array_filter( array_unique( (array) $postarr['events_in_order'] ) );
|
154 |
+
unset( $postarr['events_in_order'] );
|
155 |
+
|
156 |
+
// Delete all of the previous ones when updating.
|
157 |
+
delete_post_meta( $post_id, Order::$events_in_order_meta_key );
|
158 |
+
|
159 |
+
foreach ( $events as $event_id ) {
|
160 |
+
add_post_meta( $post_id, Order::$events_in_order_meta_key, $event_id );
|
161 |
+
}
|
162 |
+
}
|
163 |
+
|
164 |
+
if ( ! empty( $postarr['meta_input']['gateway_payload'] ) ) {
|
165 |
+
$payload = $postarr['meta_input']['gateway_payload'];
|
166 |
+
unset( $postarr['meta_input']['gateway_payload'] );
|
167 |
+
|
168 |
+
$status = tribe( Commerce\Status\Status_Handler::class )->get_by_wp_slug( $postarr['post_status'] );
|
169 |
+
|
170 |
+
if ( $status ) {
|
171 |
+
add_post_meta( $post_id, Order::get_gateway_payload_meta_key( $status ), $payload );
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
return parent::filter_postarr_for_update( $postarr, $post_id );
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* {@inheritDoc}
|
180 |
+
*/
|
181 |
+
protected function get_create_callback( array $postarr ) {
|
182 |
+
$callback = parent::get_create_callback( $postarr );
|
183 |
+
|
184 |
+
// only modify if the filters didn't change anything.
|
185 |
+
if ( 'wp_insert_post' === $callback ) {
|
186 |
+
$callback = [ $this, 'create_order_with_meta' ];
|
187 |
+
}
|
188 |
+
|
189 |
+
return $callback;
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* When creating an order via the repository there are two meta elements that need to be added using
|
194 |
+
* `add_post_meta` with the $unique param set to false.
|
195 |
+
*
|
196 |
+
* So we hijack the default create callback for this repository to allow for that behavior to exist.
|
197 |
+
*
|
198 |
+
* @since 5.1.9
|
199 |
+
*
|
200 |
+
* @param array $postarr The post array that will be used for the creation.
|
201 |
+
*
|
202 |
+
* @return int The Post ID.
|
203 |
+
*/
|
204 |
+
protected function create_order_with_meta( array $postarr ) {
|
205 |
+
$callback = parent::get_create_callback( $postarr );
|
206 |
+
|
207 |
+
$tickets = [];
|
208 |
+
if ( ! empty( $postarr['meta_input']['tickets_in_order'] ) ) {
|
209 |
+
$tickets = array_filter( array_unique( (array) $postarr['meta_input']['tickets_in_order'] ) );
|
210 |
+
unset( $postarr['meta_input']['tickets_in_order'] );
|
211 |
+
}
|
212 |
+
|
213 |
+
$events = [];
|
214 |
+
if ( ! empty( $postarr['meta_input']['events_in_order'] ) ) {
|
215 |
+
$events = array_filter( array_unique( (array) $postarr['meta_input']['events_in_order'] ) );
|
216 |
+
unset( $postarr['meta_input']['events_in_order'] );
|
217 |
+
}
|
218 |
+
|
219 |
+
$created = call_user_func( $callback, $postarr );
|
220 |
+
|
221 |
+
// Dont add in case we are dealing with a failed insertion.
|
222 |
+
if ( ! is_wp_error( $created ) ) {
|
223 |
+
foreach ( $events as $event_id ) {
|
224 |
+
add_post_meta( $created, Order::$events_in_order_meta_key, $event_id );
|
225 |
+
}
|
226 |
+
|
227 |
+
foreach ( $tickets as $ticket_id ) {
|
228 |
+
add_post_meta( $created, Order::$tickets_in_order_meta_key, $ticket_id );
|
229 |
+
}
|
230 |
+
}
|
231 |
+
|
232 |
+
return $created;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Filters the tickets data from the input so we can properly save the cart items.
|
237 |
+
*
|
238 |
+
* @since 5.1.9
|
239 |
+
*
|
240 |
+
* @param array $postarr Data set that needs filtering.
|
241 |
+
* @param null|int $post_id When we are dealing with an Update we have an ID here.
|
242 |
+
*
|
243 |
+
* @return array
|
244 |
+
*/
|
245 |
+
protected function filter_gateway_payload( $postarr, $post_id = null ) {
|
246 |
+
$meta = Arr::get( $postarr, 'meta_input', [] );
|
247 |
+
$items = Arr::get( $meta, 'gateway_payload', [] );
|
248 |
+
|
249 |
+
if ( ! empty( $items ) ) {
|
250 |
+
$statuses = tribe( Commerce\Status\Status_Handler::class )->get_all();
|
251 |
+
|
252 |
+
}
|
253 |
+
|
254 |
+
return $postarr;
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* Filters the tickets data from the input so we can properly save the cart items.
|
259 |
+
*
|
260 |
+
* @since 5.1.9
|
261 |
+
*
|
262 |
+
* @param array $postarr Data set that needs filtering.
|
263 |
+
* @param null|int $post_id When we are dealing with an Update we have an ID here.
|
264 |
+
*
|
265 |
+
* @return array
|
266 |
+
*/
|
267 |
+
protected function filter_cart_items_input( $postarr, $post_id = null ) {
|
268 |
+
$meta = Arr::get( $postarr, 'meta_input', [] );
|
269 |
+
$items = Arr::get( $meta, Order::$cart_items_meta_key, [] );
|
270 |
+
|
271 |
+
if ( ! empty( $items ) ) {
|
272 |
+
$ticket_ids = array_unique( array_filter( array_values( wp_list_pluck( $items, 'ticket_id' ) ) ) );
|
273 |
+
$event_objects = array_map( [ tribe( Module::class ), 'get_event_for_ticket' ], $ticket_ids );
|
274 |
+
$event_ids = array_unique( array_filter( array_values( wp_list_pluck( $event_objects, 'ID' ) ) ) );
|
275 |
+
|
276 |
+
// These will be remove right before actually creating the order.
|
277 |
+
$postarr['meta_input']['tickets_in_order'] = $ticket_ids;
|
278 |
+
$postarr['meta_input']['events_in_order'] = $event_ids;
|
279 |
+
}
|
280 |
+
|
281 |
+
return $postarr;
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Filters the Purchaser data from the input so we can properly save the data.
|
286 |
+
*
|
287 |
+
* @since 5.1.9
|
288 |
+
*
|
289 |
+
* @param array $postarr Data set that needs filtering.
|
290 |
+
* @param null|int $post_id When we are dealing with an Update we have an ID here.
|
291 |
+
*
|
292 |
+
* @return array
|
293 |
+
*/
|
294 |
+
protected function filter_purchaser_input( $postarr, $post_id = null ) {
|
295 |
+
$meta = Arr::get( $postarr, 'meta_input', [] );
|
296 |
+
$purchaser = Arr::get( $meta, 'purchaser', [] );
|
297 |
+
|
298 |
+
if ( is_numeric( $purchaser ) && $user = get_userdata( $purchaser ) ) {
|
299 |
+
$full_name = $user->display_name;
|
300 |
+
$first_name = $user->first_name;
|
301 |
+
$last_name = $user->last_name;
|
302 |
+
$email = $user->user_email;
|
303 |
+
} else {
|
304 |
+
$full_name = Arr::get( $purchaser, 'full_name' );
|
305 |
+
$first_name = Arr::get( $purchaser, 'first_name' );
|
306 |
+
$last_name = Arr::get( $purchaser, 'last_name' );
|
307 |
+
$email = Arr::get( $purchaser, 'email' );
|
308 |
+
}
|
309 |
+
|
310 |
+
// Maybe set the first / last name.
|
311 |
+
if ( empty( $first_name ) || empty( $last_name ) ) {
|
312 |
+
$first_name = $full_name;
|
313 |
+
$last_name = '';
|
314 |
+
|
315 |
+
// Get first name and last name.
|
316 |
+
if ( false !== strpos( $full_name, ' ' ) ) {
|
317 |
+
$name_parts = explode( ' ', $full_name );
|
318 |
+
|
319 |
+
// First name is first text.
|
320 |
+
$first_name = array_shift( $name_parts );
|
321 |
+
|
322 |
+
// Last name is everything the first text.
|
323 |
+
$last_name = implode( ' ', $name_parts );
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
+
$postarr['meta_input'][ Order::$purchaser_email_meta_key ] = $email;
|
328 |
+
$postarr['meta_input'][ Order::$purchaser_full_name_meta_key ] = $full_name;
|
329 |
+
$postarr['meta_input'][ Order::$purchaser_first_name_meta_key ] = $first_name;
|
330 |
+
$postarr['meta_input'][ Order::$purchaser_last_name_meta_key ] = $last_name;
|
331 |
+
|
332 |
+
unset( $postarr['meta_input']['purchaser'] );
|
333 |
+
|
334 |
+
return $postarr;
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Filters and updates the order meta to make sure it makes sense.
|
339 |
+
*
|
340 |
+
* @since 5.1.9
|
341 |
+
*
|
342 |
+
* @param array $postarr The update post array, passed entirely for context purposes.
|
343 |
+
* @param int $post_id The ID of the event that's being updated.
|
344 |
+
*
|
345 |
+
* @return array The filtered postarr array.
|
346 |
+
*/
|
347 |
+
protected function filter_meta_input( array $postarr, $post_id = null ) {
|
348 |
+
if ( ! empty( $postarr['meta_input']['purchaser'] ) ) {
|
349 |
+
$postarr = $this->filter_purchaser_input( $postarr, $post_id );
|
350 |
+
}
|
351 |
+
|
352 |
+
if ( ! empty( $postarr['meta_input']['gateway_payload'] ) ) {
|
353 |
+
$postarr = $this->filter_gateway_payload( $postarr, $post_id );
|
354 |
+
}
|
355 |
+
|
356 |
+
if ( ! empty( $postarr['meta_input'][ Order::$cart_items_meta_key ] ) ) {
|
357 |
+
$postarr = $this->filter_cart_items_input( $postarr, $post_id );
|
358 |
+
}
|
359 |
+
|
360 |
+
return $postarr;
|
361 |
+
}
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Cleans up a list of Post IDs into an usable array for DB query.
|
365 |
+
*
|
366 |
+
* @since 5.1.9
|
367 |
+
*
|
368 |
+
* @param int|\WP_Post|int[]|\WP_Post[] $posts Which posts we are filtering by.
|
369 |
+
*
|
370 |
+
* @return array
|
371 |
+
*/
|
372 |
+
protected function clean_post_ids( $posts ) {
|
373 |
+
return array_unique( array_filter( array_map( static function ( $post ) {
|
374 |
+
if ( is_numeric( $post ) ) {
|
375 |
+
return $post;
|
376 |
+
}
|
377 |
+
|
378 |
+
if ( $post instanceof \WP_Post ) {
|
379 |
+
return $post->ID;
|
380 |
+
}
|
381 |
+
|
382 |
+
return null;
|
383 |
+
}, (array) $posts ) ) );
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Filters order by whether or not it contains a given ticket/s.
|
388 |
+
*
|
389 |
+
* @since 5.1.9
|
390 |
+
*
|
391 |
+
* @param int|\WP_Post|int[]|\WP_Post[] $tickets Which tickets we are filtering by.
|
392 |
+
*
|
393 |
+
* @return null
|
394 |
+
*/
|
395 |
+
public function filter_by_tickets( $tickets = null ) {
|
396 |
+
if ( empty( $tickets ) ) {
|
397 |
+
return null;
|
398 |
+
}
|
399 |
+
|
400 |
+
$tickets = $this->clean_post_ids( $tickets );
|
401 |
+
|
402 |
+
if ( empty( $tickets ) ) {
|
403 |
+
return null;
|
404 |
+
}
|
405 |
+
|
406 |
+
$this->by( 'meta_in', Order::$tickets_in_order_meta_key, $tickets );
|
407 |
+
|
408 |
+
return null;
|
409 |
+
}
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Filters order by whether or not it contains a given ticket/s.
|
413 |
+
*
|
414 |
+
* @since 5.1.9
|
415 |
+
*
|
416 |
+
* @param int|\WP_Post|int[]|\WP_Post[] $tickets Which tickets we are filtering by.
|
417 |
+
*
|
418 |
+
* @return null
|
419 |
+
*/
|
420 |
+
public function filter_by_tickets_not( $tickets = null ) {
|
421 |
+
if ( empty( $tickets ) ) {
|
422 |
+
return null;
|
423 |
+
}
|
424 |
+
|
425 |
+
$tickets = $this->clean_post_ids( $tickets );
|
426 |
+
|
427 |
+
if ( empty( $tickets ) ) {
|
428 |
+
return null;
|
429 |
+
}
|
430 |
+
|
431 |
+
$this->by( 'meta_not_in', Order::$tickets_in_order_meta_key, $tickets );
|
432 |
+
|
433 |
+
return null;
|
434 |
+
}
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Filters order by whether or not it contains a given ticket/s.
|
438 |
+
*
|
439 |
+
* @since 5.1.9
|
440 |
+
*
|
441 |
+
* @param int|\WP_Post|int[]|\WP_Post[] $events Which events we are filtering by.
|
442 |
+
*
|
443 |
+
* @return null
|
444 |
+
*/
|
445 |
+
public function filter_by_events( $events = null ) {
|
446 |
+
if ( empty( $events ) ) {
|
447 |
+
return null;
|
448 |
+
}
|
449 |
+
|
450 |
+
$events = $this->clean_post_ids( $events );
|
451 |
+
|
452 |
+
if ( empty( $events ) ) {
|
453 |
+
return null;
|
454 |
+
}
|
455 |
+
|
456 |
+
$this->by( 'meta_in', Order::$events_in_order_meta_key, $events );
|
457 |
+
|
458 |
+
return null;
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Filters order by whether or not it contains a given event/s.
|
463 |
+
*
|
464 |
+
* @since 5.1.9
|
465 |
+
*
|
466 |
+
* @param int|\WP_Post|int[]|\WP_Post[] $events Which events we are filtering by.
|
467 |
+
*
|
468 |
+
* @return null
|
469 |
+
*/
|
470 |
+
public function filter_by_events_not( $events = null ) {
|
471 |
+
if ( empty( $events ) ) {
|
472 |
+
return null;
|
473 |
+
}
|
474 |
+
|
475 |
+
$events = $this->clean_post_ids( $events );
|
476 |
+
|
477 |
+
if ( empty( $events ) ) {
|
478 |
+
return null;
|
479 |
+
}
|
480 |
+
|
481 |
+
$this->by( 'meta_not_in', Order::$events_in_order_meta_key, $events );
|
482 |
+
|
483 |
+
return null;
|
484 |
+
}
|
485 |
+
|
486 |
+
}
|
src/Tickets/Commerce/Repositories/Tickets_Repository.php
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Repositories;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce;
|
6 |
+
use TEC\Tickets\Commerce\Module;
|
7 |
+
use \Tribe__Repository;
|
8 |
+
use TEC\Tickets\Commerce\Ticket;
|
9 |
+
use Tribe__Repository__Usage_Error as Usage_Error;
|
10 |
+
|
11 |
+
use Tribe__Utils__Array as Arr;
|
12 |
+
use Tribe__Date_Utils as Dates;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class Tickets Repository.
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*
|
19 |
+
* @package TEC\Tickets\Commerce\Repositories
|
20 |
+
*/
|
21 |
+
class Tickets_Repository extends Tribe__Repository {
|
22 |
+
/**
|
23 |
+
* The unique fragment that will be used to identify this repository filters.
|
24 |
+
*
|
25 |
+
* @since 5.1.9
|
26 |
+
*
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
protected $filter_name = 'tc_tickets';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Key name to use when limiting lists of keys.
|
33 |
+
*
|
34 |
+
* @since 5.1.9
|
35 |
+
*
|
36 |
+
* @var string
|
37 |
+
*/
|
38 |
+
protected $key_name = \TEC\Tickets\Commerce::ABBR;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* {@inheritdoc}
|
42 |
+
*/
|
43 |
+
public function __construct() {
|
44 |
+
parent::__construct();
|
45 |
+
|
46 |
+
// Set the order post type.
|
47 |
+
$this->default_args['post_type'] = Ticket::POSTTYPE;
|
48 |
+
$this->default_args['post_status'] = 'publish';
|
49 |
+
$this->create_args['post_status'] = 'publish';
|
50 |
+
$this->create_args['post_type'] = Ticket::POSTTYPE;
|
51 |
+
|
52 |
+
// Add event specific aliases.
|
53 |
+
$this->update_fields_aliases = array_merge(
|
54 |
+
$this->update_fields_aliases,
|
55 |
+
[
|
56 |
+
'event' => Ticket::$event_relation_meta_key,
|
57 |
+
'show_description' => Ticket::$show_description_meta_key,
|
58 |
+
'price' => Ticket::$price_meta_key,
|
59 |
+
]
|
60 |
+
);
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* {@inheritDoc}
|
65 |
+
*/
|
66 |
+
protected function format_item( $id ) {
|
67 |
+
$formatted = null === $this->formatter
|
68 |
+
? tec_tc_get_ticket( $id )
|
69 |
+
: $this->formatter->format_item( $id );
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Filters a single formatted ticket result.
|
73 |
+
*
|
74 |
+
* @since 5.1.9
|
75 |
+
*
|
76 |
+
* @param mixed|\WP_Post $formatted The formatted event result, usually a post object.
|
77 |
+
* @param int $id The formatted post ID.
|
78 |
+
* @param \Tribe__Repository__Interface $this The current repository object.
|
79 |
+
*/
|
80 |
+
$formatted = apply_filters( 'tec_tickets_commerce_repository_ticket_format', $formatted, $id, $this );
|
81 |
+
|
82 |
+
return $formatted;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* {@inheritdoc}
|
87 |
+
*/
|
88 |
+
public function filter_postarr_for_create( array $postarr ) {
|
89 |
+
if ( isset( $postarr['meta_input'] ) ) {
|
90 |
+
$postarr = $this->filter_meta_input( $postarr );
|
91 |
+
}
|
92 |
+
|
93 |
+
return parent::filter_postarr_for_create( $postarr );
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* {@inheritdoc}
|
98 |
+
*/
|
99 |
+
public function filter_postarr_for_update( array $postarr, $post_id ) {
|
100 |
+
if ( isset( $postarr['meta_input'] ) ) {
|
101 |
+
$postarr = $this->filter_meta_input( $postarr, $post_id );
|
102 |
+
}
|
103 |
+
|
104 |
+
return parent::filter_postarr_for_update( $postarr, $post_id );
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Filters and updates the order meta to make sure it makes sense.
|
109 |
+
*
|
110 |
+
* @since 5.1.9
|
111 |
+
*
|
112 |
+
* @param array $postarr The update post array, passed entirely for context purposes.
|
113 |
+
* @param int $post_id The ID of the event that's being updated.
|
114 |
+
*
|
115 |
+
* @return array The filtered postarr array.
|
116 |
+
*/
|
117 |
+
protected function filter_meta_input( array $postarr, $post_id = null ) {
|
118 |
+
// if ( ! empty( $postarr['meta_input']['purchaser'] ) ) {
|
119 |
+
// $postarr = $this->filter_purchaser_input( $postarr, $post_id );
|
120 |
+
// }
|
121 |
+
|
122 |
+
return $postarr;
|
123 |
+
}
|
124 |
+
}
|
src/Tickets/Commerce/Settings.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
*
|
4 |
-
* @since
|
5 |
*
|
6 |
* @package TEC\Tickets\Commerce
|
7 |
*/
|
@@ -30,7 +30,7 @@ class Settings extends Abstract_Settings {
|
|
30 |
*
|
31 |
* @var string
|
32 |
*/
|
33 |
-
public $option_enable = 'tickets-commerce-enable';
|
34 |
|
35 |
/**
|
36 |
* The option key for sandbox.
|
@@ -39,7 +39,7 @@ class Settings extends Abstract_Settings {
|
|
39 |
*
|
40 |
* @var string
|
41 |
*/
|
42 |
-
public $option_sandbox = '
|
43 |
|
44 |
/**
|
45 |
* The option key for currency code.
|
@@ -48,7 +48,7 @@ class Settings extends Abstract_Settings {
|
|
48 |
*
|
49 |
* @var string
|
50 |
*/
|
51 |
-
public $option_currency_code = '
|
52 |
|
53 |
/**
|
54 |
* The option key for stock handling.
|
@@ -57,7 +57,7 @@ class Settings extends Abstract_Settings {
|
|
57 |
*
|
58 |
* @var string
|
59 |
*/
|
60 |
-
public $option_stock_handling = '
|
61 |
|
62 |
/**
|
63 |
* The option key for success page.
|
@@ -66,7 +66,7 @@ class Settings extends Abstract_Settings {
|
|
66 |
*
|
67 |
* @var string
|
68 |
*/
|
69 |
-
public $option_success_page = '
|
70 |
|
71 |
/**
|
72 |
* The option key for checkout page.
|
@@ -75,7 +75,7 @@ class Settings extends Abstract_Settings {
|
|
75 |
*
|
76 |
* @var string
|
77 |
*/
|
78 |
-
public $option_checkout_page = 'tickets-commerce-checkout-page';
|
79 |
|
80 |
/**
|
81 |
* The option key for confirmation email sender email.
|
@@ -84,7 +84,7 @@ class Settings extends Abstract_Settings {
|
|
84 |
*
|
85 |
* @var string
|
86 |
*/
|
87 |
-
public $option_confirmation_email_sender_email = '
|
88 |
|
89 |
/**
|
90 |
* The option key for confirmation email sender name.
|
@@ -93,7 +93,7 @@ class Settings extends Abstract_Settings {
|
|
93 |
*
|
94 |
* @var string
|
95 |
*/
|
96 |
-
public $option_confirmation_email_sender_name = '
|
97 |
|
98 |
/**
|
99 |
* The option key for confirmation email subject.
|
@@ -102,16 +102,33 @@ class Settings extends Abstract_Settings {
|
|
102 |
*
|
103 |
* @var string
|
104 |
*/
|
105 |
-
public $option_confirmation_email_subject = '
|
106 |
|
107 |
/**
|
108 |
-
*
|
109 |
*
|
110 |
-
* @since 5.1.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
*
|
112 |
-
* @
|
|
|
|
|
|
|
113 |
*/
|
114 |
-
public function
|
|
|
115 |
$plus_link = sprintf(
|
116 |
'<a href="https://evnt.is/19zl" target="_blank" rel="noopener noreferrer">%s</a>',
|
117 |
esc_html__( 'Event Tickets Plus', 'event-tickets' )
|
@@ -121,13 +138,51 @@ class Settings extends Abstract_Settings {
|
|
121 |
esc_html__( 'Check it out!', 'event-tickets' )
|
122 |
);
|
123 |
$plus_message = sprintf(
|
124 |
-
|
125 |
esc_html_x( 'Tickets Commerce is a light implementation of a commerce gateway using PayPal and simplified stock handling. If you need more advanced features, take a look at %1$s. In addition to integrating with your favorite ecommerce provider, Event Tickets Plus includes options to collect custom information for attendees, check users in via QR codes, and share stock between %2$s. %3$s', 'about Tickets Commerce', 'event-tickets' ),
|
126 |
$plus_link,
|
127 |
esc_html( tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_about_tribe_commerce' ) ),
|
128 |
$plus_link_2
|
129 |
);
|
130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
// @todo Replace this with a better and more performant REST API based solution.
|
132 |
$page_args = [
|
133 |
'post_status' => 'publish',
|
@@ -143,8 +198,8 @@ class Settings extends Abstract_Settings {
|
|
143 |
// Add an initial empty selection to the start.
|
144 |
$pages = [ 0 => __( '-- No page set --', 'event-tickets' ) ] + $pages;
|
145 |
|
146 |
-
$
|
147 |
-
$
|
148 |
|
149 |
/** @var \Tribe__Tickets__Commerce__Currency $commerce_currency */
|
150 |
$commerce_currency = tribe( 'tickets.commerce.currency' );
|
@@ -153,40 +208,15 @@ class Settings extends Abstract_Settings {
|
|
153 |
|
154 |
$current_user = get_user_by( 'id', get_current_user_id() );
|
155 |
|
156 |
-
// @todo Fill this out and make it check if PayPal Legacy was previously active.
|
157 |
-
$is_tickets_commerce_enabled = false;
|
158 |
-
|
159 |
-
$top_level_settings = [
|
160 |
-
'tickets-commerce-heading' => [
|
161 |
-
'type' => 'html',
|
162 |
-
'html' => '<h3>' . __( 'Tickets Commerce', 'event-tickets' ) . '</h3>',
|
163 |
-
],
|
164 |
-
'tickets-commerce-et-plus-header' => [
|
165 |
-
'type' => 'html',
|
166 |
-
'html' => '<p>' . $plus_message . '</p>',
|
167 |
-
],
|
168 |
-
$this->option_enable => [
|
169 |
-
'type' => 'checkbox_bool',
|
170 |
-
'label' => esc_html__( 'Enable Tickets Commerce', 'event-tickets' ),
|
171 |
-
'tooltip' => esc_html__( 'Check this box if you wish to turn on Tickets Commerce functionality.', 'event-tickets' ),
|
172 |
-
'size' => 'medium',
|
173 |
-
'default' => $is_tickets_commerce_enabled,
|
174 |
-
'validation_type' => 'boolean',
|
175 |
-
'attributes' => [
|
176 |
-
'id' => $this->option_enable . '-input',
|
177 |
-
],
|
178 |
-
],
|
179 |
-
];
|
180 |
-
|
181 |
$settings = [
|
182 |
-
|
183 |
'type' => 'checkbox_bool',
|
184 |
'label' => esc_html__( 'Enable Test Mode', 'event-tickets' ),
|
185 |
'tooltip' => esc_html__( 'Enables Test mode for testing payments. Any payments made will be done on "sandbox" accounts.', 'event-tickets' ),
|
186 |
'default' => false,
|
187 |
'validation_type' => 'boolean',
|
188 |
],
|
189 |
-
|
190 |
'type' => 'dropdown',
|
191 |
'label' => esc_html__( 'Currency Code', 'event-tickets' ),
|
192 |
'tooltip' => esc_html__( 'The currency that will be used for Tickets Commerce transactions.', 'event-tickets' ),
|
@@ -194,12 +224,12 @@ class Settings extends Abstract_Settings {
|
|
194 |
'validation_type' => 'options',
|
195 |
'options' => $paypal_currency_code_options,
|
196 |
],
|
197 |
-
|
198 |
'type' => 'radio',
|
199 |
'label' => esc_html__( 'Stock Handling', 'event-tickets' ),
|
200 |
'tooltip' => esc_html(
|
201 |
sprintf(
|
202 |
-
|
203 |
_x( 'When a customer purchases a %s, the payment gateway might flag the order as Pending. The order will be Complete once payment is confirmed by the payment gateway.', 'tickets fields settings paypal stock handling', 'event-tickets' ),
|
204 |
tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_stock_handling' )
|
205 |
)
|
@@ -208,26 +238,26 @@ class Settings extends Abstract_Settings {
|
|
208 |
'validation_type' => 'options',
|
209 |
'options' => [
|
210 |
'on-pending' => sprintf(
|
211 |
-
|
212 |
esc_html__( 'Decrease available %s stock as soon as a Pending order is created.', 'event-tickets' ),
|
213 |
tribe_get_ticket_label_singular_lowercase( 'stock_handling' )
|
214 |
),
|
215 |
'on-complete' => sprintf(
|
216 |
-
|
217 |
esc_html__( 'Only decrease available %s stock if an order is confirmed as Completed by the payment gateway.', 'event-tickets' ),
|
218 |
tribe_get_ticket_label_singular_lowercase( 'stock_handling' )
|
219 |
),
|
220 |
],
|
221 |
'tooltip_first' => true,
|
222 |
],
|
223 |
-
|
224 |
'type' => 'dropdown',
|
225 |
'label' => esc_html__( 'Checkout page', 'event-tickets' ),
|
226 |
'tooltip' => esc_html(
|
227 |
sprintf(
|
228 |
-
|
229 |
__( 'This is the page where customers go to complete their purchase. Use the %s shortcode to display the checkout experience in the page content.', 'event-tickets' ),
|
230 |
-
"[$
|
231 |
)
|
232 |
),
|
233 |
'size' => 'medium',
|
@@ -235,14 +265,14 @@ class Settings extends Abstract_Settings {
|
|
235 |
'options' => $pages,
|
236 |
'required' => true,
|
237 |
],
|
238 |
-
|
239 |
'type' => 'dropdown',
|
240 |
'label' => esc_html__( 'Success page', 'event-tickets' ),
|
241 |
'tooltip' => esc_html(
|
242 |
sprintf(
|
243 |
-
|
244 |
__( 'After a successful order, users will be redirected to this page. Use the %s shortcode to display the order confirmation to the user in the page content.', 'event-tickets' ),
|
245 |
-
"[$
|
246 |
)
|
247 |
),
|
248 |
'size' => 'medium',
|
@@ -250,12 +280,12 @@ class Settings extends Abstract_Settings {
|
|
250 |
'options' => $pages,
|
251 |
'required' => true,
|
252 |
],
|
253 |
-
|
254 |
'type' => 'email',
|
255 |
'label' => esc_html__( 'Confirmation email sender address', 'event-tickets' ),
|
256 |
'tooltip' => esc_html(
|
257 |
sprintf(
|
258 |
-
|
259 |
_x( 'Email address that %s customers will receive confirmation from. Leave empty to use the default WordPress site email address.', 'tickets fields settings confirmation email', 'event-tickets' ),
|
260 |
tribe_get_ticket_label_plural_lowercase( 'tickets_fields_settings_paypal_confirmation_email' )
|
261 |
)
|
@@ -265,12 +295,12 @@ class Settings extends Abstract_Settings {
|
|
265 |
'validation_type' => 'email',
|
266 |
'can_be_empty' => true,
|
267 |
],
|
268 |
-
|
269 |
'type' => 'text',
|
270 |
'label' => esc_html__( 'Confirmation email sender name', 'event-tickets' ),
|
271 |
'tooltip' => esc_html(
|
272 |
sprintf(
|
273 |
-
|
274 |
_x( 'Sender name of the confirmation email sent to customers when confirming a %s purchase.', 'tickets fields settings paypal email sender', 'event-tickets' ),
|
275 |
tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_email_sender' )
|
276 |
)
|
@@ -280,12 +310,12 @@ class Settings extends Abstract_Settings {
|
|
280 |
'validation_callback' => 'is_string',
|
281 |
'validation_type' => 'textarea',
|
282 |
],
|
283 |
-
|
284 |
'type' => 'text',
|
285 |
'label' => esc_html__( 'Confirmation email subject', 'event-tickets' ),
|
286 |
'tooltip' => esc_html(
|
287 |
sprintf(
|
288 |
-
|
289 |
_x( 'Subject of the confirmation email sent to customers when confirming a %s purchase.', 'tickets fields settings paypal email subject', 'event-tickets' ),
|
290 |
tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_email_subject' )
|
291 |
)
|
@@ -293,7 +323,7 @@ class Settings extends Abstract_Settings {
|
|
293 |
'size' => 'large',
|
294 |
'default' => esc_html(
|
295 |
sprintf(
|
296 |
-
|
297 |
_x( 'You have %s!', 'tickets fields settings paypal email subject', 'event-tickets' ),
|
298 |
tribe_get_ticket_label_plural_lowercase( 'tickets_fields_settings_paypal_email_subject' )
|
299 |
)
|
@@ -303,48 +333,7 @@ class Settings extends Abstract_Settings {
|
|
303 |
],
|
304 |
];
|
305 |
|
306 |
-
|
307 |
-
$manager = tribe( Manager::class );
|
308 |
-
|
309 |
-
$gateways = $manager->get_gateways();
|
310 |
-
|
311 |
-
$gateway_setting_groups = [];
|
312 |
-
|
313 |
-
// Get all of the gateway settings.
|
314 |
-
foreach ( $gateways as $gateway ) {
|
315 |
-
/** @var Abstract_Gateway $gateway_object */
|
316 |
-
$gateway_object = $gateway['object'];
|
317 |
-
|
318 |
-
if ( ! $gateway_object::should_show() ) {
|
319 |
-
continue;
|
320 |
-
}
|
321 |
-
|
322 |
-
// Get the gateway settings.
|
323 |
-
$gateway_settings = $gateway_object->get_settings();
|
324 |
-
|
325 |
-
// If there are no gateway settings, don't show this section at all.
|
326 |
-
if ( empty( $gateway_settings ) ) {
|
327 |
-
continue;
|
328 |
-
}
|
329 |
-
|
330 |
-
$heading = [
|
331 |
-
'tickets-commerce-' . $gateway_object::get_key() => [
|
332 |
-
'type' => 'wrapped_html',
|
333 |
-
'html' => '<h3 class="event-tickets--admin_settings_subheading">' . $gateway['label'] . '</h3>',
|
334 |
-
'validation_type' => 'html',
|
335 |
-
],
|
336 |
-
];
|
337 |
-
|
338 |
-
// Add the gateway label to the start of settings.
|
339 |
-
$gateway_setting_groups[] = $heading;
|
340 |
-
|
341 |
-
$gateway_setting_groups[] = $gateway_settings;
|
342 |
-
}
|
343 |
-
|
344 |
-
if ( ! empty( $gateway_setting_groups ) ) {
|
345 |
-
// Add the gateway setting groups.
|
346 |
-
$settings = array_merge( $settings, array_merge( ...$gateway_setting_groups ) );
|
347 |
-
}
|
348 |
|
349 |
/**
|
350 |
* Allow filtering the list of Tickets Commerce settings.
|
@@ -355,10 +344,22 @@ class Settings extends Abstract_Settings {
|
|
355 |
*/
|
356 |
$settings = apply_filters( 'tribe_tickets_commerce_settings', $settings );
|
357 |
|
358 |
-
|
359 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
$fieldset_attributes = [
|
361 |
-
'data-depends' => '#' .
|
362 |
'data-condition-is-checked' => '',
|
363 |
];
|
364 |
|
@@ -378,9 +379,7 @@ class Settings extends Abstract_Settings {
|
|
378 |
$commerce_field['validate_if'] = $validate_if;
|
379 |
}
|
380 |
|
381 |
-
|
382 |
-
|
383 |
-
return array_merge( $top_level_settings, $settings );
|
384 |
}
|
385 |
|
386 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
*
|
4 |
+
* @since 5.1.6
|
5 |
*
|
6 |
* @package TEC\Tickets\Commerce
|
7 |
*/
|
30 |
*
|
31 |
* @var string
|
32 |
*/
|
33 |
+
public static $option_enable = 'tickets-commerce-enable';
|
34 |
|
35 |
/**
|
36 |
* The option key for sandbox.
|
39 |
*
|
40 |
* @var string
|
41 |
*/
|
42 |
+
public static $option_sandbox = 'tickets-commerce-sandbox';
|
43 |
|
44 |
/**
|
45 |
* The option key for currency code.
|
48 |
*
|
49 |
* @var string
|
50 |
*/
|
51 |
+
public static $option_currency_code = 'tickets-commerce-currency-code';
|
52 |
|
53 |
/**
|
54 |
* The option key for stock handling.
|
57 |
*
|
58 |
* @var string
|
59 |
*/
|
60 |
+
public static $option_stock_handling = 'tickets-commerce-stock-handling';
|
61 |
|
62 |
/**
|
63 |
* The option key for success page.
|
66 |
*
|
67 |
* @var string
|
68 |
*/
|
69 |
+
public static $option_success_page = 'tickets-commerce-success-page';
|
70 |
|
71 |
/**
|
72 |
* The option key for checkout page.
|
75 |
*
|
76 |
* @var string
|
77 |
*/
|
78 |
+
public static $option_checkout_page = 'tickets-commerce-checkout-page';
|
79 |
|
80 |
/**
|
81 |
* The option key for confirmation email sender email.
|
84 |
*
|
85 |
* @var string
|
86 |
*/
|
87 |
+
public static $option_confirmation_email_sender_email = 'tickets-commerce-confirmation-email-sender-email';
|
88 |
|
89 |
/**
|
90 |
* The option key for confirmation email sender name.
|
93 |
*
|
94 |
* @var string
|
95 |
*/
|
96 |
+
public static $option_confirmation_email_sender_name = 'tickets-commerce-confirmation-email-sender-name';
|
97 |
|
98 |
/**
|
99 |
* The option key for confirmation email subject.
|
102 |
*
|
103 |
* @var string
|
104 |
*/
|
105 |
+
public static $option_confirmation_email_subject = 'tickets-commerce-confirmation-email-subject';
|
106 |
|
107 |
/**
|
108 |
+
* Create the Tickets Commerce Payments Settings Tab.
|
109 |
*
|
110 |
+
* @since 5.1.9
|
111 |
+
*/
|
112 |
+
public function register_tab() {
|
113 |
+
$tab_settings = [
|
114 |
+
'priority' => 25,
|
115 |
+
'fields' => $this->get_settings(),
|
116 |
+
'show_save' => false,
|
117 |
+
];
|
118 |
+
|
119 |
+
new \Tribe__Settings_Tab( 'payments', esc_html__( 'Payments', 'event-tickets' ), $tab_settings );
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Gets the top level settings for Tickets Commerce.
|
124 |
*
|
125 |
+
* @since 5.1.9
|
126 |
+
*
|
127 |
+
*
|
128 |
+
* @return array[]
|
129 |
*/
|
130 |
+
public function get_top_level_settings() {
|
131 |
+
|
132 |
$plus_link = sprintf(
|
133 |
'<a href="https://evnt.is/19zl" target="_blank" rel="noopener noreferrer">%s</a>',
|
134 |
esc_html__( 'Event Tickets Plus', 'event-tickets' )
|
138 |
esc_html__( 'Check it out!', 'event-tickets' )
|
139 |
);
|
140 |
$plus_message = sprintf(
|
141 |
+
// Translators: %1$s: The Event Tickets Plus link, %2$s: The word "ticket" in lowercase, %3$s: The "Check it out!" link.
|
142 |
esc_html_x( 'Tickets Commerce is a light implementation of a commerce gateway using PayPal and simplified stock handling. If you need more advanced features, take a look at %1$s. In addition to integrating with your favorite ecommerce provider, Event Tickets Plus includes options to collect custom information for attendees, check users in via QR codes, and share stock between %2$s. %3$s', 'about Tickets Commerce', 'event-tickets' ),
|
143 |
$plus_link,
|
144 |
esc_html( tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_about_tribe_commerce' ) ),
|
145 |
$plus_link_2
|
146 |
);
|
147 |
|
148 |
+
// @todo Fill this out and make it check if PayPal Legacy was previously active.
|
149 |
+
$is_tickets_commerce_enabled = tec_tickets_commerce_is_enabled();
|
150 |
+
|
151 |
+
$top_level_settings = [
|
152 |
+
'tickets-commerce-header' => [
|
153 |
+
'type' => 'html',
|
154 |
+
'html' => '<div class="tec-tickets-commerce-toggle"><label class="tec-tickets-commerce-switch"><input type="checkbox" name="' . static::$option_enable . '" value="' . $is_tickets_commerce_enabled . '" ' . checked( $is_tickets_commerce_enabled, true, false ) . ' id="tickets-commerce-enable-input" class="tribe-dependency tribe-dependency-verified"><span class="tec-tickets-commerce-slider round"></span></label><h2>' . esc_html__( 'Enable Tickets Commerce', 'event-tickets' ) . '</h2></div>',
|
155 |
+
],
|
156 |
+
'tickets-commerce-description' => [
|
157 |
+
'type' => 'html',
|
158 |
+
'html' => '<div class="tec-tickets-commerce-description">' . $plus_message . '</div>',
|
159 |
+
],
|
160 |
+
static::$option_enable => [
|
161 |
+
'type' => 'hidden',
|
162 |
+
'validation_type' => 'boolean',
|
163 |
+
],
|
164 |
+
];
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Hook to modify the top level settings for Tickets Commerce.
|
168 |
+
*
|
169 |
+
* @since 5.1.9
|
170 |
+
*
|
171 |
+
* @param array[] $top_level_settings Top level settings.
|
172 |
+
*/
|
173 |
+
return apply_filters( 'tec_tickets_commerce_settings_top_level', $top_level_settings );
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Get the list of settings for Tickets Commerce.
|
178 |
+
*
|
179 |
+
* @since 5.1.6
|
180 |
+
*
|
181 |
+
* @return array The list of settings for Tickets Commerce.
|
182 |
+
*/
|
183 |
+
public function get_settings() {
|
184 |
+
$gateways_manager = tribe( Manager::class );
|
185 |
+
|
186 |
// @todo Replace this with a better and more performant REST API based solution.
|
187 |
$page_args = [
|
188 |
'post_status' => 'publish',
|
198 |
// Add an initial empty selection to the start.
|
199 |
$pages = [ 0 => __( '-- No page set --', 'event-tickets' ) ] + $pages;
|
200 |
|
201 |
+
$success_shortcode = Shortcodes\Success_Shortcode::get_wp_slug();
|
202 |
+
$checkout_shortcode = Shortcodes\Checkout_Shortcode::get_wp_slug();
|
203 |
|
204 |
/** @var \Tribe__Tickets__Commerce__Currency $commerce_currency */
|
205 |
$commerce_currency = tribe( 'tickets.commerce.currency' );
|
208 |
|
209 |
$current_user = get_user_by( 'id', get_current_user_id() );
|
210 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
$settings = [
|
212 |
+
static::$option_sandbox => [
|
213 |
'type' => 'checkbox_bool',
|
214 |
'label' => esc_html__( 'Enable Test Mode', 'event-tickets' ),
|
215 |
'tooltip' => esc_html__( 'Enables Test mode for testing payments. Any payments made will be done on "sandbox" accounts.', 'event-tickets' ),
|
216 |
'default' => false,
|
217 |
'validation_type' => 'boolean',
|
218 |
],
|
219 |
+
static::$option_currency_code => [
|
220 |
'type' => 'dropdown',
|
221 |
'label' => esc_html__( 'Currency Code', 'event-tickets' ),
|
222 |
'tooltip' => esc_html__( 'The currency that will be used for Tickets Commerce transactions.', 'event-tickets' ),
|
224 |
'validation_type' => 'options',
|
225 |
'options' => $paypal_currency_code_options,
|
226 |
],
|
227 |
+
static::$option_stock_handling => [
|
228 |
'type' => 'radio',
|
229 |
'label' => esc_html__( 'Stock Handling', 'event-tickets' ),
|
230 |
'tooltip' => esc_html(
|
231 |
sprintf(
|
232 |
+
// Translators: %s: The word "ticket" in lowercase.
|
233 |
_x( 'When a customer purchases a %s, the payment gateway might flag the order as Pending. The order will be Complete once payment is confirmed by the payment gateway.', 'tickets fields settings paypal stock handling', 'event-tickets' ),
|
234 |
tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_stock_handling' )
|
235 |
)
|
238 |
'validation_type' => 'options',
|
239 |
'options' => [
|
240 |
'on-pending' => sprintf(
|
241 |
+
// Translators: %s: The word "ticket" in lowercase.
|
242 |
esc_html__( 'Decrease available %s stock as soon as a Pending order is created.', 'event-tickets' ),
|
243 |
tribe_get_ticket_label_singular_lowercase( 'stock_handling' )
|
244 |
),
|
245 |
'on-complete' => sprintf(
|
246 |
+
// Translators: %s: The word "ticket" in lowercase.
|
247 |
esc_html__( 'Only decrease available %s stock if an order is confirmed as Completed by the payment gateway.', 'event-tickets' ),
|
248 |
tribe_get_ticket_label_singular_lowercase( 'stock_handling' )
|
249 |
),
|
250 |
],
|
251 |
'tooltip_first' => true,
|
252 |
],
|
253 |
+
static::$option_checkout_page => [
|
254 |
'type' => 'dropdown',
|
255 |
'label' => esc_html__( 'Checkout page', 'event-tickets' ),
|
256 |
'tooltip' => esc_html(
|
257 |
sprintf(
|
258 |
+
// Translators: %s: The [shortcode] for the success page.
|
259 |
__( 'This is the page where customers go to complete their purchase. Use the %s shortcode to display the checkout experience in the page content.', 'event-tickets' ),
|
260 |
+
"[$checkout_shortcode]"
|
261 |
)
|
262 |
),
|
263 |
'size' => 'medium',
|
265 |
'options' => $pages,
|
266 |
'required' => true,
|
267 |
],
|
268 |
+
static::$option_success_page => [
|
269 |
'type' => 'dropdown',
|
270 |
'label' => esc_html__( 'Success page', 'event-tickets' ),
|
271 |
'tooltip' => esc_html(
|
272 |
sprintf(
|
273 |
+
// Translators: %s: The [shortcode] for the success page.
|
274 |
__( 'After a successful order, users will be redirected to this page. Use the %s shortcode to display the order confirmation to the user in the page content.', 'event-tickets' ),
|
275 |
+
"[$success_shortcode]"
|
276 |
)
|
277 |
),
|
278 |
'size' => 'medium',
|
280 |
'options' => $pages,
|
281 |
'required' => true,
|
282 |
],
|
283 |
+
static::$option_confirmation_email_sender_email => [
|
284 |
'type' => 'email',
|
285 |
'label' => esc_html__( 'Confirmation email sender address', 'event-tickets' ),
|
286 |
'tooltip' => esc_html(
|
287 |
sprintf(
|
288 |
+
// Translators: %s: The word "tickets" in lowercase.
|
289 |
_x( 'Email address that %s customers will receive confirmation from. Leave empty to use the default WordPress site email address.', 'tickets fields settings confirmation email', 'event-tickets' ),
|
290 |
tribe_get_ticket_label_plural_lowercase( 'tickets_fields_settings_paypal_confirmation_email' )
|
291 |
)
|
295 |
'validation_type' => 'email',
|
296 |
'can_be_empty' => true,
|
297 |
],
|
298 |
+
static::$option_confirmation_email_sender_name => [
|
299 |
'type' => 'text',
|
300 |
'label' => esc_html__( 'Confirmation email sender name', 'event-tickets' ),
|
301 |
'tooltip' => esc_html(
|
302 |
sprintf(
|
303 |
+
// Translators: %s: The word "ticket" in lowercase.
|
304 |
_x( 'Sender name of the confirmation email sent to customers when confirming a %s purchase.', 'tickets fields settings paypal email sender', 'event-tickets' ),
|
305 |
tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_email_sender' )
|
306 |
)
|
310 |
'validation_callback' => 'is_string',
|
311 |
'validation_type' => 'textarea',
|
312 |
],
|
313 |
+
static::$option_confirmation_email_subject => [
|
314 |
'type' => 'text',
|
315 |
'label' => esc_html__( 'Confirmation email subject', 'event-tickets' ),
|
316 |
'tooltip' => esc_html(
|
317 |
sprintf(
|
318 |
+
// Translators: %s: The word "ticket" in lowercase.
|
319 |
_x( 'Subject of the confirmation email sent to customers when confirming a %s purchase.', 'tickets fields settings paypal email subject', 'event-tickets' ),
|
320 |
tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_email_subject' )
|
321 |
)
|
323 |
'size' => 'large',
|
324 |
'default' => esc_html(
|
325 |
sprintf(
|
326 |
+
// Translators: %s: The word "tickets" in lowercase.
|
327 |
_x( 'You have %s!', 'tickets fields settings paypal email subject', 'event-tickets' ),
|
328 |
tribe_get_ticket_label_plural_lowercase( 'tickets_fields_settings_paypal_email_subject' )
|
329 |
)
|
333 |
],
|
334 |
];
|
335 |
|
336 |
+
$settings = array_merge( $gateways_manager->get_gateway_settings(), $settings );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
337 |
|
338 |
/**
|
339 |
* Allow filtering the list of Tickets Commerce settings.
|
344 |
*/
|
345 |
$settings = apply_filters( 'tribe_tickets_commerce_settings', $settings );
|
346 |
|
347 |
+
return array_merge( $this->get_top_level_settings(), $settings );
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Handle setting up dependencies for all of the fields.
|
352 |
+
*
|
353 |
+
* @since 5.1.9
|
354 |
+
*
|
355 |
+
* @param array[] $settings Which settings we are applying conditioanls to.
|
356 |
+
*
|
357 |
+
* @return array[]
|
358 |
+
*/
|
359 |
+
public function apply_commerce_enabled_conditional( $settings ) {
|
360 |
+
$validate_if = new Tribe__Field_Conditional( static::$option_enable, 'tribe_is_truthy' );
|
361 |
$fieldset_attributes = [
|
362 |
+
'data-depends' => '#' . static::$option_enable . '-input',
|
363 |
'data-condition-is-checked' => '',
|
364 |
];
|
365 |
|
379 |
$commerce_field['validate_if'] = $validate_if;
|
380 |
}
|
381 |
|
382 |
+
return $settings;
|
|
|
|
|
383 |
}
|
384 |
|
385 |
}
|
src/Tickets/Commerce/Shortcodes/Checkout_Shortcode.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Shortcode [tec_tickets_checkout].
|
4 |
+
*
|
5 |
+
* @since 5.1.9
|
6 |
+
* @package TEC\Tickets\Commerce
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace TEC\Tickets\Commerce\Shortcodes;
|
10 |
+
|
11 |
+
use TEC\Tickets\Commerce\Checkout;
|
12 |
+
use TEC\Tickets\Commerce\Cart;
|
13 |
+
use TEC\Tickets\Commerce\Module;
|
14 |
+
use TEC\Tickets\Commerce\Order;
|
15 |
+
use TEC\Tickets\Commerce\Status\Completed;
|
16 |
+
use TEC\Tickets\Commerce\Status\Created;
|
17 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
18 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Settings;
|
19 |
+
use Tribe__Tickets__Editor__Template;
|
20 |
+
use TEC\Tickets\Commerce\Utils\Price;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Class for Shortcode Tribe_Tickets_Checkout.
|
24 |
+
*
|
25 |
+
* @since 5.1.9
|
26 |
+
* @package Tribe\Tickets\Shortcodes
|
27 |
+
*/
|
28 |
+
class Checkout_Shortcode extends Shortcode_Abstract {
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Id of the current shortcode for filtering purposes.
|
32 |
+
*
|
33 |
+
* @since 5.1.9
|
34 |
+
*
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
public static $shortcode_id = 'checkout';
|
38 |
+
|
39 |
+
/**
|
40 |
+
* {@inheritDoc}
|
41 |
+
*/
|
42 |
+
public function setup_template_vars() {
|
43 |
+
$items = tribe( Cart::class )->get_items_in_cart( true );
|
44 |
+
$sections = array_unique( array_filter( wp_list_pluck( $items, 'event_id' ) ) );
|
45 |
+
$sub_totals = array_filter( wp_list_pluck( $items, 'sub_total' ) );
|
46 |
+
|
47 |
+
$args = [
|
48 |
+
'provider_id' => Module::class,
|
49 |
+
'provider' => tribe( Module::class ),
|
50 |
+
'items' => $items,
|
51 |
+
'sections' => $sections,
|
52 |
+
'total_value' => tribe_format_currency( Price::total( $sub_totals ) ),
|
53 |
+
'must_login' => ! is_user_logged_in() && tribe( Module::class )->login_required(),
|
54 |
+
'login_url' => tribe( Checkout::class )->get_login_url(),
|
55 |
+
'registration_url' => tribe( Checkout::class )->get_registration_url(),
|
56 |
+
];
|
57 |
+
|
58 |
+
$this->template_vars = $args;
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* {@inheritDoc}
|
63 |
+
*/
|
64 |
+
public function get_html() {
|
65 |
+
$context = tribe_context();
|
66 |
+
|
67 |
+
if ( is_admin() && ! $context->doing_ajax() ) {
|
68 |
+
return '';
|
69 |
+
}
|
70 |
+
|
71 |
+
$args = $this->get_template_vars();
|
72 |
+
|
73 |
+
// Add the rendering attributes into global context.
|
74 |
+
$this->get_template()->add_template_globals( $args );
|
75 |
+
|
76 |
+
$html = $this->get_template()->template( 'checkout', $args, false );
|
77 |
+
|
78 |
+
// Enqueue assets.
|
79 |
+
tribe_asset_enqueue_group( 'tribe-tickets-commerce-checkout' );
|
80 |
+
|
81 |
+
return $html;
|
82 |
+
}
|
83 |
+
|
84 |
+
}
|
src/Tickets/Commerce/Shortcodes/Shortcode_Abstract.php
ADDED
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Shortcodes;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Gateways\Manager;
|
6 |
+
use Tribe\Shortcode\Shortcode_Abstract as Common_Shortcode_Abstract;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class Shortcode_Abstract
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Shortcodes
|
14 |
+
*/
|
15 |
+
abstract class Shortcode_Abstract extends Common_Shortcode_Abstract {
|
16 |
+
/**
|
17 |
+
* Configures this instance of the shortcode.
|
18 |
+
*
|
19 |
+
* @since 5.1.9
|
20 |
+
*/
|
21 |
+
public function __construct() {
|
22 |
+
$this->slug = static::get_wp_slug();
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* The Shortcode Slug inside of WordPress.
|
27 |
+
*
|
28 |
+
* @since 5.1.9
|
29 |
+
*
|
30 |
+
* @return string
|
31 |
+
*/
|
32 |
+
public static function get_wp_slug() {
|
33 |
+
return 'tec_tickets_' . static::$shortcode_id;
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Set of template variable used to generate this shortcode.
|
38 |
+
*
|
39 |
+
* @since 5.1.9
|
40 |
+
*
|
41 |
+
* @var array
|
42 |
+
*/
|
43 |
+
protected $template_vars = [];
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Stores the instance of the template engine that we will use for rendering the page.
|
47 |
+
*
|
48 |
+
* @since 5.1.9
|
49 |
+
*
|
50 |
+
* @var \Tribe__Template
|
51 |
+
*/
|
52 |
+
protected $template;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Gets the template instance used to setup the rendering of the page.
|
56 |
+
*
|
57 |
+
* @since 5.1.9
|
58 |
+
*
|
59 |
+
* @return \Tribe__Template
|
60 |
+
*/
|
61 |
+
public function get_template() {
|
62 |
+
if ( empty( $this->template ) ) {
|
63 |
+
$this->template = new \Tribe__Template();
|
64 |
+
$this->template->set_template_origin( \Tribe__Tickets__Main::instance() );
|
65 |
+
$this->template->set_template_folder( 'src/views/v2/commerce' );
|
66 |
+
$this->template->set_template_context_extract( true );
|
67 |
+
$this->template->set_template_folder_lookup( true );
|
68 |
+
}
|
69 |
+
|
70 |
+
return $this->template;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Method used to save the template vars for this instance of shortcode.
|
75 |
+
*
|
76 |
+
* @since 5.1.9
|
77 |
+
*
|
78 |
+
* @return void
|
79 |
+
*/
|
80 |
+
abstract public function setup_template_vars();
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Gets the current active gateway slug.
|
84 |
+
*
|
85 |
+
* @since 5.1.9
|
86 |
+
*
|
87 |
+
* @return string
|
88 |
+
*/
|
89 |
+
public function get_gateway_slug() {
|
90 |
+
return (string) tribe( Manager::class )->get_current_gateway();
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Calls the template vars setup and returns after filtering.
|
95 |
+
*
|
96 |
+
* @since 5.1.9
|
97 |
+
*
|
98 |
+
* @return array
|
99 |
+
*/
|
100 |
+
public function get_template_vars() {
|
101 |
+
$this->setup_template_vars();
|
102 |
+
|
103 |
+
return (array) $this->filter_template_vars( $this->template_vars );
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Enables filtering of the template variables.
|
108 |
+
*
|
109 |
+
* @since 5.1.9
|
110 |
+
*
|
111 |
+
* @param array $template_vars Which set of variables we are passing to the filters.
|
112 |
+
*
|
113 |
+
* @return array
|
114 |
+
*/
|
115 |
+
public function filter_template_vars( array $template_vars = [] ) {
|
116 |
+
/**
|
117 |
+
* Applies a filter to template vars for this shortcode.
|
118 |
+
*
|
119 |
+
* @since 5.1.9
|
120 |
+
*
|
121 |
+
* @param array $template_vars Current set of callbacks for arguments.
|
122 |
+
* @param static $instance Which instance of shortcode we are dealing with.
|
123 |
+
*/
|
124 |
+
$template_vars = apply_filters( 'tec_tickets_commerce_shortcode_page_template_vars', $template_vars, $this );
|
125 |
+
|
126 |
+
$shortcode_id = static::$shortcode_id;
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Applies a filter to template vars for this shortcode, using ID.
|
130 |
+
*
|
131 |
+
* @since 5.1.9
|
132 |
+
*
|
133 |
+
* @param array $template_vars Current set of callbacks for arguments.
|
134 |
+
* @param static $instance Which instance of shortcode we are dealing with.
|
135 |
+
*/
|
136 |
+
$template_vars = apply_filters( "tec_tickets_commerce_shortcode_{$shortcode_id}_page_template_vars", $template_vars, $this );
|
137 |
+
|
138 |
+
$gateway = $this->get_gateway_slug();
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Applies a filter to template vars for this shortcode, using ID and gateway.
|
142 |
+
*
|
143 |
+
* @since 5.1.9
|
144 |
+
*
|
145 |
+
* @param array $template_vars Current set of callbacks for arguments.
|
146 |
+
* @param static $instance Which instance of shortcode we are dealing with.
|
147 |
+
*/
|
148 |
+
return (array) apply_filters( "tec_tickets_commerce_success_shortcode_{$shortcode_id}_page_{$gateway}_template_vars", $template_vars, $this );
|
149 |
+
}
|
150 |
+
|
151 |
+
}
|
src/Tickets/Commerce/Shortcodes/Success_Shortcode.php
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Shortcode [tec_tickets_success].
|
4 |
+
*
|
5 |
+
* @since 5.1.9
|
6 |
+
* @package TEC\Tickets\Commerce
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace TEC\Tickets\Commerce\Shortcodes;
|
10 |
+
|
11 |
+
use TEC\Tickets\Commerce\Module;
|
12 |
+
use TEC\Tickets\Commerce\Status\Completed;
|
13 |
+
use TEC\Tickets\Commerce\Success;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Class for Shortcode Tribe_Tickets_Checkout.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
* @package Tribe\Tickets\Shortcodes
|
20 |
+
*/
|
21 |
+
class Success_Shortcode extends Shortcode_Abstract {
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Id of the current shortcode for filtering purposes.
|
25 |
+
*
|
26 |
+
* @since 5.1.9
|
27 |
+
*
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
public static $shortcode_id = 'success';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* {@inheritDoc}
|
34 |
+
*/
|
35 |
+
public function setup_template_vars() {
|
36 |
+
$order_id = tribe_get_request_var( Success::$order_id_query_arg );
|
37 |
+
$order = tec_tc_orders()->by_args( [
|
38 |
+
'status' => 'any',
|
39 |
+
'gateway_order_id' => $order_id,
|
40 |
+
] )->first();
|
41 |
+
|
42 |
+
$args = [
|
43 |
+
'provider_id' => Module::class,
|
44 |
+
'provider' => tribe( Module::class ),
|
45 |
+
'order_id' => $order_id,
|
46 |
+
'order' => $order,
|
47 |
+
];
|
48 |
+
|
49 |
+
$this->template_vars = $args;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* {@inheritDoc}
|
54 |
+
*/
|
55 |
+
public function get_html() {
|
56 |
+
$context = tribe_context();
|
57 |
+
|
58 |
+
if ( is_admin() && ! $context->doing_ajax() ) {
|
59 |
+
return '';
|
60 |
+
}
|
61 |
+
|
62 |
+
$args = $this->get_template_vars();
|
63 |
+
|
64 |
+
// Add the rendering attributes into global context.
|
65 |
+
$this->get_template()->add_template_globals( $args );
|
66 |
+
|
67 |
+
$html = $this->get_template()->template( 'success', $args, false );
|
68 |
+
|
69 |
+
// Enqueue assets.
|
70 |
+
tribe_asset_enqueue_group( 'tec-tickets-commerce-success' );
|
71 |
+
|
72 |
+
return $html;
|
73 |
+
}
|
74 |
+
|
75 |
+
}
|
src/Tickets/Commerce/Status/Action_Required.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Pending.
|
7 |
+
*
|
8 |
+
* This is a payment that has begun, but is not complete. An example of this is someone who has filled out the checkout
|
9 |
+
* form and then gone to Gateway for payment. We have the record of sale, but they haven't completed their payment yet.
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Status
|
14 |
+
*/
|
15 |
+
class Action_Required extends Status_Abstract {
|
16 |
+
/**
|
17 |
+
* Slug for this Status.
|
18 |
+
*
|
19 |
+
* @since 5.1.9
|
20 |
+
*
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
const SLUG = 'action-required';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* {@inheritdoc}
|
27 |
+
*/
|
28 |
+
public function get_name() {
|
29 |
+
return __( 'Action Required', 'event-tickets' );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* {@inheritdoc}
|
34 |
+
*/
|
35 |
+
protected $flags = [
|
36 |
+
'incomplete',
|
37 |
+
'trigger_option',
|
38 |
+
'attendee_generation',
|
39 |
+
'stock_reduced',
|
40 |
+
'count_attendee',
|
41 |
+
'count_incomplete',
|
42 |
+
'count_sales',
|
43 |
+
];
|
44 |
+
|
45 |
+
/**
|
46 |
+
* {@inheritdoc}
|
47 |
+
*/
|
48 |
+
protected $wp_arguments = [
|
49 |
+
'public' => true,
|
50 |
+
'exclude_from_search' => false,
|
51 |
+
'show_in_admin_all_list' => true,
|
52 |
+
'show_in_admin_status_list' => true,
|
53 |
+
];
|
54 |
+
}
|
src/Tickets/Commerce/Status/Approved.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Pending.
|
7 |
+
*
|
8 |
+
* This is a payment that has begun, but is not complete. An example of this is someone who has filled out the checkout
|
9 |
+
* form and then gone to Gateway for payment. We have the record of sale, but they haven't completed their payment yet.
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Status
|
14 |
+
*/
|
15 |
+
class Approved extends Status_Abstract {
|
16 |
+
/**
|
17 |
+
* Slug for this Status.
|
18 |
+
*
|
19 |
+
* @since 5.1.9
|
20 |
+
*
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
const SLUG = 'approved';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* {@inheritdoc}
|
27 |
+
*/
|
28 |
+
public function get_name() {
|
29 |
+
return __( 'Approved', 'event-tickets' );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* {@inheritdoc}
|
34 |
+
*/
|
35 |
+
protected $flags = [
|
36 |
+
'incomplete',
|
37 |
+
'trigger_option',
|
38 |
+
'attendee_generation',
|
39 |
+
'stock_reduced',
|
40 |
+
'count_attendee',
|
41 |
+
'count_incomplete',
|
42 |
+
'count_sales',
|
43 |
+
];
|
44 |
+
|
45 |
+
/**
|
46 |
+
* {@inheritdoc}
|
47 |
+
*/
|
48 |
+
protected $wp_arguments = [
|
49 |
+
'public' => true,
|
50 |
+
'exclude_from_search' => false,
|
51 |
+
'show_in_admin_all_list' => true,
|
52 |
+
'show_in_admin_status_list' => true,
|
53 |
+
];
|
54 |
+
}
|
src/Tickets/Commerce/Status/Completed.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace TEC\Tickets\Commerce\Status;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Class Denied.
|
6 |
+
*
|
7 |
+
* This is the status we use to mark a given order as paid and delivered in our Tickets Commerce system.
|
8 |
+
*
|
9 |
+
* @since 5.1.9
|
10 |
+
*
|
11 |
+
* @package TEC\Tickets\Commerce\Status
|
12 |
+
*/
|
13 |
+
class Completed extends Status_Abstract {
|
14 |
+
/**
|
15 |
+
* Slug for this Status.
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
const SLUG = 'completed';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* {@inheritdoc}
|
25 |
+
*/
|
26 |
+
public function get_name() {
|
27 |
+
return __( 'Completed', 'event-tickets' );
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* {@inheritdoc}
|
32 |
+
*/
|
33 |
+
protected $flags = [
|
34 |
+
'complete',
|
35 |
+
'trigger_option',
|
36 |
+
'attendee_generation',
|
37 |
+
'attendee_dispatch',
|
38 |
+
'stock_reduced',
|
39 |
+
'count_attendee',
|
40 |
+
'count_completed',
|
41 |
+
'count_sales',
|
42 |
+
];
|
43 |
+
|
44 |
+
/**
|
45 |
+
* {@inheritdoc}
|
46 |
+
*/
|
47 |
+
protected $wp_arguments = [
|
48 |
+
'public' => true,
|
49 |
+
'exclude_from_search' => false,
|
50 |
+
'show_in_admin_all_list' => true,
|
51 |
+
'show_in_admin_status_list' => true,
|
52 |
+
];
|
53 |
+
|
54 |
+
}
|
src/Tickets/Commerce/Status/Created.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace TEC\Tickets\Commerce\Status;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Class Created.
|
6 |
+
*
|
7 |
+
* This is the first Status any order will have.
|
8 |
+
*
|
9 |
+
* Used for handling the Orders that were Created in the Tickets Commerce System but never got to Pending.
|
10 |
+
* Normally the change to Pending will depend on the Gateway.
|
11 |
+
*
|
12 |
+
* @since 5.1.9
|
13 |
+
*
|
14 |
+
* @package TEC\Tickets\Commerce\Status
|
15 |
+
*/
|
16 |
+
class Created extends Status_Abstract {
|
17 |
+
/**
|
18 |
+
* Slug for this Status.
|
19 |
+
*
|
20 |
+
* @since 5.1.9
|
21 |
+
*
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
const SLUG = 'created';
|
25 |
+
|
26 |
+
/**
|
27 |
+
* {@inheritdoc}
|
28 |
+
*/
|
29 |
+
public function get_name() {
|
30 |
+
return __( 'Created', 'event-tickets' );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* {@inheritdoc}
|
35 |
+
*/
|
36 |
+
protected $flags = [
|
37 |
+
'incomplete',
|
38 |
+
'trigger_option',
|
39 |
+
];
|
40 |
+
|
41 |
+
/**
|
42 |
+
* {@inheritdoc}
|
43 |
+
*/
|
44 |
+
protected $wp_arguments = [
|
45 |
+
'public' => true,
|
46 |
+
'exclude_from_search' => false,
|
47 |
+
'show_in_admin_all_list' => true,
|
48 |
+
'show_in_admin_status_list' => true,
|
49 |
+
];
|
50 |
+
}
|
src/Tickets/Commerce/Status/Denied.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Denied.
|
7 |
+
*
|
8 |
+
* Used for handling Orders where the payment process failed, whether it be a credit card rejection or some other error.
|
9 |
+
*
|
10 |
+
* @since 5.1.9
|
11 |
+
*
|
12 |
+
* @package TEC\Tickets\Commerce\Status
|
13 |
+
*/
|
14 |
+
class Denied extends Status_Abstract {
|
15 |
+
/**
|
16 |
+
* Slug for this Status.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
const SLUG = 'denied';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* {@inheritdoc}
|
26 |
+
*/
|
27 |
+
public function get_name() {
|
28 |
+
return __( 'Denied', 'event-tickets' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* {@inheritdoc}
|
33 |
+
*/
|
34 |
+
protected $flags = [
|
35 |
+
'incomplete',
|
36 |
+
'warning',
|
37 |
+
'count_canceled',
|
38 |
+
];
|
39 |
+
|
40 |
+
/**
|
41 |
+
* {@inheritdoc}
|
42 |
+
*/
|
43 |
+
protected $wp_arguments = [
|
44 |
+
'public' => true,
|
45 |
+
'exclude_from_search' => false,
|
46 |
+
'show_in_admin_all_list' => true,
|
47 |
+
'show_in_admin_status_list' => true,
|
48 |
+
];
|
49 |
+
}
|
src/Tickets/Commerce/Status/Not_Completed.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Denied.
|
7 |
+
*
|
8 |
+
* Used for handling Orders where Pending payment but never completed it, becoming Abandoned after a week..
|
9 |
+
*
|
10 |
+
* @since 5.1.9
|
11 |
+
*
|
12 |
+
* @package TEC\Tickets\Commerce\Status
|
13 |
+
*/
|
14 |
+
class Not_Completed extends Status_Abstract {
|
15 |
+
/**
|
16 |
+
* Slug for this Status.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
const SLUG = 'not-completed';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* {@inheritdoc}
|
26 |
+
*/
|
27 |
+
public function get_name() {
|
28 |
+
return __( 'Not Completed', 'event-tickets' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* {@inheritdoc}
|
33 |
+
*/
|
34 |
+
protected $flags = [
|
35 |
+
'incomplete',
|
36 |
+
'warning',
|
37 |
+
'revert_stock',
|
38 |
+
'archive_attendee'
|
39 |
+
];
|
40 |
+
|
41 |
+
/**
|
42 |
+
* {@inheritdoc}
|
43 |
+
*/
|
44 |
+
protected $wp_arguments = [
|
45 |
+
'public' => true,
|
46 |
+
'exclude_from_search' => false,
|
47 |
+
'show_in_admin_all_list' => true,
|
48 |
+
'show_in_admin_status_list' => true,
|
49 |
+
];
|
50 |
+
}
|
src/Tickets/Commerce/Status/Pending.php
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Module;
|
6 |
+
use TEC\Tickets\Commerce\Ticket;
|
7 |
+
use WP_Error;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class Pending.
|
11 |
+
*
|
12 |
+
* This is a payment that has begun, but is not complete. An example of this is someone who has filled out the checkout
|
13 |
+
* form and then gone to Gateway for payment. We have the record of sale, but they haven't completed their payment yet.
|
14 |
+
*
|
15 |
+
* @since 5.1.9
|
16 |
+
*
|
17 |
+
* @package TEC\Tickets\Commerce\Status
|
18 |
+
*/
|
19 |
+
class Pending extends Status_Abstract {
|
20 |
+
/**
|
21 |
+
* Slug for this Status.
|
22 |
+
*
|
23 |
+
* @since 5.1.9
|
24 |
+
*
|
25 |
+
* @var string
|
26 |
+
*/
|
27 |
+
const SLUG = 'pending';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* {@inheritdoc}
|
31 |
+
*/
|
32 |
+
public function get_name() {
|
33 |
+
return __( 'Pending', 'event-tickets' );
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* {@inheritdoc}
|
38 |
+
*/
|
39 |
+
protected $flags = [
|
40 |
+
'generate_attendees',
|
41 |
+
'reduce_stock',
|
42 |
+
'count_attendee',
|
43 |
+
'count_incomplete',
|
44 |
+
'count_sales',
|
45 |
+
];
|
46 |
+
|
47 |
+
/**
|
48 |
+
* {@inheritdoc}
|
49 |
+
*/
|
50 |
+
protected $wp_arguments = [
|
51 |
+
'public' => true,
|
52 |
+
'exclude_from_search' => false,
|
53 |
+
'show_in_admin_all_list' => true,
|
54 |
+
'show_in_admin_status_list' => true,
|
55 |
+
];
|
56 |
+
|
57 |
+
/**
|
58 |
+
* {@inheritdoc}
|
59 |
+
*/
|
60 |
+
public function can_apply_to( $order ) {
|
61 |
+
$status = parent::can_apply_to( $order );
|
62 |
+
|
63 |
+
// If the parent status or abstract has an error already we dont even run.
|
64 |
+
if ( is_wp_error( $status ) ) {
|
65 |
+
return $status;
|
66 |
+
}
|
67 |
+
|
68 |
+
$order = tec_tc_get_order( $order );
|
69 |
+
|
70 |
+
// Since there are no cart items we can do anything.
|
71 |
+
if ( empty( $order->cart_items ) || ! is_array( $order->cart_items ) ) {
|
72 |
+
return true;
|
73 |
+
}
|
74 |
+
|
75 |
+
foreach ( $order->cart_items as $item ) {
|
76 |
+
// Skip if we dont have a ticket id.
|
77 |
+
if ( empty( $item['ticket_id'] ) ) {
|
78 |
+
continue;
|
79 |
+
}
|
80 |
+
|
81 |
+
// If item quantity is empty, continue
|
82 |
+
if ( empty( $item['quantity'] ) ) {
|
83 |
+
continue;
|
84 |
+
}
|
85 |
+
|
86 |
+
/** @var \Tribe__Tickets__Ticket_Object $ticket_type */
|
87 |
+
$ticket = tribe( Ticket::class )->get_ticket( $item['ticket_id'] );
|
88 |
+
|
89 |
+
if ( null === $ticket ) {
|
90 |
+
return new WP_Error(
|
91 |
+
'tec-tc-invalid-ticket-id',
|
92 |
+
sprintf( __( 'This order contained an invalid Ticket (ID: %1$d)', 'event-tickets' ), $item['ticket_id'] ),
|
93 |
+
[
|
94 |
+
'ticket' => $item['ticket_id'],
|
95 |
+
'order' => $order,
|
96 |
+
'new_status' => $this
|
97 |
+
]
|
98 |
+
);
|
99 |
+
}
|
100 |
+
|
101 |
+
// Get the event this tickets is for
|
102 |
+
$post = $ticket->get_event();
|
103 |
+
|
104 |
+
if ( empty( $post ) ) {
|
105 |
+
return new WP_Error(
|
106 |
+
'tec-tc-invalid-event-id',
|
107 |
+
sprintf( __( 'This order contained a Ticket with an invalid Event (Event ID: %1$d)', 'event-tickets' ), $item['ticket_id'] ),
|
108 |
+
[
|
109 |
+
'ticket' => $item['ticket_id'],
|
110 |
+
'order' => $order,
|
111 |
+
'new_status' => $this
|
112 |
+
]
|
113 |
+
);
|
114 |
+
}
|
115 |
+
|
116 |
+
$qty = max( (int) $item['quantity'], 0 );
|
117 |
+
|
118 |
+
if ( $qty === 0 ) {
|
119 |
+
return new WP_Error(
|
120 |
+
'tec-tc-cannot-purchase-zero',
|
121 |
+
sprintf( __( 'Cannot purchase zero of "%1$s"', 'event-tickets' ), $ticket->name ),
|
122 |
+
[
|
123 |
+
'ticket' => $item['ticket_id'],
|
124 |
+
'order' => $order,
|
125 |
+
'new_status' => $this
|
126 |
+
]
|
127 |
+
);
|
128 |
+
}
|
129 |
+
|
130 |
+
// Throw an error if Qty is bigger then Remaining
|
131 |
+
if ( $ticket->managing_stock() ) {
|
132 |
+
$inventory = (int) $ticket->inventory();
|
133 |
+
$inventory_is_not_unlimited = - 1 !== $inventory;
|
134 |
+
|
135 |
+
if ( $inventory_is_not_unlimited && $qty > $inventory ) {
|
136 |
+
return new WP_Error(
|
137 |
+
'tec-tc-ticket-insufficient-stock',
|
138 |
+
sprintf( __( 'Insufficient stock for "%1$s"', 'event-tickets' ), $ticket->name ),
|
139 |
+
[
|
140 |
+
'ticket' => $item['ticket_id'],
|
141 |
+
'order' => $order,
|
142 |
+
'new_status' => $this
|
143 |
+
]
|
144 |
+
);
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* @todo Determine if we need to check for the sale date.
|
150 |
+
*/
|
151 |
+
}
|
152 |
+
|
153 |
+
return true;
|
154 |
+
}
|
155 |
+
}
|
src/Tickets/Commerce/Status/Refunded.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Refunded.
|
7 |
+
*
|
8 |
+
*
|
9 |
+
* @since 5.1.9
|
10 |
+
*
|
11 |
+
* @package TEC\Tickets\Commerce\Status
|
12 |
+
*/
|
13 |
+
class Refunded extends Status_Abstract {
|
14 |
+
/**
|
15 |
+
* Slug for this Status.
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
const SLUG = 'refunded';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* {@inheritdoc}
|
25 |
+
*/
|
26 |
+
public function get_name() {
|
27 |
+
return __( 'Refunded', 'event-tickets' );
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* {@inheritdoc}
|
32 |
+
*/
|
33 |
+
protected $flags = [
|
34 |
+
'warning',
|
35 |
+
'count_refunded',
|
36 |
+
];
|
37 |
+
|
38 |
+
/**
|
39 |
+
* {@inheritdoc}
|
40 |
+
*/
|
41 |
+
protected $wp_arguments = [
|
42 |
+
'public' => true,
|
43 |
+
'exclude_from_search' => false,
|
44 |
+
'show_in_admin_all_list' => true,
|
45 |
+
'show_in_admin_status_list' => true,
|
46 |
+
];
|
47 |
+
}
|
src/Tickets/Commerce/Status/Reversed.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Refunded.
|
7 |
+
*
|
8 |
+
*
|
9 |
+
* @since 5.1.9
|
10 |
+
*
|
11 |
+
* @package TEC\Tickets\Commerce\Status
|
12 |
+
*/
|
13 |
+
class Reversed extends Status_Abstract {
|
14 |
+
/**
|
15 |
+
* Slug for this Status.
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
const SLUG = 'reversed';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* {@inheritdoc}
|
25 |
+
*/
|
26 |
+
public function get_name() {
|
27 |
+
return __( 'Reversed', 'event-tickets' );
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* {@inheritdoc}
|
32 |
+
*/
|
33 |
+
protected $flags = [
|
34 |
+
'warning',
|
35 |
+
'count_refunded',
|
36 |
+
];
|
37 |
+
|
38 |
+
/**
|
39 |
+
* {@inheritdoc}
|
40 |
+
*/
|
41 |
+
protected $wp_arguments = [
|
42 |
+
'public' => true,
|
43 |
+
'exclude_from_search' => false,
|
44 |
+
'show_in_admin_all_list' => true,
|
45 |
+
'show_in_admin_status_list' => true,
|
46 |
+
];
|
47 |
+
}
|
src/Tickets/Commerce/Status/Status_Abstract.php
ADDED
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Status_Abstract
|
9 |
+
*
|
10 |
+
* @since 5.1.9
|
11 |
+
*
|
12 |
+
* @package TEC\Tickets\Commerce\Status
|
13 |
+
*/
|
14 |
+
abstract class Status_Abstract implements Status_Interface {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Flags associated with this status, important to remember that the Flag Actions will be triggered in the order
|
18 |
+
* that these flags are returned.
|
19 |
+
*
|
20 |
+
* @see static::filter_get_flags
|
21 |
+
*
|
22 |
+
* List of pre-existing flags from TPP/Tribe Commerce:
|
23 |
+
*
|
24 |
+
* - incomplete
|
25 |
+
* - warning
|
26 |
+
* - attendee_generation
|
27 |
+
* - attendee_dispatch
|
28 |
+
* - stock_reduced
|
29 |
+
* - count_attendee
|
30 |
+
* - count_sales
|
31 |
+
* - count_completed
|
32 |
+
* - count_canceled
|
33 |
+
* - count_incomplete
|
34 |
+
* - count_refunded
|
35 |
+
* - count_not_going
|
36 |
+
*
|
37 |
+
* @since 5.1.9
|
38 |
+
*
|
39 |
+
* @var string[]
|
40 |
+
*/
|
41 |
+
protected $flags = [];
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Which arguments will be used to register this Status with WordPress.
|
45 |
+
*
|
46 |
+
* @since 5.1.9
|
47 |
+
*
|
48 |
+
* @var array
|
49 |
+
*/
|
50 |
+
protected $wp_arguments = [
|
51 |
+
|
52 |
+
];
|
53 |
+
|
54 |
+
/**
|
55 |
+
* {@inheritdoc}
|
56 |
+
*/
|
57 |
+
public function get_slug() {
|
58 |
+
return static::SLUG;
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* {@inheritdoc}
|
63 |
+
*/
|
64 |
+
public function get_wp_slug() {
|
65 |
+
return 'tec-' . Commerce::ABBR . '-' . static::SLUG;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* {@inheritdoc}
|
70 |
+
*/
|
71 |
+
public function get_flags() {
|
72 |
+
return $this->filter_get_flags( $this->flags );
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* {@inheritdoc}
|
77 |
+
*/
|
78 |
+
public function filter_get_flags( $flags ) {
|
79 |
+
/**
|
80 |
+
* Allows filtering of which flags are associated with this Status.
|
81 |
+
*
|
82 |
+
* @since 5.1.9
|
83 |
+
*
|
84 |
+
* @param string[] $flags Set of flags we will use.
|
85 |
+
* @param static $status Which status these flags are associated with.
|
86 |
+
*/
|
87 |
+
$flags = apply_filters( 'tec_tickets_commerce_order_status_get_flags', $flags, $this );
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Allows filtering of which flags are associated with this Status.
|
91 |
+
*
|
92 |
+
* @since 5.1.9
|
93 |
+
*
|
94 |
+
* @param string[] $flags Set of flags we will use.
|
95 |
+
* @param static $status Which status these flags are associated with.
|
96 |
+
*/
|
97 |
+
return apply_filters( "tec_tickets_commerce_order_status_{$this->get_slug()}_get_flags", $flags, $this );
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* {@inheritdoc}
|
102 |
+
*/
|
103 |
+
public function has_flags( $flags, $operator = 'AND' ) {
|
104 |
+
$intersection = array_intersect( (array) $flags, $this->get_flags() );
|
105 |
+
|
106 |
+
if ( 'AND' === strtoupper( $operator ) ) {
|
107 |
+
return count( $flags ) === count( $intersection );
|
108 |
+
}
|
109 |
+
|
110 |
+
return 0 < count( $intersection );
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* When trying to get a param that doesnt exist we test if it's a flag.
|
115 |
+
*
|
116 |
+
* @since 5.1.9
|
117 |
+
*
|
118 |
+
* @param string $name Which flag to check.
|
119 |
+
*
|
120 |
+
* @return bool
|
121 |
+
*/
|
122 |
+
public function __get( $name ) {
|
123 |
+
return $this->has_flags( $name );
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* {@inheritdoc}
|
128 |
+
*/
|
129 |
+
public function can_apply_to( $order ) {
|
130 |
+
return true;
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* {@inheritdoc}
|
135 |
+
*/
|
136 |
+
public function get_wp_arguments() {
|
137 |
+
$this->setup_wp_arguments();
|
138 |
+
|
139 |
+
$defaults = [
|
140 |
+
|
141 |
+
];
|
142 |
+
$arguments = array_merge( $defaults, $this->wp_arguments );
|
143 |
+
|
144 |
+
return $this->filter_wp_arguments( $arguments );
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* {@inheritdoc}
|
149 |
+
*/
|
150 |
+
public function filter_wp_arguments( array $arguments = [] ) {
|
151 |
+
/**
|
152 |
+
* Allows filtering of which arguments are associated with this Status registering in WP.
|
153 |
+
*
|
154 |
+
* @since 5.1.9
|
155 |
+
*
|
156 |
+
* @param array $arguments Which arguments we are passing.
|
157 |
+
* @param static $status Which status these arguments are associated with.
|
158 |
+
*/
|
159 |
+
$arguments = apply_filters( 'tec_tickets_commerce_order_status_get_wp_arguments', $arguments, $this );
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Allows filtering of which arguments are associated with this Status registering in WP.
|
163 |
+
*
|
164 |
+
* @since 5.1.9
|
165 |
+
*
|
166 |
+
* @param array $arguments Which arguments we are passing.
|
167 |
+
* @param static $status Which status these arguments are associated with.
|
168 |
+
*/
|
169 |
+
return apply_filters( "tec_tickets_commerce_order_status_{$this->get_slug()}_get_wp_arguments", $arguments, $this );
|
170 |
+
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Allows the configuration of the wp arguments before getting it, specifically used for dynamic arguments like
|
175 |
+
* the ones that will require a translation.
|
176 |
+
*
|
177 |
+
* @since 5.1.9
|
178 |
+
*
|
179 |
+
*/
|
180 |
+
protected function setup_wp_arguments() {
|
181 |
+
$this->wp_arguments['label'] = $this->get_name();
|
182 |
+
$this->wp_arguments['label_count'] = _n_noop( $this->get_name() . ' <span class="count">(%s)</span>', $this->get_name() . ' <span class="count">(%s)</span>', 'event-tickets' );
|
183 |
+
}
|
184 |
+
}
|
src/Tickets/Commerce/Status/Status_Handler.php
ADDED
@@ -0,0 +1,347 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Order;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Status_Handler
|
9 |
+
*
|
10 |
+
* @since 5.1.9
|
11 |
+
*
|
12 |
+
* @package TEC\Tickets\Commerce\Status
|
13 |
+
*/
|
14 |
+
class Status_Handler extends \tad_DI52_ServiceProvider {
|
15 |
+
/**
|
16 |
+
* Statuses registered.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @var Status_Interface[]
|
21 |
+
*/
|
22 |
+
protected $statuses = [];
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Which classes we will load for order statuses by default.
|
26 |
+
*
|
27 |
+
* @since 5.1.9
|
28 |
+
*
|
29 |
+
* @var string[]
|
30 |
+
*/
|
31 |
+
protected $default_statuses = [
|
32 |
+
Created::class,
|
33 |
+
Completed::class,
|
34 |
+
Denied::class,
|
35 |
+
Not_Completed::class,
|
36 |
+
Pending::class,
|
37 |
+
Refunded::class,
|
38 |
+
Reversed::class,
|
39 |
+
Undefined::class,
|
40 |
+
Voided::class,
|
41 |
+
];
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Which status every order will be created with.
|
45 |
+
*
|
46 |
+
* @since 5.1.9
|
47 |
+
*
|
48 |
+
* @var string
|
49 |
+
*/
|
50 |
+
protected $insert_status = Created::class;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Sets up all the Status instances for the Classes registered in $default_statuses.
|
54 |
+
*
|
55 |
+
* @since 5.1.9
|
56 |
+
*/
|
57 |
+
public function register() {
|
58 |
+
foreach ( $this->default_statuses as $status_class ) {
|
59 |
+
// Spawn the new instance.
|
60 |
+
$status = new $status_class;
|
61 |
+
|
62 |
+
// Register as a singleton for internal ease of use.
|
63 |
+
$this->container->singleton( $status_class, $status );
|
64 |
+
|
65 |
+
// Collect this particular status instance in this class.
|
66 |
+
$this->register_status( $status );
|
67 |
+
}
|
68 |
+
|
69 |
+
$this->container->singleton( static::class, $this );
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Which status an order will be created with.
|
74 |
+
*
|
75 |
+
* @since 5.1.9
|
76 |
+
*
|
77 |
+
* @return Status_Interface
|
78 |
+
*/
|
79 |
+
public function get_insert_status() {
|
80 |
+
return $this->container->make( $this->insert_status );
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Gets the statuses registered.
|
85 |
+
*
|
86 |
+
* @since 5.1.9
|
87 |
+
*
|
88 |
+
* @return Status_Interface[]
|
89 |
+
*/
|
90 |
+
public function get_all() {
|
91 |
+
return $this->statuses;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Fetches the first status registered with a given slug.
|
96 |
+
*
|
97 |
+
* @since 5.1.9
|
98 |
+
*
|
99 |
+
* @param string $slug
|
100 |
+
*
|
101 |
+
* @return Status_Interface|null
|
102 |
+
*/
|
103 |
+
public function get_by_slug( $slug ) {
|
104 |
+
foreach ( $this->get_all() as $status ) {
|
105 |
+
if ( $status->get_slug() === $slug ) {
|
106 |
+
return $status;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
return null;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Fetches the first status registered with a given wp slug.
|
115 |
+
*
|
116 |
+
* @since 5.1.9
|
117 |
+
*
|
118 |
+
* @param string $slug
|
119 |
+
*
|
120 |
+
* @return Status_Interface
|
121 |
+
*/
|
122 |
+
public function get_by_wp_slug( $slug ) {
|
123 |
+
foreach ( $this->get_all() as $status ) {
|
124 |
+
if ( $status->get_wp_slug() === $slug ) {
|
125 |
+
return $status;
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
return null;
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Fetches the status registered with a given class.
|
134 |
+
*
|
135 |
+
* @since 5.1.9
|
136 |
+
*
|
137 |
+
* @param string $class_name
|
138 |
+
*
|
139 |
+
* @return Status_Interface
|
140 |
+
*/
|
141 |
+
public function get_by_class( $class_name ) {
|
142 |
+
foreach ( $this->get_all() as $status ) {
|
143 |
+
$status_class = get_class( $status );
|
144 |
+
|
145 |
+
if ( $status_class === $class_name ) {
|
146 |
+
return $status;
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
return null;
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Using `wp_list_filter` fetches which Statuses match the flags and operator passed.
|
155 |
+
*
|
156 |
+
* @since 5.1.9
|
157 |
+
*
|
158 |
+
* @param string|array $flags
|
159 |
+
* @param string $operator
|
160 |
+
*
|
161 |
+
* @return Status_Interface[]
|
162 |
+
*/
|
163 |
+
public function get_by_flags( $flags, $operator = 'AND' ) {
|
164 |
+
$statuses = wp_list_filter( $this->get_all(), (array) $flags, $operator );
|
165 |
+
|
166 |
+
return $statuses;
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Register a given status into the Handler.
|
171 |
+
*
|
172 |
+
* @since 5.1.9
|
173 |
+
*
|
174 |
+
* @param Status_Interface $status Which status we are registering.
|
175 |
+
*/
|
176 |
+
public function register_status( Status_Interface $status ) {
|
177 |
+
$this->statuses[] = $status;
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Registers the post statuses with WordPress.
|
182 |
+
*
|
183 |
+
* @since 5.1.9
|
184 |
+
*/
|
185 |
+
public function register_order_statuses() {
|
186 |
+
|
187 |
+
$statuses = $this->get_all();
|
188 |
+
|
189 |
+
foreach ( $statuses as $status ) {
|
190 |
+
register_post_status(
|
191 |
+
$status->get_wp_slug(),
|
192 |
+
$status->get_wp_arguments()
|
193 |
+
);
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Fires when a post is transitioned from one status to another so that we can make another hook that is namespaced.
|
199 |
+
*
|
200 |
+
* @since 5.1.9
|
201 |
+
*
|
202 |
+
* @param string $new_status New post status.
|
203 |
+
* @param string $old_status Old post status.
|
204 |
+
* @param \WP_Post $post Post object.
|
205 |
+
*/
|
206 |
+
public function transition_order_post_status_hooks( $new_status, $old_status, $post ) {
|
207 |
+
if ( Order::POSTTYPE !== $post->post_type ) {
|
208 |
+
return;
|
209 |
+
}
|
210 |
+
|
211 |
+
$new_status = $this->get_by_wp_slug( $new_status );
|
212 |
+
$old_status = $this->get_by_wp_slug( $old_status );
|
213 |
+
|
214 |
+
if ( ! isset( $new_status ) ) {
|
215 |
+
return;
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Fires when a post is transitioned from one status to another.
|
220 |
+
*
|
221 |
+
* @since 5.1.9
|
222 |
+
*
|
223 |
+
* @param Status_Interface $new_status New post status.
|
224 |
+
* @param Status_Interface|null $old_status Old post status.
|
225 |
+
* @param \WP_Post $post Post object.
|
226 |
+
*/
|
227 |
+
do_action( 'tec_tickets_commerce_order_status_transition', $new_status, $old_status, $post );
|
228 |
+
|
229 |
+
if ( $old_status ) {
|
230 |
+
/**
|
231 |
+
* Fires when a post is transitioned from one status to another.
|
232 |
+
*
|
233 |
+
* The dynamic portions of the hook name, `$new_status` and `$old_status`,
|
234 |
+
* refer to the old and new post statuses, respectively.
|
235 |
+
*
|
236 |
+
* @since 5.1.9
|
237 |
+
*
|
238 |
+
* @param Status_Interface $new_status New post status.
|
239 |
+
* @param Status_Interface|null $old_status Old post status.
|
240 |
+
* @param \WP_Post $post Post object.
|
241 |
+
*/
|
242 |
+
do_action( "tec_tickets_commerce_order_status_{$old_status->get_slug()}_to_{$new_status->get_slug()}", $new_status, $old_status, $post );
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Fires when a post is transitioned from one status to another.
|
247 |
+
*
|
248 |
+
* The dynamic portions of the hook name, `$new_status`, refer to the new post status.
|
249 |
+
*
|
250 |
+
* @since 5.1.9
|
251 |
+
*
|
252 |
+
* @param Status_Interface $new_status New post status.
|
253 |
+
* @param Status_Interface|null $old_status Old post status.
|
254 |
+
* @param \WP_Post $post Post object.
|
255 |
+
*/
|
256 |
+
do_action( "tec_tickets_commerce_order_status_{$new_status->get_slug()}", $new_status, $old_status, $post );
|
257 |
+
|
258 |
+
$this->trigger_status_hooks_by_flags( $new_status, $old_status, $post );
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* When a given order is transitioned from a status to another we will pull all it's flags and trigger a couple of
|
263 |
+
* extra hooks so that all the required actions can be triggered, examples:
|
264 |
+
* - Generating Attendees
|
265 |
+
* - Re-stocking ticket/event
|
266 |
+
* - Throwing a warning
|
267 |
+
* - Handling Email communication
|
268 |
+
*
|
269 |
+
* @since 5.1.9
|
270 |
+
*
|
271 |
+
* @param Status_Interface $new_status New post status.
|
272 |
+
* @param Status_Interface|null $old_status Old post status.
|
273 |
+
* @param \WP_Post $post Post object.
|
274 |
+
*/
|
275 |
+
public function trigger_status_hooks_by_flags( Status_Interface $new_status, $old_status, $post ) {
|
276 |
+
$flags = $new_status->get_flags();
|
277 |
+
|
278 |
+
foreach ( $flags as $flag ) {
|
279 |
+
/**
|
280 |
+
* Fires when a post is transitioned from one status to another and contains a given flag.
|
281 |
+
*
|
282 |
+
* The dynamic portions of the hook name, `$flag`, refer to a given flag that this new status contains.
|
283 |
+
*
|
284 |
+
* @since 5.1.9
|
285 |
+
*
|
286 |
+
* @param Status_Interface $new_status New post status.
|
287 |
+
* @param Status_Interface|null $old_status Old post status.
|
288 |
+
* @param \WP_Post $post Post object.
|
289 |
+
*/
|
290 |
+
do_action( "tec_tickets_commerce_order_status_flag_{$flag}", $new_status, $old_status, $post );
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Fires when a post is transitioned from one status to another and contains a given flag.
|
294 |
+
*
|
295 |
+
* The dynamic portions of the hook name, `$new_status` and `$flag`, refer to the new post status and a
|
296 |
+
* given flag that this new status contains.
|
297 |
+
*
|
298 |
+
* @since 5.1.9
|
299 |
+
*
|
300 |
+
* @param Status_Interface $new_status New post status.
|
301 |
+
* @param Status_Interface|null $old_status Old post status.
|
302 |
+
* @param \WP_Post $post Post object.
|
303 |
+
*/
|
304 |
+
do_action( "tec_tickets_commerce_order_status_{$new_status->get_slug()}_flag_{$flag}", $new_status, $old_status, $post );
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Whether an order status will mark a transaction as completed one way or another.
|
310 |
+
*
|
311 |
+
* A transaction might be completed because it successfully completed, because it
|
312 |
+
* was refunded or denied.
|
313 |
+
*
|
314 |
+
* @since 5.1.9
|
315 |
+
*
|
316 |
+
* @param string $payment_status
|
317 |
+
*
|
318 |
+
* @return bool
|
319 |
+
*/
|
320 |
+
public function is_complete_transaction_status( $payment_status ) {
|
321 |
+
$statuses = $this->get_by_flags( [ 'count_completed', 'count_refunded' ], 'OR' );
|
322 |
+
$statuses = array_map( static function ( $status ) {
|
323 |
+
return $status->get_slug();
|
324 |
+
}, $statuses );
|
325 |
+
|
326 |
+
return in_array( $payment_status, $statuses, true );
|
327 |
+
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Whether an order status will mark a transaction as generating revenue or not.
|
332 |
+
*
|
333 |
+
* @since 5.1.9
|
334 |
+
*
|
335 |
+
* @param string $payment_status
|
336 |
+
*
|
337 |
+
* @return bool
|
338 |
+
*/
|
339 |
+
public function is_revenue_generating_status( $payment_status ) {
|
340 |
+
$statuses = $this->get_by_flags( 'count_completed' );
|
341 |
+
$statuses = array_map( static function ( $status ) {
|
342 |
+
return $status->get_slug();
|
343 |
+
}, $statuses );
|
344 |
+
|
345 |
+
return in_array( $payment_status, $statuses, true );
|
346 |
+
}
|
347 |
+
}
|
src/Tickets/Commerce/Status/Status_Interface.php
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Status_Interface
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce\Status
|
11 |
+
*/
|
12 |
+
interface Status_Interface {
|
13 |
+
/**
|
14 |
+
* Gets the slug of this status in WordPress
|
15 |
+
*
|
16 |
+
* @since 5.1.9
|
17 |
+
*
|
18 |
+
* @return string
|
19 |
+
*/
|
20 |
+
public function get_wp_slug();
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Filters and returns the flags for the get_flags method.
|
24 |
+
*
|
25 |
+
* @since 5.1.9
|
26 |
+
*
|
27 |
+
* @param string[] $flags Which flags will be filtered.
|
28 |
+
*
|
29 |
+
* @return string[]
|
30 |
+
*/
|
31 |
+
public function filter_get_flags( $flags );
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Gets the name of this status.
|
35 |
+
*
|
36 |
+
* @since 5.1.9
|
37 |
+
*
|
38 |
+
* @return string
|
39 |
+
*/
|
40 |
+
public function get_name();
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Gets the constant slug of this status.
|
44 |
+
*
|
45 |
+
* @since 5.1.9
|
46 |
+
*
|
47 |
+
* @return string
|
48 |
+
*/
|
49 |
+
public function get_slug();
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Gets the flags associated with this status.
|
53 |
+
*
|
54 |
+
* @since 5.1.9
|
55 |
+
*
|
56 |
+
* @return array
|
57 |
+
*/
|
58 |
+
public function get_flags();
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Determines if this Status has a set of flags.
|
62 |
+
*
|
63 |
+
* @since 5.1.9
|
64 |
+
*
|
65 |
+
* @param array|string $flags Which flags we are testing.
|
66 |
+
* @param string $operator Operator for the test.
|
67 |
+
*
|
68 |
+
* @return bool
|
69 |
+
*/
|
70 |
+
public function has_flags( $flags, $operator = 'AND' );
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Determines if a given order can be modified to this status.
|
75 |
+
*
|
76 |
+
* @since 5.1.9
|
77 |
+
*
|
78 |
+
* @param int|\WP_Post $order Which order we are testing against.
|
79 |
+
*
|
80 |
+
* @return boolean|\WP_Error
|
81 |
+
*/
|
82 |
+
public function can_apply_to( $order );
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Filters the WP arguments used to register the status.
|
86 |
+
*
|
87 |
+
* @since 5.1.9
|
88 |
+
*
|
89 |
+
* @param array $arguments Which arguments we are passing.
|
90 |
+
*
|
91 |
+
* @return array
|
92 |
+
*/
|
93 |
+
public function filter_wp_arguments( array $arguments = [] );
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Fetches the WordPress arguments required to register this Status.
|
97 |
+
*
|
98 |
+
* @since 5.1.9
|
99 |
+
*
|
100 |
+
* @return array
|
101 |
+
*/
|
102 |
+
public function get_wp_arguments();
|
103 |
+
}
|
src/Tickets/Commerce/Status/Undefined.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Undefined.
|
7 |
+
*
|
8 |
+
* Orders that landed on Undefined are just broken in some way that we cannot define.
|
9 |
+
*
|
10 |
+
* @since 5.1.9
|
11 |
+
*
|
12 |
+
* @package TEC\Tickets\Commerce\Status
|
13 |
+
*/
|
14 |
+
class Undefined extends Status_Abstract {
|
15 |
+
/**
|
16 |
+
* Slug for this Status.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
const SLUG = 'undefined';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* {@inheritdoc}
|
26 |
+
*/
|
27 |
+
public function get_name() {
|
28 |
+
return __( 'Undefined', 'event-tickets' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* {@inheritdoc}
|
33 |
+
*/
|
34 |
+
protected $flags = [
|
35 |
+
'count_incomplete',
|
36 |
+
'incomplete',
|
37 |
+
'warning',
|
38 |
+
];
|
39 |
+
|
40 |
+
/**
|
41 |
+
* {@inheritdoc}
|
42 |
+
*/
|
43 |
+
protected $wp_arguments = [
|
44 |
+
'public' => true,
|
45 |
+
'exclude_from_search' => false,
|
46 |
+
'show_in_admin_all_list' => true,
|
47 |
+
'show_in_admin_status_list' => true,
|
48 |
+
];
|
49 |
+
}
|
src/Tickets/Commerce/Status/Voided.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Status;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Voided.
|
7 |
+
*
|
8 |
+
* Normally when an Order is Voided means the the Authorization for payment failed. Which means this order needs to be
|
9 |
+
* ignored and refunded, since it's a status that cannot be reversed into complete or anything else.
|
10 |
+
*
|
11 |
+
* @since 5.1.9
|
12 |
+
*
|
13 |
+
* @package TEC\Tickets\Commerce\Status
|
14 |
+
*/
|
15 |
+
class Voided extends Status_Abstract {
|
16 |
+
/**
|
17 |
+
* Slug for this Status.
|
18 |
+
*
|
19 |
+
* @since 5.1.9
|
20 |
+
*
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
const SLUG = 'voided';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* {@inheritdoc}
|
27 |
+
*/
|
28 |
+
public function get_name() {
|
29 |
+
return __( 'Voided', 'event-tickets' );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* {@inheritdoc}
|
34 |
+
*/
|
35 |
+
protected $flags = [
|
36 |
+
'count_refunded',
|
37 |
+
'warning',
|
38 |
+
];
|
39 |
+
|
40 |
+
/**
|
41 |
+
* {@inheritdoc}
|
42 |
+
*/
|
43 |
+
protected $wp_arguments = [
|
44 |
+
'public' => true,
|
45 |
+
'exclude_from_search' => false,
|
46 |
+
'show_in_admin_all_list' => true,
|
47 |
+
'show_in_admin_status_list' => true,
|
48 |
+
];
|
49 |
+
}
|
50 |
+
|
src/Tickets/Commerce/Success.php
ADDED
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Success
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce
|
11 |
+
*/
|
12 |
+
class Success {
|
13 |
+
/**
|
14 |
+
* Param we use to store the order ID.
|
15 |
+
*
|
16 |
+
* @since 5.1.9
|
17 |
+
*
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
public static $order_id_query_arg = 'tc-order-id';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Get the Success page ID.
|
24 |
+
*
|
25 |
+
* @since 5.1.9
|
26 |
+
*
|
27 |
+
*
|
28 |
+
* @return int|null
|
29 |
+
*/
|
30 |
+
public function get_page_id() {
|
31 |
+
$success_page = (int) tribe_get_option( Settings::$option_success_page );
|
32 |
+
|
33 |
+
if ( empty( $success_page ) ) {
|
34 |
+
return null;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Allows filtering of the Page ID for the Success page.
|
39 |
+
*
|
40 |
+
* @since 5.1.9
|
41 |
+
*
|
42 |
+
* @param int|null $success_page Which page is used in the settings.
|
43 |
+
*/
|
44 |
+
return apply_filters( 'tec_tickets_commerce_success_page_id', $success_page );
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Determine the Current success URL.
|
49 |
+
*
|
50 |
+
* @since 5.1.9
|
51 |
+
*
|
52 |
+
* @return string
|
53 |
+
*/
|
54 |
+
public function get_url() {
|
55 |
+
$url = home_url( '/' );
|
56 |
+
$success_page = $this->get_page_id();
|
57 |
+
|
58 |
+
if ( is_numeric( $success_page ) ) {
|
59 |
+
$success_page = get_post( $success_page );
|
60 |
+
}
|
61 |
+
|
62 |
+
// Only modify the URL in case we have a success page setup in the settings.
|
63 |
+
if ( $success_page instanceof \WP_Post ) {
|
64 |
+
$url = get_the_permalink( $success_page );
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Allows modifications to the success url for Tickets Commerce.
|
69 |
+
*
|
70 |
+
* @since 5.1.9
|
71 |
+
*
|
72 |
+
* @param string $url URL for the cart.
|
73 |
+
*/
|
74 |
+
return (string) apply_filters( 'tec_tickets_commerce_success_url', $url );
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Determines if the current page is the success page.
|
79 |
+
*
|
80 |
+
* @since 5.1.9
|
81 |
+
*
|
82 |
+
*
|
83 |
+
* @return bool
|
84 |
+
*/
|
85 |
+
public function is_current_page() {
|
86 |
+
if ( is_admin() ) {
|
87 |
+
return false;
|
88 |
+
}
|
89 |
+
|
90 |
+
$current_page = get_queried_object_id();
|
91 |
+
$is_current_page = $this->get_page_id() === $current_page;
|
92 |
+
|
93 |
+
/**
|
94 |
+
* @todo determine hte usage of tribe_ticket_redirect_to
|
95 |
+
* $redirect = tribe_get_request_var( 'tribe_tickets_redirect_to', null );
|
96 |
+
*/
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Allows modifications to the conditional of if we are in the success page.
|
100 |
+
*
|
101 |
+
* @since 5.1.9
|
102 |
+
*
|
103 |
+
* @param bool $is_current_page Are we in the current page for checkout.
|
104 |
+
*/
|
105 |
+
return tribe_is_truthy( apply_filters( 'tec_tickets_commerce_success_is_current_page', $is_current_page ) );
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* If there is any data or request management or parsing that needs to happen on the success page here is where
|
110 |
+
* we do it.
|
111 |
+
*
|
112 |
+
* @since 5.1.9
|
113 |
+
*/
|
114 |
+
public function parse_request() {
|
115 |
+
if ( ! $this->is_current_page() ) {
|
116 |
+
return;
|
117 |
+
}
|
118 |
+
|
119 |
+
// In case the ID is passed we set the cookie for usage.
|
120 |
+
$cookie_param = tribe_get_request_var( Cart::$cookie_query_arg, false );
|
121 |
+
if ( $cookie_param ) {
|
122 |
+
tribe( Cart::class )->set_cart_hash_cookie( $cookie_param );
|
123 |
+
}
|
124 |
+
}
|
125 |
+
}
|
src/Tickets/Commerce/Ticket.php
ADDED
@@ -0,0 +1,768 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce;
|
4 |
+
|
5 |
+
use TEC\Tickets\Commerce\Status\Denied;
|
6 |
+
use TEC\Tickets\Commerce\Status\Pending;
|
7 |
+
use TEC\Tickets\Event;
|
8 |
+
|
9 |
+
use Tribe__Utils__Array as Arr;
|
10 |
+
use Tribe__Tickets__Global_Stock as Event_Stock;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Class Ticket.
|
14 |
+
*
|
15 |
+
* @since 5.1.9
|
16 |
+
*
|
17 |
+
* @package TEC\Tickets\Commerce
|
18 |
+
*/
|
19 |
+
class Ticket {
|
20 |
+
/**
|
21 |
+
* Tickets Commerce Ticket Post Type slug.
|
22 |
+
*
|
23 |
+
* @since 5.1.9
|
24 |
+
*
|
25 |
+
* @var string
|
26 |
+
*/
|
27 |
+
const POSTTYPE = 'tec_tc_ticket';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Which meta holds the Relation ship between an ticket and which event it's registered to.
|
31 |
+
*
|
32 |
+
* @since 5.1.9
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
public static $event_relation_meta_key = '_tec_tickets_commerce_event';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Which meta holds the data for showing the ticket description.
|
40 |
+
*
|
41 |
+
* @since 5.1.9
|
42 |
+
*
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
public static $show_description_meta_key = '_tribe_ticket_show_description';
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Which meta holds the data for the ticket sku.
|
49 |
+
*
|
50 |
+
* @since 5.1.9
|
51 |
+
*
|
52 |
+
* @var string
|
53 |
+
*/
|
54 |
+
public static $sku_meta_key = '_sku';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Which meta holds the data for the ticket price.
|
58 |
+
*
|
59 |
+
* @since 5.1.9
|
60 |
+
*
|
61 |
+
* @var string
|
62 |
+
*/
|
63 |
+
public static $price_meta_key = '_price';
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Which meta holds the data for the ticket stock mode.
|
67 |
+
*
|
68 |
+
* @since 5.1.9
|
69 |
+
*
|
70 |
+
* @var string
|
71 |
+
*/
|
72 |
+
public static $stock_mode_meta_key = Event_Stock::TICKET_STOCK_MODE;
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Which meta holds the data for the ticket stock.
|
76 |
+
*
|
77 |
+
* @since 5.1.9
|
78 |
+
*
|
79 |
+
* @var string
|
80 |
+
*/
|
81 |
+
public static $stock_meta_key = '_stock';
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Which meta holds the data for the ticket stock status.
|
85 |
+
*
|
86 |
+
* @since 5.1.9
|
87 |
+
*
|
88 |
+
* @var string
|
89 |
+
*/
|
90 |
+
public static $stock_status_meta_key = '_stock_status';
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Which meta holds the data for the ticket allows backorders.
|
94 |
+
*
|
95 |
+
* @since 5.1.9
|
96 |
+
*
|
97 |
+
* @var string
|
98 |
+
*/
|
99 |
+
public static $allow_backorders_meta_key = '_backorders';
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Which meta holds the data for the ticket is managing stock.
|
103 |
+
*
|
104 |
+
* @since 5.1.9
|
105 |
+
*
|
106 |
+
* @var string
|
107 |
+
*/
|
108 |
+
public static $should_manage_stock_meta_key = '_manage_stock';
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Register this Class post type into WP.
|
112 |
+
*
|
113 |
+
* @since 5.1.9
|
114 |
+
*/
|
115 |
+
public function register_post_type() {
|
116 |
+
|
117 |
+
$post_type_args = [
|
118 |
+
'label' => __( 'Tickets', 'event-tickets' ),
|
119 |
+
'labels' => [
|
120 |
+
'name' => __( 'Tickets Commerce Tickets', 'event-tickets' ),
|
121 |
+
'singular_name' => __( 'Tickets Commerce Ticket', 'event-tickets' ),
|
122 |
+
],
|
123 |
+
'public' => false,
|
124 |
+
'show_ui' => false,
|
125 |
+
'show_in_menu' => false,
|
126 |
+
'query_var' => false,
|
127 |
+
'rewrite' => false,
|
128 |
+
'capability_type' => 'post',
|
129 |
+
'has_archive' => false,
|
130 |
+
'hierarchical' => false,
|
131 |
+
];
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Filter the arguments that craft the ticket post type.
|
135 |
+
*
|
136 |
+
* @see register_post_type
|
137 |
+
*
|
138 |
+
* @since 5.1.9
|
139 |
+
*
|
140 |
+
* @param array $post_type_args Post type arguments, passed to register_post_type()
|
141 |
+
*/
|
142 |
+
$post_type_args = apply_filters( 'tec_tickets_commerce_ticket_post_type_args', $post_type_args );
|
143 |
+
|
144 |
+
register_post_type( static::POSTTYPE, $post_type_args );
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Gets an individual ticket.
|
149 |
+
*
|
150 |
+
* @todo TribeCommerceLegacy: This method needs to make use of the Ticket Model.
|
151 |
+
*
|
152 |
+
* @since 5.1.9
|
153 |
+
*
|
154 |
+
* @param int|\WP_Post $ticket_id
|
155 |
+
*
|
156 |
+
* @return null|\Tribe__Tickets__Ticket_Object
|
157 |
+
*/
|
158 |
+
public function get_ticket( $ticket_id ) {
|
159 |
+
$product = get_post( $ticket_id );
|
160 |
+
|
161 |
+
if ( ! $product ) {
|
162 |
+
return null;
|
163 |
+
}
|
164 |
+
|
165 |
+
$event_id = get_post_meta( $ticket_id, static::$event_relation_meta_key, true );
|
166 |
+
|
167 |
+
$return = new \Tribe__Tickets__Ticket_Object();
|
168 |
+
|
169 |
+
$qty_sold = get_post_meta( $ticket_id, 'total_sales', true );
|
170 |
+
|
171 |
+
$return->description = $product->post_excerpt;
|
172 |
+
$return->ID = $ticket_id;
|
173 |
+
$return->name = $product->post_title;
|
174 |
+
$return->menu_order = $product->menu_order;
|
175 |
+
$return->post_type = $product->post_type;
|
176 |
+
$return->price = get_post_meta( $ticket_id, '_price', true );
|
177 |
+
$return->provider_class = Module::class;
|
178 |
+
$return->admin_link = '';
|
179 |
+
$return->show_description = $return->show_description();
|
180 |
+
$return->start_date = get_post_meta( $ticket_id, '_ticket_start_date', true );
|
181 |
+
$return->end_date = get_post_meta( $ticket_id, '_ticket_end_date', true );
|
182 |
+
$return->start_time = get_post_meta( $ticket_id, '_ticket_start_time', true );
|
183 |
+
$return->end_time = get_post_meta( $ticket_id, '_ticket_end_time', true );
|
184 |
+
$return->sku = get_post_meta( $ticket_id, '_sku', true );
|
185 |
+
|
186 |
+
// If the quantity sold wasn't set, default to zero
|
187 |
+
$qty_sold = $qty_sold ? $qty_sold : 0;
|
188 |
+
|
189 |
+
// Ticket stock is a simple reflection of remaining inventory for this item...
|
190 |
+
$stock = (int) get_post_meta( $ticket_id, '_stock', true );
|
191 |
+
|
192 |
+
// If we don't have a stock value, then stock should be considered 'unlimited'
|
193 |
+
if ( null === $stock ) {
|
194 |
+
$stock = - 1;
|
195 |
+
}
|
196 |
+
|
197 |
+
$return->manage_stock( 'yes' === get_post_meta( $ticket_id, '_manage_stock', true ) );
|
198 |
+
$return->stock( $stock );
|
199 |
+
$return->global_stock_mode( get_post_meta( $ticket_id, \Tribe__Tickets__Global_Stock::TICKET_STOCK_MODE, true ) );
|
200 |
+
$capped = get_post_meta( $ticket_id, \Tribe__Tickets__Global_Stock::TICKET_STOCK_CAP, true );
|
201 |
+
|
202 |
+
if ( '' !== $capped ) {
|
203 |
+
$return->global_stock_cap( $capped );
|
204 |
+
}
|
205 |
+
|
206 |
+
$qty_cancelled = $this->get_cancelled( $ticket_id );
|
207 |
+
|
208 |
+
// Manually add cancelled to sold so that we can remove it correctly later when calculating.
|
209 |
+
$return->qty_sold( $qty_sold + $qty_cancelled );
|
210 |
+
|
211 |
+
$return->qty_cancelled( $qty_cancelled );
|
212 |
+
|
213 |
+
$pending = $this->get_qty_pending( $ticket_id );
|
214 |
+
|
215 |
+
$return->qty_pending( $pending );
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Use this Filter to change any information you want about this ticket
|
219 |
+
*
|
220 |
+
* @since 5.1.9
|
221 |
+
*
|
222 |
+
* @param object $ticket
|
223 |
+
* @param int $post_id
|
224 |
+
* @param int $ticket_id
|
225 |
+
*/
|
226 |
+
$return = apply_filters( 'tec_tickets_commerce_get_ticket_legacy', $return, $event_id, $ticket_id );
|
227 |
+
|
228 |
+
return $return;
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Returns the total number of cancelled tickets.
|
233 |
+
*
|
234 |
+
* @todo TribeCommerceLegacy: Move this method into the another place.
|
235 |
+
*
|
236 |
+
* @since 5.1.9
|
237 |
+
*
|
238 |
+
* @param int $ticket_id The ticket post ID.
|
239 |
+
*
|
240 |
+
* @return int
|
241 |
+
*/
|
242 |
+
protected function get_cancelled( $ticket_id ) {
|
243 |
+
$denied_orders = \Tribe__Tickets__Commerce__PayPal__Order::find_by( array(
|
244 |
+
'ticket_id' => $ticket_id,
|
245 |
+
'post_status' => Denied::SLUG,
|
246 |
+
'posts_per_page' => - 1,
|
247 |
+
), [
|
248 |
+
'items',
|
249 |
+
] );
|
250 |
+
|
251 |
+
$denied = 0;
|
252 |
+
foreach ( $denied_orders as $denied_order ) {
|
253 |
+
$denied += $denied_order->get_item_quantity( $ticket_id );
|
254 |
+
}
|
255 |
+
|
256 |
+
return max( 0, $denied );
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Returns the number of pending attendees by ticket.
|
261 |
+
*
|
262 |
+
* @todo TribeCommerceLegacy: Move this method into the another place.
|
263 |
+
*
|
264 |
+
* @since 5.1.9
|
265 |
+
*
|
266 |
+
* @param int $ticket_id The ticket post ID
|
267 |
+
* @param bool $refresh Whether to try and use the cached value or not.
|
268 |
+
*
|
269 |
+
* @return int
|
270 |
+
*/
|
271 |
+
public function get_qty_pending( $ticket_id, $refresh = false ) {
|
272 |
+
static $pending_attendees_by_ticket = [];
|
273 |
+
|
274 |
+
if ( $refresh || empty( $pending_attendees_by_ticket[ $ticket_id ] ) ) {
|
275 |
+
$pending_query = new \WP_Query( [
|
276 |
+
'fields' => 'ids',
|
277 |
+
'per_page' => 1,
|
278 |
+
'post_type' => Attendee::POSTTYPE,
|
279 |
+
'meta_query' => [
|
280 |
+
[
|
281 |
+
'key' => Attendee::$event_relation_meta_key,
|
282 |
+
'value' => $ticket_id,
|
283 |
+
],
|
284 |
+
'relation' => 'AND',
|
285 |
+
[
|
286 |
+
'key' => Attendee::$status_meta_key,
|
287 |
+
'value' => tribe( Pending::class )->get_wp_slug(),
|
288 |
+
],
|
289 |
+
],
|
290 |
+
] );
|
291 |
+
|
292 |
+
$pending_attendees_by_ticket[ $ticket_id ] = $pending_query->found_posts;
|
293 |
+
}
|
294 |
+
|
295 |
+
return $pending_attendees_by_ticket[ $ticket_id ];
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Legacy method ported from Tribe Commerce (TPP), we are specifically avoiding refactoring anything on the first
|
300 |
+
* stage of Tickets Commerce
|
301 |
+
*
|
302 |
+
* @todo TribeCommerceLegacy: This method needs to be split into `create` and `update`
|
303 |
+
*
|
304 |
+
* @since 5.1.9
|
305 |
+
*
|
306 |
+
* @param $post_id
|
307 |
+
* @param $ticket
|
308 |
+
* @param array $raw_data
|
309 |
+
*
|
310 |
+
* @return false|int|\WP_Error
|
311 |
+
*/
|
312 |
+
public function save( $post_id, $ticket, $raw_data = [] ) {
|
313 |
+
$save_type = 'update';
|
314 |
+
|
315 |
+
if ( empty( $ticket->ID ) ) {
|
316 |
+
$save_type = 'create';
|
317 |
+
|
318 |
+
/* Create main product post */
|
319 |
+
$args = array(
|
320 |
+
'post_status' => 'publish',
|
321 |
+
'post_type' => static::POSTTYPE,
|
322 |
+
'post_author' => get_current_user_id(),
|
323 |
+
'post_excerpt' => $ticket->description,
|
324 |
+
'post_title' => $ticket->name,
|
325 |
+
'menu_order' => tribe_get_request_var( 'menu_order', - 1 ),
|
326 |
+
);
|
327 |
+
|
328 |
+
$ticket->ID = wp_insert_post( $args );
|
329 |
+
|
330 |
+
// Relate event <---> ticket
|
331 |
+
add_post_meta( $ticket->ID, static::$event_relation_meta_key, $post_id );
|
332 |
+
|
333 |
+
} else {
|
334 |
+
$args = array(
|
335 |
+
'ID' => $ticket->ID,
|
336 |
+
'post_excerpt' => $ticket->description,
|
337 |
+
'post_title' => $ticket->name,
|
338 |
+
'menu_order' => $ticket->menu_order,
|
339 |
+
);
|
340 |
+
|
341 |
+
$ticket->ID = wp_update_post( $args );
|
342 |
+
}
|
343 |
+
|
344 |
+
if ( ! $ticket->ID ) {
|
345 |
+
return false;
|
346 |
+
}
|
347 |
+
|
348 |
+
/** @var \Tribe__Tickets__Tickets_Handler $tickets_handler */
|
349 |
+
$tickets_handler = tribe( 'tickets.handler' );
|
350 |
+
|
351 |
+
// Updates if we should show Description.
|
352 |
+
$ticket->show_description = isset( $ticket->show_description ) && tribe_is_truthy( $ticket->show_description ) ? 'yes' : 'no';
|
353 |
+
update_post_meta( $ticket->ID, $tickets_handler->key_show_description, $ticket->show_description );
|
354 |
+
|
355 |
+
// let's make sure float price values are formatted to "0.xyz"
|
356 |
+
if ( is_numeric( $ticket->price ) ) {
|
357 |
+
$ticket->price = (string) (int) $ticket->price === $ticket->price
|
358 |
+
? (int) $ticket->price
|
359 |
+
: (float) $ticket->price;
|
360 |
+
}
|
361 |
+
|
362 |
+
update_post_meta( $ticket->ID, '_price', $ticket->price );
|
363 |
+
|
364 |
+
$ticket_data = \Tribe__Utils__Array::get( $raw_data, 'tribe-ticket', array() );
|
365 |
+
tribe( Module::class )->update_capacity( $ticket, $ticket_data, $save_type );
|
366 |
+
|
367 |
+
foreach ( [ 'start_date', 'start_time', 'end_date', 'end_time' ] as $time_key ) {
|
368 |
+
if ( isset( $ticket->{$time_key} ) ) {
|
369 |
+
update_post_meta( $ticket->ID, "_ticket_{$time_key}", $ticket->{$time_key} );
|
370 |
+
} else {
|
371 |
+
delete_post_meta( $ticket->ID, "_ticket_{$time_key}" );
|
372 |
+
}
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Toggle filter to allow skipping the automatic SKU generation.
|
377 |
+
*
|
378 |
+
* @param bool $should_default_ticket_sku
|
379 |
+
*/
|
380 |
+
$should_default_ticket_sku = apply_filters( 'tribe_tickets_should_default_ticket_sku', true );
|
381 |
+
if ( $should_default_ticket_sku ) {
|
382 |
+
// make sure the SKU is set to the correct value
|
383 |
+
if ( ! empty( $raw_data['ticket_sku'] ) ) {
|
384 |
+
$sku = $raw_data['ticket_sku'];
|
385 |
+
} else {
|
386 |
+
$post_author = get_post( $ticket->ID )->post_author;
|
387 |
+
$str = $raw_data['ticket_name'];
|
388 |
+
$str = tribe_strtoupper( $str );
|
389 |
+
$sku = "{$ticket->ID}-{$post_author}-" . str_replace( ' ', '-', $str );
|
390 |
+
$raw_data['ticket_sku'] = $sku;
|
391 |
+
}
|
392 |
+
update_post_meta( $ticket->ID, '_sku', $sku );
|
393 |
+
}
|
394 |
+
|
395 |
+
// Fetches all Ticket Form data
|
396 |
+
$data = \Tribe__Utils__Array::get( $raw_data, 'tribe-ticket', array() );
|
397 |
+
|
398 |
+
// Fetch the Global stock Instance for this Event
|
399 |
+
$event_stock = new \Tribe__Tickets__Global_Stock( $post_id );
|
400 |
+
|
401 |
+
// Only need to do this if we haven't already set one - they shouldn't be able to edit it from here otherwise
|
402 |
+
if ( ! $event_stock->is_enabled() ) {
|
403 |
+
if ( isset( $data['event_capacity'] ) ) {
|
404 |
+
$data['event_capacity'] = trim( filter_var( $data['event_capacity'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH ) );
|
405 |
+
|
406 |
+
// If empty we need to modify to -1
|
407 |
+
if ( '' === $data['event_capacity'] ) {
|
408 |
+
$data['event_capacity'] = - 1;
|
409 |
+
}
|
410 |
+
|
411 |
+
// Makes sure it's an Int after this point
|
412 |
+
$data['event_capacity'] = (int) $data['event_capacity'];
|
413 |
+
|
414 |
+
$tickets_handler->remove_hooks();
|
415 |
+
|
416 |
+
// We need to update event post meta - if we've set a global stock
|
417 |
+
$event_stock->enable();
|
418 |
+
$event_stock->set_stock_level( $data['event_capacity'], true );
|
419 |
+
|
420 |
+
// Update Event capacity
|
421 |
+
update_post_meta( $post_id, $tickets_handler->key_capacity, $data['event_capacity'] );
|
422 |
+
update_post_meta( $post_id, $event_stock::GLOBAL_STOCK_ENABLED, 1 );
|
423 |
+
|
424 |
+
$tickets_handler->add_hooks();
|
425 |
+
}
|
426 |
+
} else {
|
427 |
+
// If the Global Stock is configured we pull it from the Event
|
428 |
+
$global_capacity = (int) tribe_tickets_get_capacity( $post_id );
|
429 |
+
$data['event_capacity'] = (int) \Tribe__Utils__Array::get( 'event_capacity', $data, 0 );
|
430 |
+
|
431 |
+
if ( ! empty( $data['event_capacity'] ) && $data['event_capacity'] !== $global_capacity ) {
|
432 |
+
// Update stock level with $data['event_capacity'].
|
433 |
+
$event_stock->set_stock_level( $data['event_capacity'], true );
|
434 |
+
} else {
|
435 |
+
// Set $data['event_capacity'] with what we know.
|
436 |
+
$data['event_capacity'] = $global_capacity;
|
437 |
+
}
|
438 |
+
}
|
439 |
+
|
440 |
+
// Default Capacity will be 0
|
441 |
+
$default_capacity = 0;
|
442 |
+
$is_capacity_passed = true;
|
443 |
+
|
444 |
+
// If we have Event Global stock we fetch that Stock
|
445 |
+
if ( $event_stock->is_enabled() ) {
|
446 |
+
$default_capacity = $data['event_capacity'];
|
447 |
+
}
|
448 |
+
|
449 |
+
// Fetch capacity field, if we don't have it use default (defined above)
|
450 |
+
$data['capacity'] = trim( \Tribe__Utils__Array::get( $data, 'capacity', $default_capacity ) );
|
451 |
+
|
452 |
+
// If empty we need to modify to the default
|
453 |
+
if ( '' !== $data['capacity'] ) {
|
454 |
+
// Makes sure it's an Int after this point
|
455 |
+
$data['capacity'] = (int) $data['capacity'];
|
456 |
+
|
457 |
+
// The only available value lower than zero is -1 which is unlimited
|
458 |
+
if ( 0 > $data['capacity'] ) {
|
459 |
+
$data['capacity'] = - 1;
|
460 |
+
}
|
461 |
+
|
462 |
+
$default_capacity = $data['capacity'];
|
463 |
+
}
|
464 |
+
|
465 |
+
// Fetch the stock if defined, otherwise use Capacity field
|
466 |
+
$data['stock'] = trim( \Tribe__Utils__Array::get( $data, 'stock', $default_capacity ) );
|
467 |
+
|
468 |
+
// If empty we need to modify to what every capacity was
|
469 |
+
if ( '' === $data['stock'] ) {
|
470 |
+
$data['stock'] = $default_capacity;
|
471 |
+
}
|
472 |
+
|
473 |
+
// Makes sure it's an Int after this point
|
474 |
+
$data['stock'] = (int) $data['stock'];
|
475 |
+
|
476 |
+
// The only available value lower than zero is -1 which is unlimited.
|
477 |
+
if ( 0 > $data['stock'] ) {
|
478 |
+
$data['stock'] = - 1;
|
479 |
+
}
|
480 |
+
|
481 |
+
$mode = isset( $data['mode'] ) ? $data['mode'] : 'own';
|
482 |
+
|
483 |
+
if ( '' !== $mode ) {
|
484 |
+
if ( 'update' === $save_type ) {
|
485 |
+
$totals = $tickets_handler->get_ticket_totals( $ticket->ID );
|
486 |
+
$data['stock'] -= $totals['pending'] + $totals['sold'];
|
487 |
+
}
|
488 |
+
|
489 |
+
// In here is safe to check because we don't have unlimited = -1
|
490 |
+
$status = ( 0 < $data['stock'] ) ? 'instock' : 'outofstock';
|
491 |
+
|
492 |
+
update_post_meta( $ticket->ID, \Tribe__Tickets__Global_Stock::TICKET_STOCK_MODE, $mode );
|
493 |
+
update_post_meta( $ticket->ID, '_stock', $data['stock'] );
|
494 |
+
update_post_meta( $ticket->ID, '_stock_status', $status );
|
495 |
+
update_post_meta( $ticket->ID, '_backorders', 'no' );
|
496 |
+
update_post_meta( $ticket->ID, '_manage_stock', 'yes' );
|
497 |
+
|
498 |
+
// Prevent Ticket Capacity from going higher then Event Capacity
|
499 |
+
if (
|
500 |
+
$event_stock->is_enabled()
|
501 |
+
&& \Tribe__Tickets__Global_Stock::OWN_STOCK_MODE !== $mode
|
502 |
+
&& (
|
503 |
+
'' === $data['capacity']
|
504 |
+
|| $data['event_capacity'] < $data['capacity']
|
505 |
+
)
|
506 |
+
) {
|
507 |
+
$data['capacity'] = $data['event_capacity'];
|
508 |
+
}
|
509 |
+
} else {
|
510 |
+
// Unlimited Tickets
|
511 |
+
// Besides setting _manage_stock to "no" we should remove the associated stock fields if set previously
|
512 |
+
update_post_meta( $ticket->ID, '_manage_stock', 'no' );
|
513 |
+
delete_post_meta( $ticket->ID, '_stock_status' );
|
514 |
+
delete_post_meta( $ticket->ID, '_stock' );
|
515 |
+
delete_post_meta( $ticket->ID, \Tribe__Tickets__Global_Stock::TICKET_STOCK_CAP );
|
516 |
+
delete_post_meta( $ticket->ID, \Tribe__Tickets__Global_Stock::TICKET_STOCK_MODE );
|
517 |
+
|
518 |
+
// Set Capacity -1 when we don't have a stock mode, which means unlimited
|
519 |
+
$data['capacity'] = - 1;
|
520 |
+
}
|
521 |
+
|
522 |
+
if ( '' !== $data['capacity'] ) {
|
523 |
+
// Update Ticket capacity
|
524 |
+
update_post_meta( $ticket->ID, $tickets_handler->key_capacity, $data['capacity'] );
|
525 |
+
}
|
526 |
+
|
527 |
+
/**
|
528 |
+
* Generic action fired after saving a ticket (by type)
|
529 |
+
*
|
530 |
+
* @since 5.1.9
|
531 |
+
*
|
532 |
+
* @param int $post_id Post ID of post the ticket is tied to
|
533 |
+
* @param \Tribe__Tickets__Ticket_Object $ticket Ticket that was just saved
|
534 |
+
* @param array $raw_data Ticket data
|
535 |
+
* @param string $class Commerce engine class
|
536 |
+
*/
|
537 |
+
do_action( "tec_tickets_commerce_after_{$save_type}_ticket", $post_id, $ticket, $raw_data, static::class );
|
538 |
+
|
539 |
+
/**
|
540 |
+
* Generic action fired after saving a ticket
|
541 |
+
*
|
542 |
+
* @since 4.7
|
543 |
+
*
|
544 |
+
* @param int $post_id Post ID of post the ticket is tied to
|
545 |
+
* @param \Tribe__Tickets__Ticket_Object $ticket Ticket that was just saved
|
546 |
+
* @param array $raw_data Ticket data
|
547 |
+
* @param string $class Commerce engine class
|
548 |
+
*/
|
549 |
+
do_action( 'tec_tickets_commerce_after_save_ticket', $post_id, $ticket, $raw_data, static::class );
|
550 |
+
|
551 |
+
return $ticket->ID;
|
552 |
+
}
|
553 |
+
|
554 |
+
/**
|
555 |
+
* Deletes a given ticket.
|
556 |
+
*
|
557 |
+
* @todo TribeCommerceLegacy: This method needs to be refactored to Tickets Commerce standards.
|
558 |
+
*
|
559 |
+
* @since 5.1.9
|
560 |
+
*
|
561 |
+
* @param $event_id
|
562 |
+
* @param $ticket_id
|
563 |
+
*
|
564 |
+
* @return bool
|
565 |
+
*/
|
566 |
+
public function delete( $event_id, $ticket_id ) {
|
567 |
+
// Ensure we know the event and product IDs (the event ID may not have been passed in)
|
568 |
+
if ( empty( $event_id ) ) {
|
569 |
+
$event_id = get_post_meta( $ticket_id, Attendee::$event_relation_meta_key, true );
|
570 |
+
}
|
571 |
+
|
572 |
+
// Additional check (in case we were passed an invalid ticket ID and still can't determine the event)
|
573 |
+
if ( empty( $event_id ) ) {
|
574 |
+
return false;
|
575 |
+
}
|
576 |
+
|
577 |
+
$product_id = get_post_meta( $ticket_id, Attendee::$event_relation_meta_key, true );
|
578 |
+
|
579 |
+
// @todo: should deleting an attendee replenish a ticket stock?
|
580 |
+
|
581 |
+
// Store name so we can still show it in the attendee list
|
582 |
+
$attendees = tribe( Module::class )->get_attendees_by_id( $event_id );
|
583 |
+
$post_to_delete = get_post( $ticket_id );
|
584 |
+
|
585 |
+
foreach ( (array) $attendees as $attendee ) {
|
586 |
+
if ( $attendee['product_id'] == $ticket_id ) {
|
587 |
+
update_post_meta( $attendee['attendee_id'], Attendee::$deleted_ticket_meta_key, esc_html( $post_to_delete->post_title ) );
|
588 |
+
}
|
589 |
+
}
|
590 |
+
|
591 |
+
// Try to kill the actual ticket/attendee post
|
592 |
+
$delete = wp_delete_post( $ticket_id, true );
|
593 |
+
if ( is_wp_error( $delete ) || ! isset( $delete->ID ) ) {
|
594 |
+
return false;
|
595 |
+
}
|
596 |
+
|
597 |
+
\Tribe__Tickets__Attendance::instance( $event_id )->increment_deleted_attendees_count();
|
598 |
+
do_action( 'tec_tickets_commerce_ticket_deleted', $ticket_id, $event_id, $product_id );
|
599 |
+
\Tribe__Post_Transient::instance()->delete( $event_id, \Tribe__Tickets__Tickets::ATTENDEES_CACHE );
|
600 |
+
|
601 |
+
return true;
|
602 |
+
}
|
603 |
+
|
604 |
+
/**
|
605 |
+
* Update Stock and Global Stock when deleting an Attendee
|
606 |
+
*
|
607 |
+
* @todo TribeCommerceLegacy: This should be moved into using a Flag Action.
|
608 |
+
*
|
609 |
+
* @since 5.1.9
|
610 |
+
*
|
611 |
+
* @param int $ticket_id the attendee id being deleted
|
612 |
+
* @param int $post_id the post or event id for the attendee
|
613 |
+
* @param int $product_id the ticket-product id in Tribe Commerce
|
614 |
+
*/
|
615 |
+
public function update_stock_after_deletion( $ticket_id, $post_id, $product_id ) {
|
616 |
+
|
617 |
+
$global_stock = new \Tribe__Tickets__Global_Stock( $post_id );
|
618 |
+
$shared_capacity = false;
|
619 |
+
if ( $global_stock->is_enabled() ) {
|
620 |
+
$shared_capacity = true;
|
621 |
+
}
|
622 |
+
|
623 |
+
tribe( Module::class )->decrease_ticket_sales_by( $product_id, 1, $shared_capacity, $global_stock );
|
624 |
+
}
|
625 |
+
|
626 |
+
/**
|
627 |
+
* Update Global Stock.
|
628 |
+
*
|
629 |
+
* @todo TribeCommerceLegacy: Not sure where this method fits, might just need to integrate it it into the
|
630 |
+
* create/update methods and delete this.
|
631 |
+
*
|
632 |
+
* @since 5.1.9
|
633 |
+
*
|
634 |
+
* @param \Tribe__Tickets__Global_Stock $global_stock The global stock object.
|
635 |
+
* @param int $qty The quantity to modify stock.
|
636 |
+
* @param bool $increase Whether to increase stock, default is false.
|
637 |
+
*/
|
638 |
+
public function update_global_stock( $global_stock, $qty = 1, $increase = false ) {
|
639 |
+
$level = $global_stock->get_stock_level();
|
640 |
+
|
641 |
+
if ( $increase ) {
|
642 |
+
$new_level = (int) $level + (int) $qty;
|
643 |
+
} else {
|
644 |
+
$new_level = (int) $level - (int) $qty;
|
645 |
+
}
|
646 |
+
|
647 |
+
$global_stock->set_stock_level( $new_level );
|
648 |
+
}
|
649 |
+
|
650 |
+
/**
|
651 |
+
* Increase the sales for a ticket by a specific quantity.
|
652 |
+
*
|
653 |
+
* @todo TribeCommerceLegacy: This should be moved into using a Flag Action.
|
654 |
+
*
|
655 |
+
* @since 5.1.9
|
656 |
+
*
|
657 |
+
* @param int $ticket_id The ticket post ID.
|
658 |
+
* @param int $quantity The quantity to increase the ticket sales by.
|
659 |
+
* @param bool $shared_capacity Whether the ticket is using shared capacity.
|
660 |
+
* @param \Tribe__Tickets__Global_Stock|null $global_stock The stock object or null.
|
661 |
+
*
|
662 |
+
* @return int The new sales amount.
|
663 |
+
*/
|
664 |
+
public function increase_ticket_sales_by( $ticket_id, $quantity = 1, $shared_capacity = false, $global_stock = null ) {
|
665 |
+
// Adjust sales.
|
666 |
+
$sales = (int) get_post_meta( $ticket_id, 'total_sales', true ) + $quantity;
|
667 |
+
|
668 |
+
update_post_meta( $ticket_id, 'total_sales', $sales );
|
669 |
+
|
670 |
+
if ( $shared_capacity && $global_stock instanceof \Tribe__Tickets__Global_Stock ) {
|
671 |
+
$this->update_global_stock( $global_stock, $quantity );
|
672 |
+
}
|
673 |
+
|
674 |
+
return $sales;
|
675 |
+
}
|
676 |
+
|
677 |
+
/**
|
678 |
+
* Decrease the sales for a ticket by a specific quantity.
|
679 |
+
*
|
680 |
+
* @todo TribeCommerceLegacy: This should be moved into using a Flag Action.
|
681 |
+
*
|
682 |
+
* @since 5.1.9
|
683 |
+
*
|
684 |
+
* @param int $ticket_id The ticket post ID.
|
685 |
+
* @param int $quantity The quantity to increase the ticket sales by.
|
686 |
+
* @param bool $shared_capacity Whether the ticket is using shared capacity.
|
687 |
+
* @param \Tribe__Tickets__Global_Stock|null $global_stock The stock object or null.
|
688 |
+
*
|
689 |
+
* @return int The new sales amount.
|
690 |
+
*/
|
691 |
+
public function decrease_ticket_sales_by( $ticket_id, $quantity = 1, $shared_capacity = false, $global_stock = null ) {
|
692 |
+
// Adjust sales.
|
693 |
+
$sales = (int) get_post_meta( $ticket_id, 'total_sales', true ) - $quantity;
|
694 |
+
|
695 |
+
// Prevent negatives.
|
696 |
+
$sales = max( $sales, 0 );
|
697 |
+
|
698 |
+
update_post_meta( $ticket_id, 'total_sales', $sales );
|
699 |
+
|
700 |
+
if ( $shared_capacity && $global_stock instanceof \Tribe__Tickets__Global_Stock ) {
|
701 |
+
$this->update_global_stock( $global_stock, $quantity, true );
|
702 |
+
}
|
703 |
+
|
704 |
+
return $sales;
|
705 |
+
}
|
706 |
+
|
707 |
+
/**
|
708 |
+
* Gets the product price value.
|
709 |
+
*
|
710 |
+
* @todo TribeCommerceLegacy: This should not be used, the model should be used.
|
711 |
+
*
|
712 |
+
* @since 5.1.9
|
713 |
+
*
|
714 |
+
* @param int|\WP_Post $product
|
715 |
+
*
|
716 |
+
* @return string
|
717 |
+
*/
|
718 |
+
public function get_price_value( $product ) {
|
719 |
+
$product = get_post( $product );
|
720 |
+
|
721 |
+
if ( ! $product instanceof \WP_Post ) {
|
722 |
+
return false;
|
723 |
+
}
|
724 |
+
|
725 |
+
return get_post_meta( $product->ID, static::$price_meta_key, true );
|
726 |
+
}
|
727 |
+
|
728 |
+
/**
|
729 |
+
* Get's the product price html
|
730 |
+
*
|
731 |
+
* @todo TribeCommerceLegacy: This should not be used, the model and a template should be used.
|
732 |
+
*
|
733 |
+
* @since 5.1.9
|
734 |
+
*
|
735 |
+
* @param int|object $product
|
736 |
+
* @param array|boolean $attendee
|
737 |
+
*
|
738 |
+
* @return string
|
739 |
+
*/
|
740 |
+
public function get_price_html( $product, $attendee = false ) {
|
741 |
+
$product_id = $product;
|
742 |
+
|
743 |
+
if ( $product instanceof \WP_Post ) {
|
744 |
+
$product_id = $product->ID;
|
745 |
+
} elseif ( is_numeric( $product_id ) ) {
|
746 |
+
$product = get_post( $product_id );
|
747 |
+
} else {
|
748 |
+
return '';
|
749 |
+
}
|
750 |
+
|
751 |
+
$price = $this->get_price_value( $product );
|
752 |
+
$price = tribe( 'tickets.commerce.paypal.currency' )->format_currency( $price, $product_id );
|
753 |
+
|
754 |
+
$price_html = '<span class="tribe-tickets-price-amount amount">' . esc_html( $price ) . '</span>';
|
755 |
+
|
756 |
+
/**
|
757 |
+
* Allow filtering of the Price HTML
|
758 |
+
*
|
759 |
+
* @since 5.1.9
|
760 |
+
*
|
761 |
+
* @param string $price_html
|
762 |
+
* @param mixed $product
|
763 |
+
* @param mixed $attendee
|
764 |
+
*
|
765 |
+
*/
|
766 |
+
return apply_filters( 'tec_tickets_commerce_ticket_price_html', $price_html, $product, $attendee );
|
767 |
+
}
|
768 |
+
}
|
src/Tickets/Commerce/Tickets_View.php
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Tickets_View
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce
|
11 |
+
*/
|
12 |
+
class Tickets_View extends \Tribe__Tickets__Tickets_View {
|
13 |
+
/**
|
14 |
+
* Groups PayPal ticket attendees by purchaser name/email
|
15 |
+
*
|
16 |
+
* @since 5.1.9
|
17 |
+
*
|
18 |
+
* @param int $post_id The post ID it relates to
|
19 |
+
* @param int|null $user_id An optional user ID
|
20 |
+
*
|
21 |
+
* @return array Array with the tickets attendees grouped by purchaser name/email
|
22 |
+
*/
|
23 |
+
public function get_post_attendees_by_purchaser( $post_id, $user_id ) {
|
24 |
+
$attendees = $this->get_post_ticket_attendees( $post_id, $user_id );
|
25 |
+
|
26 |
+
if ( ! $attendees ) {
|
27 |
+
return array();
|
28 |
+
}
|
29 |
+
|
30 |
+
$attendee_groups = array();
|
31 |
+
foreach ( $attendees as $attendee ) {
|
32 |
+
$key = $attendee['purchaser_name'] . '::' . $attendee['purchaser_email'];
|
33 |
+
|
34 |
+
if ( ! isset( $attendee_groups[ $key ] ) ) {
|
35 |
+
$attendee_groups[ $key ] = array();
|
36 |
+
}
|
37 |
+
|
38 |
+
$attendee_groups[ $key ][] = $attendee;
|
39 |
+
}
|
40 |
+
|
41 |
+
return $attendee_groups;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Fetches from the Cached attendees list the ones that are relevant for this user and event
|
46 |
+
*
|
47 |
+
* Important to note that this method will bring the attendees from PayPal tickets
|
48 |
+
*
|
49 |
+
* @since 5.1.9
|
50 |
+
*
|
51 |
+
* @param int $event_id The Event ID it relates to
|
52 |
+
* @param int|null $user_id An Optional User ID
|
53 |
+
*
|
54 |
+
* @return array Array with the PayPal tickets attendees
|
55 |
+
*/
|
56 |
+
public function get_post_ticket_attendees( $event_id, $user_id ) {
|
57 |
+
$module = tribe( Module::class );
|
58 |
+
|
59 |
+
if ( $user_id ) {
|
60 |
+
return $module->get_attendees_by_user_id( $user_id, $event_id );
|
61 |
+
}
|
62 |
+
|
63 |
+
return $module->get_attendees_by_id( $event_id );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Verifies if the Given Event has Ticket participation restricted
|
68 |
+
*
|
69 |
+
* @since 5.1.9
|
70 |
+
*
|
71 |
+
* @param int $event_id The Event/Post ID (optional)
|
72 |
+
* @param int $ticket_id The Ticket/RSVP ID (optional)
|
73 |
+
* @param int $user_id An User ID (optional)
|
74 |
+
*
|
75 |
+
* @return boolean
|
76 |
+
*/
|
77 |
+
public function is_ticket_restricted( $event_id = null, $ticket_id = null, $user_id = null ) {
|
78 |
+
// By default we always pass the current User
|
79 |
+
if ( is_null( $user_id ) ) {
|
80 |
+
$user_id = get_current_user_id();
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Allow users to filter if this Event or Ticket has Restricted Tickets
|
85 |
+
*
|
86 |
+
* @since 4.7.1
|
87 |
+
*
|
88 |
+
* @param boolean $restricted Is this Event or Ticket Restricted?
|
89 |
+
* @param int $event_id The Event/Post ID (optional)
|
90 |
+
* @param int $ticket_id The Ticket/RSVP ID (optional)
|
91 |
+
* @param int $user_id An User ID (optional)
|
92 |
+
*/
|
93 |
+
return apply_filters( 'tec_tickets_commerce_is_ticket_restricted', false, $event_id, $ticket_id, $user_id );
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Gets a HTML Attribute for input/select/textarea to be disabled
|
98 |
+
*
|
99 |
+
* @since 5.1.9
|
100 |
+
*
|
101 |
+
* @param int $event_id The Event/Post ID (optional)
|
102 |
+
* @param int $ticket_id The Ticket/RSVP ID (optional)
|
103 |
+
*
|
104 |
+
* @return boolean
|
105 |
+
*/
|
106 |
+
public function get_restriction_attr( $event_id = null, $ticket_id = null ) {
|
107 |
+
$is_disabled = '';
|
108 |
+
if ( $this->is_ticket_restricted( $event_id, $ticket_id ) ) {
|
109 |
+
$is_disabled = 'disabled title="' . esc_attr__( 'This ticket is no longer active.', 'event-tickets' ) . '"';
|
110 |
+
}
|
111 |
+
|
112 |
+
return $is_disabled;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Creates the HTML for the status of the PayPal ticket.
|
117 |
+
*
|
118 |
+
* @since 5.1.9
|
119 |
+
*
|
120 |
+
* @param string $status The ticket order status
|
121 |
+
*
|
122 |
+
* @return void
|
123 |
+
*/
|
124 |
+
public function render_ticket_status( $status = null ) {
|
125 |
+
$ticket_status = $this->get_ticket_status( $status );
|
126 |
+
|
127 |
+
echo sprintf( '<span>%s</span>', esc_html( $ticket_status ) );
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Returns the ticket status corresponding to the ticket status slug.
|
132 |
+
*
|
133 |
+
* @since 5.1.9
|
134 |
+
*
|
135 |
+
* @param string $status
|
136 |
+
*
|
137 |
+
* @return string
|
138 |
+
*/
|
139 |
+
public function get_ticket_status( $status ) {
|
140 |
+
$ticket_status = __( 'unavailable', 'event-tickets' );
|
141 |
+
|
142 |
+
if ( ! empty( $status ) ) {
|
143 |
+
/** @var \Tribe__Tickets__Status__Manager $status_mgr */
|
144 |
+
$status_mgr = tribe( 'tickets.status' );
|
145 |
+
|
146 |
+
$statuses = $status_mgr->get_all_provider_statuses( 'tpp' );
|
147 |
+
$status_strings = [];
|
148 |
+
foreach ( $statuses as $s ) {
|
149 |
+
$status_strings[ $s->provider_name ] = _x( $s->name, 'a PayPal ticket order status', 'event-tickets' );
|
150 |
+
}
|
151 |
+
|
152 |
+
$ticket_status = \Tribe__Utils__Array::get( $status_strings, $status, reset( $status_strings ) );
|
153 |
+
}
|
154 |
+
|
155 |
+
return $ticket_status;
|
156 |
+
}
|
157 |
+
}
|
src/Tickets/Commerce/Traits/Has_Mode.php
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Traits;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Trait Has_Mode.
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets\Commerce\Traits
|
11 |
+
*/
|
12 |
+
trait Has_Mode {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* The current working mode: live or sandbox.
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
protected $mode;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Valid modes.
|
25 |
+
*
|
26 |
+
* @since 5.1.9
|
27 |
+
*
|
28 |
+
* @var array
|
29 |
+
*/
|
30 |
+
protected $valid_modes = [
|
31 |
+
'sandbox', // Default.
|
32 |
+
'live',
|
33 |
+
];
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Sets the mode for the Merchant for handling operations.
|
37 |
+
*
|
38 |
+
* @since 5.1.9
|
39 |
+
*
|
40 |
+
* @param string $mode
|
41 |
+
*
|
42 |
+
* @return $this
|
43 |
+
*/
|
44 |
+
public function set_mode( $mode ) {
|
45 |
+
if ( ! in_array( $mode, $this->valid_modes, true ) ) {
|
46 |
+
$mode = reset( $this->valid_modes );
|
47 |
+
}
|
48 |
+
|
49 |
+
$this->mode = $mode;
|
50 |
+
|
51 |
+
return $this;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Gets the mode for Merchant for handling operations.
|
56 |
+
*
|
57 |
+
* @since 5.1.9
|
58 |
+
*
|
59 |
+
* @return string Which mode we are using the Merchant.
|
60 |
+
*/
|
61 |
+
public function get_mode() {
|
62 |
+
return $this->mode;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Determines if we are using sandbox mode.
|
67 |
+
*
|
68 |
+
* @since 5.1.9
|
69 |
+
*
|
70 |
+
* @return bool
|
71 |
+
*/
|
72 |
+
public function is_sandbox() {
|
73 |
+
return 'sandbox' === $this->get_mode();
|
74 |
+
}
|
75 |
+
}
|
src/Tickets/Commerce/Utils/Price.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets\Commerce\Utils;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Price
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
class Price {
|
12 |
+
/**
|
13 |
+
* Taking a given numerical price it will multiply the by the quantity passed it will not convert the values into
|
14 |
+
* float at any point, it will use full integers and strings to calculate, to avoid float point problems.
|
15 |
+
*
|
16 |
+
* We only allow two decimal points.
|
17 |
+
*
|
18 |
+
* @since 5.1.9
|
19 |
+
*
|
20 |
+
* @param string $value Which value we are going to multiply for the subtotal.
|
21 |
+
* @param int $quantity Quantity that the value will be multiplied..
|
22 |
+
* @param null|string $decimal Which Decimal separator.
|
23 |
+
* @param null|string $thousand_sep Which thousand separator.
|
24 |
+
*
|
25 |
+
* @return string
|
26 |
+
*/
|
27 |
+
public static function sub_total( $value, $quantity, $decimal = null, $thousand_sep = null ) {
|
28 |
+
$decimal = $decimal ?: tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'decimal_point' );
|
29 |
+
$thousand_sep = $thousand_sep ?: tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'thousands_sep' );
|
30 |
+
$number = number_format( $value, 2, $decimal, $thousand_sep );
|
31 |
+
$number = (int) str_replace( [ $decimal, $thousand_sep ], '', $number );
|
32 |
+
|
33 |
+
$sub_total = $number * $quantity;
|
34 |
+
$sub_total = substr_replace( (string) $sub_total, $decimal, - 2, 0 );
|
35 |
+
|
36 |
+
return number_format( $sub_total, 2, $decimal, $thousand_sep );
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Taking an array of values it creates the sum of those values, it will not convert the values into float at any
|
41 |
+
* point, it will use full integers and strings to calculate, to avoid float point problems.
|
42 |
+
*
|
43 |
+
* We only allow two decimal points.
|
44 |
+
*
|
45 |
+
* @since 5.1.9
|
46 |
+
*
|
47 |
+
* @param array $values Values that need to be summed.
|
48 |
+
* @param null|string $decimal Which Decimal separator.
|
49 |
+
* @param null|string $thousand_sep Which thousand separator.
|
50 |
+
*
|
51 |
+
* @return string
|
52 |
+
*/
|
53 |
+
public static function total( array $values, $decimal = null, $thousand_sep = null ) {
|
54 |
+
$decimal = $decimal ?: tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'decimal_point' );
|
55 |
+
$thousand_sep = $thousand_sep ?: tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'thousands_sep' );
|
56 |
+
|
57 |
+
$values = array_map( static function ( $value ) use ( $decimal, $thousand_sep ) {
|
58 |
+
$number = number_format( $value, 2, $decimal, $thousand_sep );
|
59 |
+
|
60 |
+
return (int) str_replace( [ $decimal, $thousand_sep ], '', $number );
|
61 |
+
}, $values );
|
62 |
+
|
63 |
+
|
64 |
+
$total = array_sum( array_filter( $values ) );
|
65 |
+
$total = substr_replace( (string) $total, $decimal, - 2, 0 );
|
66 |
+
|
67 |
+
return number_format( $total, 2, $decimal, $thousand_sep );
|
68 |
+
}
|
69 |
+
}
|
src/Tickets/Event.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace TEC\Tickets;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Event
|
7 |
+
*
|
8 |
+
* @since 5.1.9
|
9 |
+
*
|
10 |
+
* @package TEC\Tickets
|
11 |
+
*/
|
12 |
+
class Event {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Value stored for the Events from TEC.
|
16 |
+
*
|
17 |
+
* @since 5.1.9
|
18 |
+
*
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
protected static $post_type = 'tribe_events';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Gets the TEC events CPT, will fallback into the Static variable on this class, but will try to pull from
|
25 |
+
* TEC main class constant first.
|
26 |
+
*
|
27 |
+
* @since 5.1.9
|
28 |
+
*
|
29 |
+
*
|
30 |
+
* @return string
|
31 |
+
*/
|
32 |
+
public static function get_post_type() {
|
33 |
+
if ( class_exists( '\Tribe__Events__Main' ) ) {
|
34 |
+
return \Tribe__Events__Main::POSTTYPE;
|
35 |
+
}
|
36 |
+
return static::$post_type;
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
src/Tickets/Hooks.php
CHANGED
@@ -53,7 +53,12 @@ class Hooks extends tad_DI52_ServiceProvider {
|
|
53 |
* @since 5.1.6
|
54 |
*/
|
55 |
protected function add_filters() {
|
|
|
|
|
|
|
|
|
56 |
|
|
|
57 |
}
|
58 |
|
59 |
}
|
53 |
* @since 5.1.6
|
54 |
*/
|
55 |
protected function add_filters() {
|
56 |
+
// add_filter( 'tribe_tickets_get_default_module', [ $this, 'filter_include_tickets_commerce' ], 10, 2 );
|
57 |
+
}
|
58 |
+
|
59 |
+
public function filter_include_tickets_commerce( $module, $modules ) {
|
60 |
|
61 |
+
return $module;
|
62 |
}
|
63 |
|
64 |
}
|
src/Tribe/Admin/Ticket_Settings.php
CHANGED
@@ -1,14 +1,16 @@
|
|
1 |
<?php
|
|
|
2 |
/**
|
3 |
* Manages the admin settings UI in relation to ticket configuration.
|
4 |
*/
|
5 |
class Tribe__Tickets__Admin__Ticket_Settings {
|
|
|
6 |
/**
|
7 |
* Sets up the display of timezone-related settings and listeners to deal with timezone-update
|
8 |
* requests (which are initiated from within the settings screen).
|
9 |
*/
|
10 |
public function __construct() {
|
11 |
-
add_action( 'tribe_settings_do_tabs',
|
12 |
}
|
13 |
|
14 |
/**
|
1 |
<?php
|
2 |
+
|
3 |
/**
|
4 |
* Manages the admin settings UI in relation to ticket configuration.
|
5 |
*/
|
6 |
class Tribe__Tickets__Admin__Ticket_Settings {
|
7 |
+
|
8 |
/**
|
9 |
* Sets up the display of timezone-related settings and listeners to deal with timezone-update
|
10 |
* requests (which are initiated from within the settings screen).
|
11 |
*/
|
12 |
public function __construct() {
|
13 |
+
add_action( 'tribe_settings_do_tabs', [ $this, 'settings_ui' ] );
|
14 |
}
|
15 |
|
16 |
/**
|
src/Tribe/Assets.php
CHANGED
@@ -22,6 +22,8 @@ class Tribe__Tickets__Assets {
|
|
22 |
|
23 |
if ( $this->should_enqueue_common_full() ) {
|
24 |
$tickets_deps[] = 'tribe-common-full-style';
|
|
|
|
|
25 |
}
|
26 |
|
27 |
// Check wether we use v1 or v2. We need to update this when we deprecate tickets v1.
|
@@ -32,7 +34,7 @@ class Tribe__Tickets__Assets {
|
|
32 |
[
|
33 |
[ 'event-tickets-reset-css', 'reset.css' ],
|
34 |
[ 'event-tickets-tickets-css', $tickets_stylesheet, $tickets_deps ],
|
35 |
-
[ 'event-tickets-tickets-rsvp-css', 'rsvp-v1.css', [] ],
|
36 |
[ 'event-tickets-tickets-rsvp-js', 'rsvp.js', [ 'jquery' ] ],
|
37 |
[ 'event-tickets-attendees-list-js', 'attendees-list.js', [ 'jquery' ] ],
|
38 |
[ 'event-tickets-details-js', 'ticket-details.js', [] ],
|
@@ -47,7 +49,7 @@ class Tribe__Tickets__Assets {
|
|
47 |
$tickets_main,
|
48 |
'tribe-tickets-forms-style',
|
49 |
'tickets-forms.css',
|
50 |
-
[],
|
51 |
null,
|
52 |
[
|
53 |
'groups' => [
|
@@ -85,7 +87,7 @@ class Tribe__Tickets__Assets {
|
|
85 |
$tickets_main,
|
86 |
'tribe-common-responsive',
|
87 |
'common-responsive.css',
|
88 |
-
[ 'tribe-common-skeleton-style' ],
|
89 |
null,
|
90 |
[
|
91 |
'conditionals' => [ $this, 'should_enqueue_tickets_loader' ],
|
@@ -93,6 +95,8 @@ class Tribe__Tickets__Assets {
|
|
93 |
'tribe-tickets-block-assets',
|
94 |
'tribe-tickets-rsvp',
|
95 |
'tribe-tickets-registration-page',
|
|
|
|
|
96 |
],
|
97 |
]
|
98 |
);
|
@@ -165,7 +169,7 @@ class Tribe__Tickets__Assets {
|
|
165 |
$tickets_main,
|
166 |
'tribe-tickets-registration-page-styles',
|
167 |
'tickets-registration-page.css',
|
168 |
-
[],
|
169 |
null,
|
170 |
[
|
171 |
'groups' => [
|
@@ -210,7 +214,7 @@ class Tribe__Tickets__Assets {
|
|
210 |
$assets = [
|
211 |
[ 'event-tickets-admin-css', 'tickets-admin.css', [ 'tribe-validation-style', 'tribe-jquery-timepicker-css', 'tribe-common-admin' ] ],
|
212 |
[ 'event-tickets-admin-refresh-css', 'tickets-refresh.css', [ 'event-tickets-admin-css', 'tribe-common-admin' ] ],
|
213 |
-
[ 'event-tickets-admin-tables-css', 'tickets-tables.css', [ 'event-tickets-admin-css' ] ],
|
214 |
[ 'event-tickets-attendees-list-js', 'attendees-list.js', [ 'jquery' ] ],
|
215 |
[ 'event-tickets-admin-accordion-js', 'accordion.js', [] ],
|
216 |
[ 'event-tickets-admin-accordion-css', 'accordion.css', [] ],
|
@@ -363,6 +367,7 @@ class Tribe__Tickets__Assets {
|
|
363 |
$admin_tabs = [
|
364 |
'event-tickets',
|
365 |
'event-tickets-commerce',
|
|
|
366 |
];
|
367 |
|
368 |
// Load specifically on Ticket Settings page only.
|
22 |
|
23 |
if ( $this->should_enqueue_common_full() ) {
|
24 |
$tickets_deps[] = 'tribe-common-full-style';
|
25 |
+
} else {
|
26 |
+
$tickets_deps[] = 'tec-variables-full';
|
27 |
}
|
28 |
|
29 |
// Check wether we use v1 or v2. We need to update this when we deprecate tickets v1.
|
34 |
[
|
35 |
[ 'event-tickets-reset-css', 'reset.css' ],
|
36 |
[ 'event-tickets-tickets-css', $tickets_stylesheet, $tickets_deps ],
|
37 |
+
[ 'event-tickets-tickets-rsvp-css', 'rsvp-v1.css', [ 'tec-variables-full' ] ],
|
38 |
[ 'event-tickets-tickets-rsvp-js', 'rsvp.js', [ 'jquery' ] ],
|
39 |
[ 'event-tickets-attendees-list-js', 'attendees-list.js', [ 'jquery' ] ],
|
40 |
[ 'event-tickets-details-js', 'ticket-details.js', [] ],
|
49 |
$tickets_main,
|
50 |
'tribe-tickets-forms-style',
|
51 |
'tickets-forms.css',
|
52 |
+
[ 'tec-variables-full' ],
|
53 |
null,
|
54 |
[
|
55 |
'groups' => [
|
87 |
$tickets_main,
|
88 |
'tribe-common-responsive',
|
89 |
'common-responsive.css',
|
90 |
+
[ 'tribe-common-skeleton-style', 'tec-variables-full' ],
|
91 |
null,
|
92 |
[
|
93 |
'conditionals' => [ $this, 'should_enqueue_tickets_loader' ],
|
95 |
'tribe-tickets-block-assets',
|
96 |
'tribe-tickets-rsvp',
|
97 |
'tribe-tickets-registration-page',
|
98 |
+
'tribe-tickets-commerce',
|
99 |
+
'tribe-tickets-commerce-checkout',
|
100 |
],
|
101 |
]
|
102 |
);
|
169 |
$tickets_main,
|
170 |
'tribe-tickets-registration-page-styles',
|
171 |
'tickets-registration-page.css',
|
172 |
+
[ 'tec-variables-full' ],
|
173 |
null,
|
174 |
[
|
175 |
'groups' => [
|
214 |
$assets = [
|
215 |
[ 'event-tickets-admin-css', 'tickets-admin.css', [ 'tribe-validation-style', 'tribe-jquery-timepicker-css', 'tribe-common-admin' ] ],
|
216 |
[ 'event-tickets-admin-refresh-css', 'tickets-refresh.css', [ 'event-tickets-admin-css', 'tribe-common-admin' ] ],
|
217 |
+
[ 'event-tickets-admin-tables-css', 'tickets-tables.css', [ 'tec-variables-full', 'event-tickets-admin-css' ] ],
|
218 |
[ 'event-tickets-attendees-list-js', 'attendees-list.js', [ 'jquery' ] ],
|
219 |
[ 'event-tickets-admin-accordion-js', 'accordion.js', [] ],
|
220 |
[ 'event-tickets-admin-accordion-css', 'accordion.css', [] ],
|
367 |
$admin_tabs = [
|
368 |
'event-tickets',
|
369 |
'event-tickets-commerce',
|
370 |
+
'payments',
|
371 |
];
|
372 |
|
373 |
// Load specifically on Ticket Settings page only.
|
src/Tribe/Attendee_Repository.php
CHANGED
@@ -47,7 +47,7 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
47 |
*/
|
48 |
protected static $public_order_statuses = [
|
49 |
'yes', // RSVP
|
50 |
-
'completed', // PayPal
|
51 |
'wc-completed', // WooCommerce
|
52 |
'publish', // Easy Digital Downloads
|
53 |
];
|
@@ -142,8 +142,9 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
142 |
*/
|
143 |
public function attendee_types() {
|
144 |
return [
|
145 |
-
'rsvp'
|
146 |
-
'tribe-commerce'
|
|
|
147 |
];
|
148 |
}
|
149 |
|
@@ -158,8 +159,9 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
158 |
*/
|
159 |
public function attendee_to_event_keys() {
|
160 |
return [
|
161 |
-
'rsvp'
|
162 |
-
'tribe-commerce'
|
|
|
163 |
];
|
164 |
}
|
165 |
|
@@ -174,8 +176,9 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
174 |
*/
|
175 |
public function attendee_to_ticket_keys() {
|
176 |
return [
|
177 |
-
'rsvp'
|
178 |
-
'tribe-commerce'
|
|
|
179 |
];
|
180 |
}
|
181 |
|
@@ -189,8 +192,9 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
189 |
*/
|
190 |
protected function attendee_to_order_keys() {
|
191 |
return [
|
192 |
-
'rsvp'
|
193 |
-
'tribe-commerce'
|
|
|
194 |
];
|
195 |
}
|
196 |
|
@@ -205,8 +209,9 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
205 |
*/
|
206 |
public function purchaser_name_keys() {
|
207 |
return [
|
208 |
-
'rsvp'
|
209 |
-
'tribe-commerce'
|
|
|
210 |
];
|
211 |
}
|
212 |
|
@@ -221,8 +226,9 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
221 |
*/
|
222 |
public function purchaser_email_keys() {
|
223 |
return [
|
224 |
-
'rsvp'
|
225 |
-
'tribe-commerce'
|
|
|
226 |
];
|
227 |
}
|
228 |
|
@@ -237,8 +243,9 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
237 |
*/
|
238 |
public function security_code_keys() {
|
239 |
return [
|
240 |
-
'rsvp'
|
241 |
-
'tribe-commerce'
|
|
|
242 |
];
|
243 |
}
|
244 |
|
@@ -253,8 +260,9 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
253 |
*/
|
254 |
public function attendee_optout_keys() {
|
255 |
return [
|
256 |
-
'rsvp'
|
257 |
-
'tribe-commerce'
|
|
|
258 |
];
|
259 |
}
|
260 |
|
@@ -267,8 +275,9 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
267 |
*/
|
268 |
public function checked_in_keys() {
|
269 |
return [
|
270 |
-
'rsvp'
|
271 |
-
'tribe-commerce'
|
|
|
272 |
];
|
273 |
}
|
274 |
|
@@ -399,9 +408,10 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
399 |
*
|
400 |
* @since 4.8
|
401 |
*
|
|
|
|
|
402 |
* @param string|array $event_status
|
403 |
*
|
404 |
-
* @throws Tribe__Repository__Void_Query_Exception If the requested statuses are not accessible by the user.
|
405 |
*/
|
406 |
public function filter_by_event_status( $event_status ) {
|
407 |
$statuses = Arr::list_to_array( $event_status );
|
@@ -470,10 +480,11 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
470 |
*
|
471 |
* @since 4.8
|
472 |
*
|
473 |
-
* @
|
|
|
474 |
* @param string $type Type of matching (in, not_in, like).
|
475 |
*
|
476 |
-
* @
|
477 |
*/
|
478 |
public function filter_by_order_status( $order_status, $type = 'in' ) {
|
479 |
$statuses = Arr::list_to_array( $order_status );
|
@@ -561,9 +572,10 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
561 |
*
|
562 |
* @since 4.10.6
|
563 |
*
|
|
|
|
|
564 |
* @param string|array $order_status
|
565 |
*
|
566 |
-
* @throws Tribe__Repository__Void_Query_Exception If the requested statuses are not accessible by the user.
|
567 |
*/
|
568 |
public function filter_by_order_status_not_in( $order_status ) {
|
569 |
$this->filter_by_order_status( $order_status, 'not_in' );
|
@@ -725,12 +737,14 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
725 |
*
|
726 |
* @since 5.1.0
|
727 |
*
|
728 |
-
* @
|
|
|
729 |
* @param array $attendee_data List of additional attendee data.
|
730 |
*
|
|
|
|
|
731 |
* @return WP_Post|false The new post object or false if unsuccessful.
|
732 |
*
|
733 |
-
* @throws Tribe__Repository__Usage_Error If the argument types are not set as expected.
|
734 |
*/
|
735 |
public function create_attendee_for_ticket( $ticket, $attendee_data ) {
|
736 |
// Attempt to get the ticket object from the ticket ID.
|
@@ -768,17 +782,19 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
768 |
*
|
769 |
* @since 5.1.0
|
770 |
*
|
771 |
-
* @
|
|
|
772 |
* @param bool $return_promise Whether to return a promise object or just the ids
|
773 |
* of the updated posts; if `true` then a promise will
|
774 |
* be returned whether the update is happening in background
|
775 |
* or not.
|
776 |
*
|
|
|
|
|
777 |
* @return array|Tribe__Promise A list of the post IDs that have been (synchronous) or will
|
778 |
* be (asynchronous) updated if `$return_promise` is set to `false`;
|
779 |
* the Promise object if `$return_promise` is set to `true`.
|
780 |
*
|
781 |
-
* @throws Tribe__Repository__Usage_Error If the argument types are not set as expected.
|
782 |
*/
|
783 |
public function update_attendee( $attendee_data, $return_promise = false ) {
|
784 |
if ( empty( $attendee_data['attendee_id'] ) ) {
|
@@ -807,7 +823,7 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
807 |
$repository = $this;
|
808 |
|
809 |
return $saved->then(
|
810 |
-
static function() use ( $repository, $attendee_data ) {
|
811 |
// Trigger the update actions.
|
812 |
$repository->trigger_update_actions( $attendee_data );
|
813 |
}
|
@@ -825,10 +841,11 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
825 |
*
|
826 |
* @since 5.1.0
|
827 |
*
|
828 |
-
* @
|
|
|
829 |
* @param Tribe__Tickets__Ticket_Object $ticket The ticket object or null if not relying on it.
|
830 |
*
|
831 |
-
* @
|
832 |
*/
|
833 |
public function set_attendee_args( $attendee_data, $ticket = null ) {
|
834 |
$args = [
|
@@ -1038,6 +1055,7 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
1038 |
$query->set_args( $args );
|
1039 |
} catch ( Tribe__Repository__Usage_Error $e ) {
|
1040 |
do_action( 'tribe_log', 'error', __CLASS__, [ 'message' => $e->getMessage() ] );
|
|
|
1041 |
return;
|
1042 |
}
|
1043 |
|
@@ -1103,7 +1121,7 @@ class Tribe__Tickets__Attendee_Repository extends Tribe__Repository {
|
|
1103 |
*
|
1104 |
* @since 5.1.0
|
1105 |
*
|
1106 |
-
* @param array $attendee_data
|
1107 |
*/
|
1108 |
public function trigger_update_actions( $attendee_data ) {
|
1109 |
/**
|
47 |
*/
|
48 |
protected static $public_order_statuses = [
|
49 |
'yes', // RSVP
|
50 |
+
'completed', // PayPal Legacy
|
51 |
'wc-completed', // WooCommerce
|
52 |
'publish', // Easy Digital Downloads
|
53 |
];
|
142 |
*/
|
143 |
public function attendee_types() {
|
144 |
return [
|
145 |
+
'rsvp' => 'tribe_rsvp_attendees',
|
146 |
+
'tribe-commerce' => 'tribe_tpp_attendees',
|
147 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::POSTTYPE,
|
148 |
];
|
149 |
}
|
150 |
|
159 |
*/
|
160 |
public function attendee_to_event_keys() {
|
161 |
return [
|
162 |
+
'rsvp' => '_tribe_rsvp_event',
|
163 |
+
'tribe-commerce' => '_tribe_tpp_event',
|
164 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::$event_relation_meta_key,
|
165 |
];
|
166 |
}
|
167 |
|
176 |
*/
|
177 |
public function attendee_to_ticket_keys() {
|
178 |
return [
|
179 |
+
'rsvp' => '_tribe_rsvp_product',
|
180 |
+
'tribe-commerce' => '_tribe_tpp_product',
|
181 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::$ticket_relation_meta_key,
|
182 |
];
|
183 |
}
|
184 |
|
192 |
*/
|
193 |
protected function attendee_to_order_keys() {
|
194 |
return [
|
195 |
+
'rsvp' => '_tribe_rsvp_order',
|
196 |
+
'tribe-commerce' => '_tribe_tpp_order',
|
197 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::$order_relation_meta_key,
|
198 |
];
|
199 |
}
|
200 |
|
209 |
*/
|
210 |
public function purchaser_name_keys() {
|
211 |
return [
|
212 |
+
'rsvp' => '_tribe_rsvp_full_name',
|
213 |
+
'tribe-commerce' => '_tribe_tpp_full_name',
|
214 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::$purchaser_name_meta_key,
|
215 |
];
|
216 |
}
|
217 |
|
226 |
*/
|
227 |
public function purchaser_email_keys() {
|
228 |
return [
|
229 |
+
'rsvp' => '_tribe_rsvp_email',
|
230 |
+
'tribe-commerce' => '_tribe_tpp_email',
|
231 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::$purchaser_email_meta_key,
|
232 |
];
|
233 |
}
|
234 |
|
243 |
*/
|
244 |
public function security_code_keys() {
|
245 |
return [
|
246 |
+
'rsvp' => '_tribe_rsvp_security_code',
|
247 |
+
'tribe-commerce' => '_tribe_tpp_security_code',
|
248 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::$security_code_meta_key,
|
249 |
];
|
250 |
}
|
251 |
|
260 |
*/
|
261 |
public function attendee_optout_keys() {
|
262 |
return [
|
263 |
+
'rsvp' => '_tribe_rsvp_attendee_optout',
|
264 |
+
'tribe-commerce' => '_tribe_tpp_attendee_optout',
|
265 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::$optout_meta_key,
|
266 |
];
|
267 |
}
|
268 |
|
275 |
*/
|
276 |
public function checked_in_keys() {
|
277 |
return [
|
278 |
+
'rsvp' => '_tribe_rsvp_checkedin',
|
279 |
+
'tribe-commerce' => '_tribe_tpp_checkedin',
|
280 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::$checked_in_meta_key,
|
281 |
];
|
282 |
}
|
283 |
|
408 |
*
|
409 |
* @since 4.8
|
410 |
*
|
411 |
+
* @throws Tribe__Repository__Void_Query_Exception If the requested statuses are not accessible by the user.
|
412 |
+
*
|
413 |
* @param string|array $event_status
|
414 |
*
|
|
|
415 |
*/
|
416 |
public function filter_by_event_status( $event_status ) {
|
417 |
$statuses = Arr::list_to_array( $event_status );
|
480 |
*
|
481 |
* @since 4.8
|
482 |
*
|
483 |
+
* @throws Tribe__Repository__Void_Query_Exception If the requested statuses are not accessible by the user.
|
484 |
+
*
|
485 |
* @param string $type Type of matching (in, not_in, like).
|
486 |
*
|
487 |
+
* @param string|array $order_status Order status.
|
488 |
*/
|
489 |
public function filter_by_order_status( $order_status, $type = 'in' ) {
|
490 |
$statuses = Arr::list_to_array( $order_status );
|
572 |
*
|
573 |
* @since 4.10.6
|
574 |
*
|
575 |
+
* @throws Tribe__Repository__Void_Query_Exception If the requested statuses are not accessible by the user.
|
576 |
+
*
|
577 |
* @param string|array $order_status
|
578 |
*
|
|
|
579 |
*/
|
580 |
public function filter_by_order_status_not_in( $order_status ) {
|
581 |
$this->filter_by_order_status( $order_status, 'not_in' );
|
737 |
*
|
738 |
* @since 5.1.0
|
739 |
*
|
740 |
+
* @throws Tribe__Repository__Usage_Error If the argument types are not set as expected.
|
741 |
+
*
|
742 |
* @param array $attendee_data List of additional attendee data.
|
743 |
*
|
744 |
+
* @param Tribe__Tickets__Ticket_Object|int $ticket The ticket object or ID.
|
745 |
+
*
|
746 |
* @return WP_Post|false The new post object or false if unsuccessful.
|
747 |
*
|
|
|
748 |
*/
|
749 |
public function create_attendee_for_ticket( $ticket, $attendee_data ) {
|
750 |
// Attempt to get the ticket object from the ticket ID.
|
782 |
*
|
783 |
* @since 5.1.0
|
784 |
*
|
785 |
+
* @throws Tribe__Repository__Usage_Error If the argument types are not set as expected.
|
786 |
+
*
|
787 |
* @param bool $return_promise Whether to return a promise object or just the ids
|
788 |
* of the updated posts; if `true` then a promise will
|
789 |
* be returned whether the update is happening in background
|
790 |
* or not.
|
791 |
*
|
792 |
+
* @param array $attendee_data List of attendee data to be saved.
|
793 |
+
*
|
794 |
* @return array|Tribe__Promise A list of the post IDs that have been (synchronous) or will
|
795 |
* be (asynchronous) updated if `$return_promise` is set to `false`;
|
796 |
* the Promise object if `$return_promise` is set to `true`.
|
797 |
*
|
|
|
798 |
*/
|
799 |
public function update_attendee( $attendee_data, $return_promise = false ) {
|
800 |
if ( empty( $attendee_data['attendee_id'] ) ) {
|
823 |
$repository = $this;
|
824 |
|
825 |
return $saved->then(
|
826 |
+
static function () use ( $repository, $attendee_data ) {
|
827 |
// Trigger the update actions.
|
828 |
$repository->trigger_update_actions( $attendee_data );
|
829 |
}
|
841 |
*
|
842 |
* @since 5.1.0
|
843 |
*
|
844 |
+
* @throws Tribe__Repository__Usage_Error If the argument types are not set as expected.
|
845 |
+
*
|
846 |
* @param Tribe__Tickets__Ticket_Object $ticket The ticket object or null if not relying on it.
|
847 |
*
|
848 |
+
* @param array $attendee_data List of additional attendee data.
|
849 |
*/
|
850 |
public function set_attendee_args( $attendee_data, $ticket = null ) {
|
851 |
$args = [
|
1055 |
$query->set_args( $args );
|
1056 |
} catch ( Tribe__Repository__Usage_Error $e ) {
|
1057 |
do_action( 'tribe_log', 'error', __CLASS__, [ 'message' => $e->getMessage() ] );
|
1058 |
+
|
1059 |
return;
|
1060 |
}
|
1061 |
|
1121 |
*
|
1122 |
* @since 5.1.0
|
1123 |
*
|
1124 |
+
* @param array $attendee_data List of attendee data to be saved.
|
1125 |
*/
|
1126 |
public function trigger_update_actions( $attendee_data ) {
|
1127 |
/**
|
src/Tribe/Commerce/PayPal/Main.php
CHANGED
@@ -1598,7 +1598,7 @@ class Tribe__Tickets__Commerce__PayPal__Main extends Tribe__Tickets__Tickets {
|
|
1598 |
/**
|
1599 |
* {@inheritdoc}
|
1600 |
*/
|
1601 |
-
|
1602 |
if ( ! is_numeric( $order_id ) ) {
|
1603 |
return parent::get_attendees_by_order_id( $order_id, $ticket_id );
|
1604 |
}
|
1598 |
/**
|
1599 |
* {@inheritdoc}
|
1600 |
*/
|
1601 |
+
public function get_attendees_by_order_id( $order_id, $ticket_id = null ) {
|
1602 |
if ( ! is_numeric( $order_id ) ) {
|
1603 |
return parent::get_attendees_by_order_id( $order_id, $ticket_id );
|
1604 |
}
|
src/Tribe/Editor/Configuration.php
CHANGED
@@ -134,9 +134,12 @@ class Tribe__Tickets__Editor__Configuration implements Tribe__Editor__Configurat
|
|
134 |
$currency_position = $currency->get_provider_symbol_position( $class_name, null );
|
135 |
}
|
136 |
|
|
|
|
|
137 |
$providers[] = [
|
138 |
'name' => $modules[ $class_name ],
|
139 |
'class' => $class_name,
|
|
|
140 |
'currency' => html_entity_decode( $currency_symbol ),
|
141 |
'currency_position' => $currency_position,
|
142 |
];
|
134 |
$currency_position = $currency->get_provider_symbol_position( $class_name, null );
|
135 |
}
|
136 |
|
137 |
+
$html_safe_class = str_replace( [ '\\' ], [ '_' ], $class_name );
|
138 |
+
|
139 |
$providers[] = [
|
140 |
'name' => $modules[ $class_name ],
|
141 |
'class' => $class_name,
|
142 |
+
'html_safe_class' => sanitize_html_class( $html_safe_class ),
|
143 |
'currency' => html_entity_decode( $currency_symbol ),
|
144 |
'currency_position' => $currency_position,
|
145 |
];
|
src/Tribe/Editor/Provider.php
CHANGED
@@ -126,10 +126,21 @@ class Tribe__Tickets__Editor__Provider extends tad_DI52_ServiceProvider {
|
|
126 |
tribe_callback( 'tickets.editor.blocks.attendees', 'register' )
|
127 |
);
|
128 |
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
134 |
|
135 |
/**
|
126 |
tribe_callback( 'tickets.editor.blocks.attendees', 'register' )
|
127 |
);
|
128 |
|
129 |
+
global $wp_version;
|
130 |
+
if( version_compare( $wp_version, '5.8', '<' ) ) {
|
131 |
+
// WP version is less then 5.8.
|
132 |
+
add_action(
|
133 |
+
'block_categories',
|
134 |
+
tribe_callback( 'tickets.editor', 'block_categories' )
|
135 |
+
);
|
136 |
+
} else {
|
137 |
+
// WP version is 5.8 or above.
|
138 |
+
add_action(
|
139 |
+
'block_categories_all',
|
140 |
+
tribe_callback( 'tickets.editor', 'block_categories' )
|
141 |
+
);
|
142 |
+
}
|
143 |
+
|
144 |
}
|
145 |
|
146 |
/**
|
src/Tribe/Event_Repository.php
CHANGED
@@ -88,8 +88,9 @@ class Tribe__Tickets__Event_Repository extends Tribe__Repository__Decorator {
|
|
88 |
*/
|
89 |
public function attendee_types() {
|
90 |
return [
|
91 |
-
'rsvp'
|
92 |
-
'tribe-commerce'
|
|
|
93 |
];
|
94 |
}
|
95 |
|
@@ -104,8 +105,9 @@ class Tribe__Tickets__Event_Repository extends Tribe__Repository__Decorator {
|
|
104 |
*/
|
105 |
public function attendee_to_event_keys() {
|
106 |
return [
|
107 |
-
'rsvp'
|
108 |
-
'tribe-commerce'
|
|
|
109 |
];
|
110 |
}
|
111 |
|
88 |
*/
|
89 |
public function attendee_types() {
|
90 |
return [
|
91 |
+
'rsvp' => 'tribe_rsvp_attendees',
|
92 |
+
'tribe-commerce' => 'tribe_tpp_attendees',
|
93 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::POSTTYPE,
|
94 |
];
|
95 |
}
|
96 |
|
105 |
*/
|
106 |
public function attendee_to_event_keys() {
|
107 |
return [
|
108 |
+
'rsvp' => '_tribe_rsvp_event',
|
109 |
+
'tribe-commerce' => '_tribe_tpp_event',
|
110 |
+
\TEC\Tickets\Commerce::PROVIDER => \TEC\Tickets\Commerce\Attendee::$event_relation_meta_key,
|
111 |
];
|
112 |
}
|
113 |
|
src/Tribe/Main.php
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
use Tribe\Tickets\Events\Service_Provider as Events_Service_Provider;
|
4 |
use Tribe\Tickets\Promoter\Service_Provider as Promoter_Service_Provider;
|
5 |
|
@@ -8,7 +7,7 @@ class Tribe__Tickets__Main {
|
|
8 |
/**
|
9 |
* Current version of this plugin
|
10 |
*/
|
11 |
-
const VERSION = '5.1.
|
12 |
|
13 |
/**
|
14 |
* Used to store the version history.
|
@@ -302,8 +301,17 @@ class Tribe__Tickets__Main {
|
|
302 |
|
303 |
add_action( 'tribe_common_loaded', [ $this, 'bootstrap' ], 0 );
|
304 |
|
305 |
-
// Customizer support.
|
306 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
307 |
}
|
308 |
|
309 |
/**
|
1 |
<?php
|
|
|
2 |
use Tribe\Tickets\Events\Service_Provider as Events_Service_Provider;
|
3 |
use Tribe\Tickets\Promoter\Service_Provider as Promoter_Service_Provider;
|
4 |
|
7 |
/**
|
8 |
* Current version of this plugin
|
9 |
*/
|
10 |
+
const VERSION = '5.1.9';
|
11 |
|
12 |
/**
|
13 |
* Used to store the version history.
|
301 |
|
302 |
add_action( 'tribe_common_loaded', [ $this, 'bootstrap' ], 0 );
|
303 |
|
304 |
+
// Customizer support - only loaded on older version of TEC for backwards compatibility.
|
305 |
+
if (
|
306 |
+
class_exists( 'Tribe__Events__Main' )
|
307 |
+
&& (
|
308 |
+
! function_exists( 'tribe_events_views_v2_is_enabled' )
|
309 |
+
|| ! tribe_events_views_v2_is_enabled()
|
310 |
+
)
|
311 |
+
) {
|
312 |
+
tribe_register_provider( Tribe\Tickets\Service_Providers\Customizer::class );
|
313 |
+
}
|
314 |
+
|
315 |
}
|
316 |
|
317 |
/**
|
src/Tribe/REST/V1/Endpoints/Base.php
CHANGED
@@ -50,7 +50,7 @@ abstract class Tribe__Tickets__REST__V1__Endpoints__Base {
|
|
50 |
* @param Tribe__Tickets__REST__V1__Validator__Interface $validator
|
51 |
*/
|
52 |
public function __construct(
|
53 |
-
Tribe__REST__Messages_Interface $messages,
|
54 |
Tribe__Tickets__REST__Interfaces__Post_Repository $post_repository = null,
|
55 |
Tribe__Tickets__REST__V1__Validator__Interface $validator = null
|
56 |
) {
|
50 |
* @param Tribe__Tickets__REST__V1__Validator__Interface $validator
|
51 |
*/
|
52 |
public function __construct(
|
53 |
+
Tribe__REST__Messages_Interface $messages = null,
|
54 |
Tribe__Tickets__REST__Interfaces__Post_Repository $post_repository = null,
|
55 |
Tribe__Tickets__REST__V1__Validator__Interface $validator = null
|
56 |
) {
|
src/Tribe/Repositories/Order.php
CHANGED
@@ -99,7 +99,7 @@ class Order extends Tribe__Repository {
|
|
99 |
return;
|
100 |
}
|
101 |
|
102 |
-
/** @var Tribe__Tickets__Status__Manager $status_mgr */
|
103 |
$status_mgr = tribe( 'tickets.status' );
|
104 |
|
105 |
/**
|
99 |
return;
|
100 |
}
|
101 |
|
102 |
+
/** @var \Tribe__Tickets__Status__Manager $status_mgr */
|
103 |
$status_mgr = tribe( 'tickets.status' );
|
104 |
|
105 |
/**
|
src/Tribe/Shortcodes/Tribe_Tickets_Checkout.php
CHANGED
@@ -8,8 +8,9 @@
|
|
8 |
|
9 |
namespace Tribe\Tickets\Shortcodes;
|
10 |
|
|
|
11 |
use Tribe\Shortcode\Shortcode_Abstract;
|
12 |
-
use TEC\Tickets\Commerce\Gateways\PayPal\
|
13 |
use TEC\Tickets\Commerce\Gateways\PayPal\Settings;
|
14 |
use Tribe__Tickets__Editor__Template;
|
15 |
|
@@ -39,15 +40,27 @@ class Tribe_Tickets_Checkout extends Shortcode_Abstract {
|
|
39 |
/** @var Tribe__Tickets__Editor__Template $template */
|
40 |
$template = tribe( 'tickets.editor.template' );
|
41 |
|
42 |
-
$
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
$args = [
|
46 |
-
|
47 |
-
'
|
48 |
-
'
|
|
|
|
|
49 |
];
|
50 |
|
|
|
|
|
51 |
// Add the rendering attributes into global context.
|
52 |
$template->add_template_globals( $args );
|
53 |
|
8 |
|
9 |
namespace Tribe\Tickets\Shortcodes;
|
10 |
|
11 |
+
use TEC\Tickets\Commerce\Checkout;
|
12 |
use Tribe\Shortcode\Shortcode_Abstract;
|
13 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
14 |
use TEC\Tickets\Commerce\Gateways\PayPal\Settings;
|
15 |
use Tribe__Tickets__Editor__Template;
|
16 |
|
40 |
/** @var Tribe__Tickets__Editor__Template $template */
|
41 |
$template = tribe( 'tickets.editor.template' );
|
42 |
|
43 |
+
$merchant = tribe( Merchant::class );
|
44 |
+
|
45 |
+
$data = tribe( Checkout::class )->prepare_data_for_template( $_POST );
|
46 |
+
|
47 |
+
$post = get_post( $data['post_id'] );
|
48 |
+
$is_event = 'tribe_events' === $post->post_type;
|
49 |
+
$event = null;
|
50 |
+
if ( $is_event && function_exists( 'tribe_get_event' ) ) {
|
51 |
+
$event = tribe_get_event( $post );
|
52 |
+
}
|
53 |
|
54 |
$args = [
|
55 |
+
'merchant' => $merchant,
|
56 |
+
'post' => $post,
|
57 |
+
'event' => $event,
|
58 |
+
'provider' => $data['provider'],
|
59 |
+
'tickets' => $data['tickets'],
|
60 |
];
|
61 |
|
62 |
+
$args['paypal_attribution_id'] = \TEC\Tickets\Commerce\Gateways\PayPal\Gateway::ATTRIBUTION_ID;
|
63 |
+
|
64 |
// Add the rendering attributes into global context.
|
65 |
$template->add_template_globals( $args );
|
66 |
|
src/Tribe/Status/Manager.php
CHANGED
@@ -25,6 +25,7 @@ class Tribe__Tickets__Status__Manager {
|
|
25 |
'Tribe__Tickets__RSVP' => 'rsvp',
|
26 |
'Tribe__Tickets__Commerce__PayPal__Main' => 'tpp',
|
27 |
'Tribe__Tickets_Plus__Commerce__WooCommerce__Main' => 'woo',
|
|
|
28 |
];
|
29 |
/**
|
30 |
* Active Modules
|
@@ -39,10 +40,10 @@ class Tribe__Tickets__Status__Manager {
|
|
39 |
* @var array
|
40 |
*/
|
41 |
protected $status_managers = [
|
42 |
-
'edd'
|
43 |
-
'rsvp'
|
44 |
-
'tpp'
|
45 |
-
'woo'
|
46 |
];
|
47 |
|
48 |
/**
|
25 |
'Tribe__Tickets__RSVP' => 'rsvp',
|
26 |
'Tribe__Tickets__Commerce__PayPal__Main' => 'tpp',
|
27 |
'Tribe__Tickets_Plus__Commerce__WooCommerce__Main' => 'woo',
|
28 |
+
\TEC\Tickets\Commerce\Module::class => \TEC\Tickets\Commerce::ABBR,
|
29 |
];
|
30 |
/**
|
31 |
* Active Modules
|
40 |
* @var array
|
41 |
*/
|
42 |
protected $status_managers = [
|
43 |
+
'edd' => 'Tribe__Tickets_Plus__Commerce__EDD__Status_Manager',
|
44 |
+
'rsvp' => 'Tribe__Tickets__RSVP__Status_Manager',
|
45 |
+
'tpp' => 'Tribe__Tickets__Commerce__PayPal__Status_Manager',
|
46 |
+
'woo' => 'Tribe__Tickets_Plus__Commerce__WooCommerce__Status_Manager',
|
47 |
];
|
48 |
|
49 |
/**
|
src/Tribe/Tickets.php
CHANGED
@@ -884,7 +884,7 @@ if ( ! class_exists( 'Tribe__Tickets__Tickets' ) ) {
|
|
884 |
*
|
885 |
* @return array List of attendees.
|
886 |
*/
|
887 |
-
|
888 |
$ticket_id = null;
|
889 |
|
890 |
// Support an optional second argument while not causing warnings from other ticket provider classes.
|
@@ -3415,7 +3415,7 @@ if ( ! class_exists( 'Tribe__Tickets__Tickets' ) ) {
|
|
3415 |
* @param array $raw_data
|
3416 |
* @param string $save_type
|
3417 |
*/
|
3418 |
-
|
3419 |
if ( empty( $data ) ) {
|
3420 |
return;
|
3421 |
}
|
884 |
*
|
885 |
* @return array List of attendees.
|
886 |
*/
|
887 |
+
public function get_attendees_by_order_id( $order_id ) {
|
888 |
$ticket_id = null;
|
889 |
|
890 |
// Support an optional second argument while not causing warnings from other ticket provider classes.
|
3415 |
* @param array $raw_data
|
3416 |
* @param string $save_type
|
3417 |
*/
|
3418 |
+
public function update_capacity( $ticket, $data, $save_type ) {
|
3419 |
if ( empty( $data ) ) {
|
3420 |
return;
|
3421 |
}
|
src/Tribe/Tickets_View.php
CHANGED
@@ -1236,20 +1236,6 @@ class Tribe__Tickets__Tickets_View {
|
|
1236 |
*/
|
1237 |
$template->add_template_globals( $args );
|
1238 |
|
1239 |
-
// Determine whether to show the previews on the page.
|
1240 |
-
if (
|
1241 |
-
defined( 'TRIBE_TICKETS_RSVP_NEW_VIEWS_PREVIEW' )
|
1242 |
-
&& TRIBE_TICKETS_RSVP_NEW_VIEWS_PREVIEW
|
1243 |
-
) {
|
1244 |
-
// Enqueue new assets.
|
1245 |
-
tribe_asset_enqueue( 'tribe-tickets-rsvp-style' );
|
1246 |
-
tribe_asset_enqueue( 'tribe-tickets-forms-style' );
|
1247 |
-
// @todo: Remove this once we solve the common breakpoints vs container based.
|
1248 |
-
tribe_asset_enqueue( 'tribe-common-responsive' );
|
1249 |
-
|
1250 |
-
return $template->template( 'v2/rsvp-kitchen-sink', $args, $echo );
|
1251 |
-
}
|
1252 |
-
|
1253 |
ob_start();
|
1254 |
|
1255 |
/**
|
1236 |
*/
|
1237 |
$template->add_template_globals( $args );
|
1238 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1239 |
ob_start();
|
1240 |
|
1241 |
/**
|
src/admin-views/commerce/gateways/paypal/signup-link.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script>
|
2 |
+
function onboardedCallback( authCode, sharedId ) {
|
3 |
+
fetch( '<?php echo tribe( \TEC\Tickets\Commerce\Gateways\PayPal\REST\On_Boarding_Endpoint::class )->get_route_url() ?>', {
|
4 |
+
method: 'POST',
|
5 |
+
headers: {
|
6 |
+
'content-type': 'application/json',
|
7 |
+
},
|
8 |
+
body: JSON.stringify( {
|
9 |
+
auth_code: authCode,
|
10 |
+
shared_id: sharedId,
|
11 |
+
nonce: '<?php echo wp_create_nonce( 'tec-tc-on-boarded' ); ?>',
|
12 |
+
} ),
|
13 |
+
} );
|
14 |
+
}
|
15 |
+
</script>
|
16 |
+
|
17 |
+
<div class="tec-tickets-commerce-connect-paypal-button">
|
18 |
+
<a
|
19 |
+
target="_blank"
|
20 |
+
data-paypal-onboard-complete="onboardedCallback"
|
21 |
+
href="<?php echo esc_url( $url ) ?>&displayMode=minibrowser"
|
22 |
+
data-paypal-button="true"
|
23 |
+
id="connect_to_paypal"
|
24 |
+
>
|
25 |
+
<?php echo wp_kses( __( 'Connect Automatically with <i>PayPal</i>', 'event-tickets' ), 'post' ); ?>
|
26 |
+
</a>
|
27 |
+
</div>
|
src/admin-views/commerce/metabox/capacity.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var string|int $ticket_capacity
|
4 |
+
*/
|
5 |
+
?>
|
6 |
+
|
7 |
+
<div
|
8 |
+
class="input_block ticket_advanced_TEC_Tickets_Commerce_Module tribe-dependent"
|
9 |
+
data-depends="#provider_TEC_Tickets_Commerce_Module_radio"
|
10 |
+
data-condition-is-checked
|
11 |
+
>
|
12 |
+
<label
|
13 |
+
for="Tribe__Tickets__Commerce__PayPal__Main_capacity"
|
14 |
+
class="ticket_form_label ticket_form_left"
|
15 |
+
>
|
16 |
+
<?php esc_html_e( 'Capacity:', 'event-tickets' ); ?>
|
17 |
+
</label>
|
18 |
+
<input
|
19 |
+
type='text' id='TEC_Tickets_Commerce_Module_capacity'
|
20 |
+
name='tribe-ticket[capacity]'
|
21 |
+
class="ticket_field tribe-tpp-field-capacity ticket_form_right"
|
22 |
+
size='7'
|
23 |
+
value='<?php echo esc_attr( -1 === (int) $ticket_capacity ? '' : $ticket_capacity ); ?>'
|
24 |
+
/>
|
25 |
+
<span class="tribe_soft_note ticket_form_right"><?php esc_html_e( 'Leave blank for unlimited', 'event-tickets' ); ?></span>
|
26 |
+
</div>
|
27 |
+
<?php
|
src/admin-views/commerce/metabox/sku.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use TEC\Tickets\Commerce\Module;
|
4 |
+
/**
|
5 |
+
* Filters the boolean value that controls whether a sku is displayed or not
|
6 |
+
*
|
7 |
+
* @since 4.7
|
8 |
+
*
|
9 |
+
* @param boolean $display_sku
|
10 |
+
*/
|
11 |
+
$display_sku = apply_filters( 'tribe_events_tickets_tpp_display_sku', true );
|
12 |
+
$html_safe_provider_class = sanitize_html_class( Module::class );
|
13 |
+
|
14 |
+
if ( ! $display_sku ) {
|
15 |
+
return;
|
16 |
+
}
|
17 |
+
?>
|
18 |
+
|
19 |
+
<div class="'ticket_advanced_<?php echo $html_safe_provider_class; ?> input_block tribe-dependent"
|
20 |
+
data-depends="#provider_TEC_Tickets_Commerce_Module_radio"
|
21 |
+
data-condition-is-checked
|
22 |
+
>
|
23 |
+
<label for="ticket_tpp_sku" class="ticket_form_label ticket_form_left"><?php esc_html_e( 'SKU:', 'event-tickets' ); ?></label>
|
24 |
+
<input
|
25 |
+
type="text"
|
26 |
+
id="ticket_sku"
|
27 |
+
name="ticket_sku"
|
28 |
+
class="ticket_field sku_input ticket_form_right"
|
29 |
+
size="14"
|
30 |
+
value="<?php echo esc_attr( $sku ); ?>"
|
31 |
+
>
|
32 |
+
<p class="description ticket_form_right">
|
33 |
+
<?php
|
34 |
+
echo esc_html(
|
35 |
+
sprintf(
|
36 |
+
__( 'A unique identifying code for each %s type you\'re selling', 'event-tickets' ),
|
37 |
+
tribe_get_ticket_label_singular_lowercase( 'sku' )
|
38 |
+
)
|
39 |
+
);
|
40 |
+
?>
|
41 |
+
</p>
|
42 |
+
</div>
|
src/admin-views/editor/fieldset/settings-provider.php
CHANGED
@@ -23,7 +23,7 @@ $default_module_class = (string) Tribe__Tickets__Tickets::get_event_ticket_provi
|
|
23 |
type="radio"
|
24 |
class="tribe-ticket-editor-field-default_provider settings_field"
|
25 |
name="tribe-tickets[settings][default_provider]"
|
26 |
-
id="provider_<?php echo esc_attr( $active_provider['
|
27 |
value="<?php echo esc_attr( $active_provider['class'] ); ?>"
|
28 |
checked
|
29 |
>
|
@@ -52,12 +52,12 @@ $default_module_class = (string) Tribe__Tickets__Tickets::get_event_ticket_provi
|
|
52 |
?></em>
|
53 |
</p>
|
54 |
<?php foreach ( $active_providers as $active_provider ) : ?>
|
55 |
-
<label class="ticket_form_right" for="provider_<?php echo esc_attr( $active_provider['
|
56 |
<input
|
57 |
<?php checked( $default_module_class, $active_provider['class'] ); ?>
|
58 |
type="radio"
|
59 |
name="tribe-tickets[settings][default_provider]"
|
60 |
-
id="provider_<?php echo esc_attr( $active_provider['
|
61 |
value="<?php echo esc_attr( $active_provider['class'] ); ?>"
|
62 |
class="tribe-ticket-editor-field-default_provider settings_field ticket_field"
|
63 |
aria-labelledby="default_ticket_provider_legend"
|
23 |
type="radio"
|
24 |
class="tribe-ticket-editor-field-default_provider settings_field"
|
25 |
name="tribe-tickets[settings][default_provider]"
|
26 |
+
id="provider_<?php echo esc_attr( $active_provider['html_safe_class'] . '_radio' ); ?>"
|
27 |
value="<?php echo esc_attr( $active_provider['class'] ); ?>"
|
28 |
checked
|
29 |
>
|
52 |
?></em>
|
53 |
</p>
|
54 |
<?php foreach ( $active_providers as $active_provider ) : ?>
|
55 |
+
<label class="ticket_form_right" for="provider_<?php echo esc_attr( $active_provider['html_safe_class'] . '_radio' ); ?>">
|
56 |
<input
|
57 |
<?php checked( $default_module_class, $active_provider['class'] ); ?>
|
58 |
type="radio"
|
59 |
name="tribe-tickets[settings][default_provider]"
|
60 |
+
id="provider_<?php echo esc_attr( $active_provider['html_safe_class'] . '_radio' ); ?>"
|
61 |
value="<?php echo esc_attr( $active_provider['class'] ); ?>"
|
62 |
class="tribe-ticket-editor-field-default_provider settings_field ticket_field"
|
63 |
aria-labelledby="default_ticket_provider_legend"
|
src/admin-views/payments/tickets-commerce.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The Template for displaying the Tickets Commerce Payments Settings.
|
4 |
+
*
|
5 |
+
* @version 5.1.9
|
6 |
+
*
|
7 |
+
* @todo This whole file needs to be completely reviewed once the designs are correct in place.
|
8 |
+
*/
|
9 |
+
|
10 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
11 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Signup;
|
12 |
+
|
13 |
+
$merchant = tribe( Merchant::class );
|
14 |
+
$is_merchant_active = $merchant->is_active();
|
15 |
+
|
16 |
+
$display = '<div class="tec-tickets-commerce-paypal-connect">';
|
17 |
+
|
18 |
+
if ( $is_merchant_active ) {
|
19 |
+
$name = $merchant->get_merchant_id();
|
20 |
+
|
21 |
+
$disconnect_url = Tribe__Settings::instance()->get_url( [ 'tab' => 'payments', 'tc-action' => 'paypal-disconnect' ] );
|
22 |
+
$refresh_url = Tribe__Settings::instance()->get_url( [ 'tab' => 'payments', 'tc-action' => 'paypal-refresh-access-token' ] );
|
23 |
+
$refresh_user_info_url = Tribe__Settings::instance()->get_url( [ 'tab' => 'payments', 'tc-action' => 'paypal-refresh-user-info' ] );
|
24 |
+
|
25 |
+
$disconnect = ' <a href="' . esc_url( $disconnect_url ) . '">' . esc_html__( 'Disconnect', 'event-tickets' ) . '</a>';
|
26 |
+
$refresh = ' <a href="' . esc_url( $refresh_url ) . '">' . esc_html__( 'Refresh Access Token', 'event-tickets' ) . '</a>';
|
27 |
+
$refresh_user_info = ' <a href="' . esc_url( $refresh_user_info_url ) . '">' . esc_html__( 'Refresh User Info', 'event-tickets' ) . '</a>';
|
28 |
+
$display .= '<p>' . esc_html__( 'PayPal Status: Connected', 'event-tickets' ) . '</p>';
|
29 |
+
$display .= '<p>' . esc_html( sprintf( __( 'Connected as: %1$s', 'event-tickets' ), $name ) ) . $disconnect . '</p>';
|
30 |
+
$display .= '<p>' . $refresh . $refresh_user_info . '</p>';
|
31 |
+
} else {
|
32 |
+
$display .= '<h2>' . esc_html__( 'Accept online payments with PayPal!', 'event-tickets' ) . '</h2>
|
33 |
+
' . esc_html__( 'Start selling tickets to your events today with PayPal. Attendees can purchase tickets directly on your site using debt or credit cards with no additional fees.',
|
34 |
+
'event-tickets' ) . tribe( Signup::class )->get_link_html();
|
35 |
+
}
|
36 |
+
$path = tribe_resource_url( 'images/admin/paypal_logo.png', false, null, Tribe__Tickets__Main::instance() );
|
37 |
+
$display .= '</div><div class="tec-tickets-commerce-paypal-logo"><img src=' . esc_url( $path ) . ' alt="Tickets Commerce PayPal Logo">';
|
38 |
+
|
39 |
+
$display .= '
|
40 |
+
<ul>
|
41 |
+
<li>' . esc_html__( 'Credit and debit card payments', 'event-tickets' ) . '</li>
|
42 |
+
<li>' . esc_html__( 'Easy, no API key connection', 'event-tickets' ) . '</li>
|
43 |
+
<li>' . esc_html__( 'Accept payments from around the world', 'event-tickets' ) . '</li>
|
44 |
+
<li>' . esc_html__( 'Support 3D Secure Payments', 'event-tickets' ) . '</li>
|
45 |
+
</ul>
|
46 |
+
';
|
47 |
+
|
48 |
+
$display .= '</div>';
|
49 |
+
|
50 |
+
$tickets_fields = [
|
51 |
+
'tribe-form-content-start' => [
|
52 |
+
'type' => 'html',
|
53 |
+
'html' => '<div class="tribe-settings-form-wrap tec-tickets-commerce-payments">',
|
54 |
+
],
|
55 |
+
'tickets-commerce-header' => [
|
56 |
+
'type' => 'html',
|
57 |
+
'html' => '<div class="tec-tickets-commerce-toggle"><label class="tec-tickets-commerce-switch"><input type="checkbox"><span class="tec-tickets-commerce-slider round"></span></label><h2>' . esc_html__( 'Enable TicketsCommerce', 'event-tickets' ) . '</h2></div>',
|
58 |
+
],
|
59 |
+
'tickets-commerce-description' => [
|
60 |
+
'type' => 'html',
|
61 |
+
'html' => '<div class="tec-tickets-commerce-description">' . esc_html__( 'TicketsCommerce allows you to accept payments for tickets with Event Tickets and Event Tickets Plus. Configure payments through PayPal, allowing users to pay with credit card or their PayPal account. Learn More about payment processing with TicketsCommerce.' ) . '</div>',
|
62 |
+
],
|
63 |
+
'tickets-commerce-paypal-description' => [
|
64 |
+
'type' => 'html',
|
65 |
+
'html' => '<div class="tec-tickets-commerce-paypal">' . $display . '</div>',
|
66 |
+
],
|
67 |
+
'tribe-form-content-end' => [
|
68 |
+
'type' => 'html',
|
69 |
+
'html' => '</div>',
|
70 |
+
],
|
71 |
+
];
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Filters the fields to be registered in the Events > Settings > Payments tab.
|
75 |
+
*
|
76 |
+
* @see Tribe__Field
|
77 |
+
* @see Tribe__Settings_Tab
|
78 |
+
*
|
79 |
+
* @param array $tickets_fields An associative array of fields definitions to register.
|
80 |
+
*
|
81 |
+
*/
|
82 |
+
$tickets_fields = apply_filters( 'tribe_tickets_commerce_payments_settings_tab_fields', $tickets_fields );
|
83 |
+
|
84 |
+
$tickets_tab = [
|
85 |
+
'priority' => 20,
|
86 |
+
'fields' => $tickets_fields,
|
87 |
+
'show_save' => false,
|
88 |
+
];
|
src/admin-views/settings/tickets-commerce/paypal-commerce/introduction.php
CHANGED
@@ -1,40 +1,59 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
-
* @
|
|
|
6 |
*
|
7 |
-
* @var string $plugin_url [Global] The plugin URL.
|
8 |
*/
|
9 |
|
10 |
-
|
|
|
11 |
|
|
|
|
|
|
|
12 |
?>
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
<
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
</p>
|
21 |
-
|
22 |
-
|
23 |
-
<img src="<?php echo esc_url( $plugin_url . 'src/resources/images/admin/paypal-logo.svg' ); ?>" width="316" height="84" alt="<?php esc_attr_e( 'PayPal Logo Image', 'event-tickets' ); ?>">
|
24 |
-
</div>
|
25 |
</div>
|
26 |
-
<div class="
|
27 |
-
<
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
|
|
39 |
</div>
|
40 |
-
</div>
|
1 |
<?php
|
2 |
/**
|
3 |
+
* The Template for displaying the Tickets Commerce Payments Settings.
|
4 |
*
|
5 |
+
* @todo This whole file needs to be completely reviewed once the designs are correct in place.
|
6 |
+
* @version 5.1.9
|
7 |
*
|
|
|
8 |
*/
|
9 |
|
10 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Merchant;
|
11 |
+
use TEC\Tickets\Commerce\Gateways\PayPal\Signup;
|
12 |
|
13 |
+
$merchant = tribe( Merchant::class );
|
14 |
+
$is_merchant_active = $merchant->is_active();
|
15 |
+
$path = tribe_resource_url( 'images/admin/paypal-logo.svg', false, null, Tribe__Tickets__Main::instance() );
|
16 |
?>
|
17 |
+
<div class="tec-tickets-commerce-paypal">
|
18 |
+
<div id="tec-tickets-commerce-paypal-connect">
|
19 |
+
<?php if ( $is_merchant_active ) : ?>
|
20 |
+
<?php
|
21 |
+
$name = $merchant->get_merchant_id();
|
22 |
|
23 |
+
$disconnect_url = Tribe__Settings::instance()->get_url( [ 'tab' => 'payments', 'tc-action' => 'paypal-disconnect' ] );
|
24 |
+
$refresh_url = Tribe__Settings::instance()->get_url( [ 'tab' => 'payments', 'tc-action' => 'paypal-refresh-access-token' ] );
|
25 |
+
$refresh_user_info_url = Tribe__Settings::instance()->get_url( [ 'tab' => 'payments', 'tc-action' => 'paypal-refresh-user-info' ] );
|
26 |
+
|
27 |
+
$disconnect = ' <a href="' . esc_url( $disconnect_url ) . '">' . esc_html__( 'Disconnect', 'event-tickets' ) . '</a>';
|
28 |
+
$refresh = ' <a href="' . esc_url( $refresh_url ) . '">' . esc_html__( 'Refresh Access Token', 'event-tickets' ) . '</a>';
|
29 |
+
$refresh_user_info = ' <a href="' . esc_url( $refresh_user_info_url ) . '">' . esc_html__( 'Refresh User Info', 'event-tickets' ) . '</a>';
|
30 |
+
?>
|
31 |
+
<p><?php esc_html_e( 'PayPal Status: Connected', 'event-tickets' ); ?></p>
|
32 |
+
<p><?php echo esc_html( sprintf( __( 'Connected as: %1$s', 'event-tickets' ), $name ) ) . $disconnect; ?></p>
|
33 |
+
<p><?php echo $refresh . $refresh_user_info; ?></p>
|
34 |
+
<?php else : ?>
|
35 |
+
<h2><?php esc_html_e( 'Accept online payments with PayPal!', 'event-tickets' ); ?></h2>
|
36 |
+
<p>
|
37 |
+
<?php esc_html_e( 'Start selling tickets to your events today with PayPal. Attendees can purchase tickets directly on your site using debt or credit cards with no additional fees.', 'event-tickets' ); ?>
|
38 |
</p>
|
39 |
+
<?php echo tribe( Signup::class )->get_link_html(); ?>
|
40 |
+
<?php endif; ?>
|
|
|
|
|
41 |
</div>
|
42 |
+
<div class="tec-tickets-commerce-paypal-logo">
|
43 |
+
<img src="<?php echo esc_url( $path ); ?>" width="316" height="84" alt="<?php esc_attr_e( 'PayPal Logo Image', 'event-tickets' ); ?>">
|
44 |
+
<ul>
|
45 |
+
<li>
|
46 |
+
<?php esc_html_e( 'Credit and Debit Card payments', 'event-tickets' ); ?>
|
47 |
+
</li>
|
48 |
+
<li>
|
49 |
+
<?php esc_html_e( 'Easy no-API key connection', 'event-tickets' ); ?>
|
50 |
+
</li>
|
51 |
+
<li>
|
52 |
+
<?php esc_html_e( 'Accept payments from around the world', 'event-tickets' ); ?>
|
53 |
+
</li>
|
54 |
+
<li>
|
55 |
+
<?php esc_html_e( 'Supports 3D Secure payments', 'event-tickets' ); ?>
|
56 |
+
</li>
|
57 |
+
</ul>
|
58 |
</div>
|
59 |
+
</div>
|
src/functions/commerce/attendees.php
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Functions and template tags dedicated to attendees in Ticket Commerce.
|
4 |
+
*
|
5 |
+
* @since 5.1.9
|
6 |
+
*/
|
7 |
+
|
8 |
+
use TEC\Tickets\Commerce\Models\Ticket_Model;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Fetches and returns a decorated post object representing an attendee.
|
12 |
+
*
|
13 |
+
* @since 5.1.9
|
14 |
+
*
|
15 |
+
* @param null|int|WP_Post $attendee The attendee ID or post object or `null` to use the global one.
|
16 |
+
* @param string|null $output The required return type. One of `OBJECT`, `ARRAY_A`, or `ARRAY_N`, which
|
17 |
+
* correspond to a WP_Post object, an associative array, or a numeric array,
|
18 |
+
* respectively. Defaults to `OBJECT`.
|
19 |
+
* @param string $filter Type of filter to apply.
|
20 |
+
* @param bool $force Whether to force a re-fetch ignoring cached results or not.
|
21 |
+
*
|
22 |
+
* @return array|mixed|void|WP_Post|null The Order post object or array, `null` if not found.
|
23 |
+
*/
|
24 |
+
function tec_tc_get_attendee( $attendee = null, $output = OBJECT, $filter = 'raw', $force = false ) {
|
25 |
+
/**
|
26 |
+
* Filters the attendee result before any logic applies.
|
27 |
+
*
|
28 |
+
* Returning a non `null` value here will short-circuit the function and return the value.
|
29 |
+
* Note: this value will not be cached and the caching of this value is a duty left to the filtering function.
|
30 |
+
*
|
31 |
+
* @since 5.1.9
|
32 |
+
*
|
33 |
+
* @param mixed $return The attendee object to return.
|
34 |
+
* @param mixed $attendee The attendee object to fetch.
|
35 |
+
* @param string|null $output The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
|
36 |
+
* correspond to a `WP_Post` object, an associative array, or a numeric array,
|
37 |
+
* respectively. Defaults to `OBJECT`.
|
38 |
+
* @param string $filter Type of filter to apply.
|
39 |
+
*/
|
40 |
+
$return = apply_filters( 'tec_tickets_commerce_get_attendee_before', null, $attendee, $output, $filter );
|
41 |
+
|
42 |
+
if ( null !== $return ) {
|
43 |
+
return $return;
|
44 |
+
}
|
45 |
+
|
46 |
+
$post = false;
|
47 |
+
|
48 |
+
/** @var Tribe__Cache $cache */
|
49 |
+
$cache = tribe( 'cache' );
|
50 |
+
|
51 |
+
$cache_post = get_post( $attendee );
|
52 |
+
|
53 |
+
if ( empty( $cache_post ) ) {
|
54 |
+
return null;
|
55 |
+
}
|
56 |
+
|
57 |
+
$key_fields = [
|
58 |
+
$cache_post->ID,
|
59 |
+
$cache_post->post_modified,
|
60 |
+
// Use the `post_password` field as we show/hide some information depending on that.
|
61 |
+
$cache_post->post_password,
|
62 |
+
// We must include options on cache key, because options influence the hydrated data on the Order object.
|
63 |
+
wp_json_encode( Tribe__Settings_Manager::get_options() ),
|
64 |
+
wp_json_encode( [
|
65 |
+
get_option( 'start_of_week' ),
|
66 |
+
get_option( 'timezone_string' ),
|
67 |
+
get_option( 'gmt_offset' )
|
68 |
+
] ),
|
69 |
+
$output,
|
70 |
+
$filter,
|
71 |
+
];
|
72 |
+
|
73 |
+
$cache_key = 'tec_tc_get_attendee_' . md5( wp_json_encode( $key_fields ) );
|
74 |
+
|
75 |
+
if ( ! $force ) {
|
76 |
+
$post = $cache->get( $cache_key, Tribe__Cache_Listener::TRIGGER_SAVE_POST );
|
77 |
+
}
|
78 |
+
|
79 |
+
if ( false === $post ) {
|
80 |
+
$post = Ticket_Model::from_post( $attendee )->to_post( $output, $filter );
|
81 |
+
|
82 |
+
if ( empty( $post ) ) {
|
83 |
+
return null;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Filters the attendee post object before caching it and returning it.
|
88 |
+
*
|
89 |
+
* Note: this value will be cached; as such this filter might not run on each request.
|
90 |
+
* If you need to filter the output value on each call of this function then use the `tec_tickets_commerce_get_attendee_before`
|
91 |
+
* filter.
|
92 |
+
*
|
93 |
+
* @since 5.1.9
|
94 |
+
*
|
95 |
+
* @param WP_Post $post The attendee post object, decorated with a set of custom properties.
|
96 |
+
* @param string $output The output format to use.
|
97 |
+
* @param string $filter The filter, or context of the fetch.
|
98 |
+
*/
|
99 |
+
$post = apply_filters( 'tec_tickets_commerce_get_attendee', $post, $output, $filter );
|
100 |
+
|
101 |
+
// Dont try to reset cache when forcing.
|
102 |
+
if ( ! $force ) {
|
103 |
+
$cache->set( $cache_key, $post, WEEK_IN_SECONDS, Tribe__Cache_Listener::TRIGGER_SAVE_POST );
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Filters the attendee result after the attendee has been built from the function.
|
109 |
+
*
|
110 |
+
* Note: this value will not be cached and the caching of this value is a duty left to the filtering function.
|
111 |
+
*
|
112 |
+
* @since 5.1.9
|
113 |
+
*
|
114 |
+
* @param WP_Post $post The attendee post object to filter and return.
|
115 |
+
* @param int|WP_Post $attendee The attendee object to fetch.
|
116 |
+
* @param string|null $output The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
|
117 |
+
* correspond to a `WP_Post` object, an associative array, or a numeric array,
|
118 |
+
* respectively. Defaults to `OBJECT`.
|
119 |
+
* @param string $filter Type of filter to apply.
|
120 |
+
*/
|
121 |
+
$post = apply_filters( 'tec_tickets_commerce_get_attendee_after', $post, $attendee, $output, $filter );
|
122 |
+
|
123 |
+
if ( OBJECT !== $output ) {
|
124 |
+
$post = ARRAY_A === $output ? (array) $post : array_values( (array) $post );
|
125 |
+
}
|
126 |
+
|
127 |
+
return $post;
|
128 |
+
}
|
src/functions/commerce/orders.php
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Functions and template tags dedicated to Orders in Ticket Commerce.
|
4 |
+
*
|
5 |
+
* @since 5.1.9
|
6 |
+
*/
|
7 |
+
|
8 |
+
use TEC\Tickets\Commerce\Models\Order_Model;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Fetches and returns a decorated post object representing an Order.
|
12 |
+
*
|
13 |
+
* @since 5.1.9
|
14 |
+
*
|
15 |
+
* @param null|int|WP_Post $order The order ID or post object or `null` to use the global one.
|
16 |
+
* @param string|null $output The required return type. One of `OBJECT`, `ARRAY_A`, or `ARRAY_N`, which
|
17 |
+
* correspond to a WP_Post object, an associative array, or a numeric array,
|
18 |
+
* respectively. Defaults to `OBJECT`.
|
19 |
+
* @param string $filter Type of filter to apply.
|
20 |
+
* @param bool $force Whether to force a re-fetch ignoring cached results or not.
|
21 |
+
*
|
22 |
+
* @return array|WP_Post|null The Order post object or array, `null` if not found.
|
23 |
+
*/
|
24 |
+
function tec_tc_get_order( $order = null, $output = OBJECT, $filter = 'raw', $force = false ) {
|
25 |
+
/**
|
26 |
+
* Filters the order result before any logic applies.
|
27 |
+
*
|
28 |
+
* Returning a non `null` value here will short-circuit the function and return the value.
|
29 |
+
* Note: this value will not be cached and the caching of this value is a duty left to the filtering function.
|
30 |
+
*
|
31 |
+
* @since 5.1.9
|
32 |
+
*
|
33 |
+
* @param mixed $return The order object to return.
|
34 |
+
* @param mixed $order The order object to fetch.
|
35 |
+
* @param string|null $output The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
|
36 |
+
* correspond to a `WP_Post` object, an associative array, or a numeric array,
|
37 |
+
* respectively. Defaults to `OBJECT`.
|
38 |
+
* @param string $filter Type of filter to apply.
|
39 |
+
*/
|
40 |
+
$return = apply_filters( 'tec_tickets_commerce_get_order_before', null, $order, $output, $filter );
|
41 |
+
|
42 |
+
if ( null !== $return ) {
|
43 |
+
return $return;
|
44 |
+
}
|
45 |
+
|
46 |
+
$post = false;
|
47 |
+
|
48 |
+
/** @var Tribe__Cache $cache */
|
49 |
+
$cache = tribe( 'cache' );
|
50 |
+
|
51 |
+
$cache_post = get_post( $order );
|
52 |
+
|
53 |
+
if ( empty( $cache_post ) ) {
|
54 |
+
return null;
|
55 |
+
}
|
56 |
+
|
57 |
+
$key_fields = [
|
58 |
+
$cache_post->ID,
|
59 |
+
$cache_post->post_modified,
|
60 |
+
// Use the `post_password` field as we show/hide some information depending on that.
|
61 |
+
$cache_post->post_password,
|
62 |
+
// We must include options on cache key, because options influence the hydrated data on the Order object.
|
63 |
+
wp_json_encode( Tribe__Settings_Manager::get_options() ),
|
64 |
+
wp_json_encode( [
|
65 |
+
get_option( 'start_of_week' ),
|
66 |
+
get_option( 'timezone_string' ),
|
67 |
+
get_option( 'gmt_offset' )
|
68 |
+
] ),
|
69 |
+
$output,
|
70 |
+
$filter,
|
71 |
+
];
|
72 |
+
|
73 |
+
$cache_key = 'tec_tc_get_order_' . md5( wp_json_encode( $key_fields ) );
|
74 |
+
|
75 |
+
if ( ! $force ) {
|
76 |
+
$post = $cache->get( $cache_key, Tribe__Cache_Listener::TRIGGER_SAVE_POST );
|
77 |
+
}
|
78 |
+
|
79 |
+
if ( false === $post ) {
|
80 |
+
$post = Order_Model::from_post( $order )->to_post( $output, $filter );
|
81 |
+
|
82 |
+
if ( empty( $post ) ) {
|
83 |
+
return null;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Filters the order post object before caching it and returning it.
|
88 |
+
*
|
89 |
+
* Note: this value will be cached; as such this filter might not run on each request.
|
90 |
+
* If you need to filter the output value on each call of this function then use the `tec_tickets_commerce_get_order_before`
|
91 |
+
* filter.
|
92 |
+
*
|
93 |
+
* @since 5.1.9
|
94 |
+
*
|
95 |
+
* @param WP_Post $post The order post object, decorated with a set of custom properties.
|
96 |
+
* @param string $output The output format to use.
|
97 |
+
* @param string $filter The filter, or context of the fetch.
|
98 |
+
*/
|
99 |
+
$post = apply_filters( 'tec_tickets_commerce_get_order', $post, $output, $filter );
|
100 |
+
|
101 |
+
// Dont try to reset cache when forcing.
|
102 |
+
if ( ! $force ) {
|
103 |
+
$cache->set( $cache_key, $post, WEEK_IN_SECONDS, Tribe__Cache_Listener::TRIGGER_SAVE_POST );
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Filters the order result after the order has been built from the function.
|
109 |
+
*
|
110 |
+
* Note: this value will not be cached and the caching of this value is a duty left to the filtering function.
|
111 |
+
*
|
112 |
+
* @since 5.1.9
|
113 |
+
*
|
114 |
+
* @param WP_Post $post The order post object to filter and return.
|
115 |
+
* @param int|WP_Post $order The order object to fetch.
|
116 |
+
* @param string|null $output The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
|
117 |
+
* correspond to a `WP_Post` object, an associative array, or a numeric array,
|
118 |
+
* respectively. Defaults to `OBJECT`.
|
119 |
+
* @param string $filter Type of filter to apply.
|
120 |
+
*/
|
121 |
+
$post = apply_filters( 'tec_tickets_commerce_get_order_after', $post, $order, $output, $filter );
|
122 |
+
|
123 |
+
if ( OBJECT !== $output ) {
|
124 |
+
$post = ARRAY_A === $output ? (array) $post : array_values( (array) $post );
|
125 |
+
}
|
126 |
+
|
127 |
+
return $post;
|
128 |
+
}
|
src/functions/commerce/orm.php
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
use \Tribe__Utils__Array as Arr;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Builds and returns the correct Orders repository.
|
6 |
+
*
|
7 |
+
* @since 5.1.9
|
8 |
+
*
|
9 |
+
* @param string $repository The slug of the repository to build/return.
|
10 |
+
*
|
11 |
+
* @return Tribe__Repository__Interface An instance of the requested repository
|
12 |
+
* class.
|
13 |
+
*/
|
14 |
+
function tec_tc_orders( $repository = 'default' ) {
|
15 |
+
$map = [
|
16 |
+
'default' => TEC\Tickets\Commerce\Repositories\Order_Repository::class,
|
17 |
+
];
|
18 |
+
|
19 |
+
$args = func_num_args() > 1 ? array_slice( func_get_args(), 1 ) : [];
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Filters the map relating orders repository slugs to service container bindings.
|
23 |
+
*
|
24 |
+
* @since 5.1.9
|
25 |
+
*
|
26 |
+
* @param array $map A map in the shape [ <repository_slug> => <service_name> ]
|
27 |
+
* @param string $repository The currently requested implementation.
|
28 |
+
* @param array $args An array of additional call arguments used to call the function beside the
|
29 |
+
* repository slug.
|
30 |
+
*/
|
31 |
+
$map = apply_filters( 'tec_tickets_commerce_orders_repository_map', $map, $repository, $args );
|
32 |
+
|
33 |
+
return tribe( Arr::get( $map, $repository, $map['default'] ) );
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Builds and returns the correct Tickets repository.
|
38 |
+
*
|
39 |
+
* @since 5.1.9
|
40 |
+
*
|
41 |
+
* @param string $repository The slug of the repository to build/return.
|
42 |
+
*
|
43 |
+
* @return Tribe__Repository__Interface An instance of the requested repository
|
44 |
+
* class.
|
45 |
+
*/
|
46 |
+
function tec_tc_tickets( $repository = 'default' ) {
|
47 |
+
$map = [
|
48 |
+
'default' => TEC\Tickets\Commerce\Repositories\Tickets_Repository::class,
|
49 |
+
];
|
50 |
+
|
51 |
+
$args = func_num_args() > 1 ? array_slice( func_get_args(), 1 ) : [];
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Filters the map relating tickets repository slugs to service container bindings.
|
55 |
+
*
|
56 |
+
* @since 5.1.9
|
57 |
+
*
|
58 |
+
* @param array $map A map in the shape [ <repository_slug> => <service_name> ]
|
59 |
+
* @param string $repository The currently requested implementation.
|
60 |
+
* @param array $args An array of additional call arguments used to call the function beside the
|
61 |
+
* repository slug.
|
62 |
+
*/
|
63 |
+
$map = apply_filters( 'tec_tickets_commerce_tickets_repository_map', $map, $repository, $args );
|
64 |
+
|
65 |
+
return tribe( Arr::get( $map, $repository, $map['default'] ) );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Builds and returns the correct Attendees repository.
|
70 |
+
*
|
71 |
+
* @since 5.1.9
|
72 |
+
*
|
73 |
+
* @param string $repository The slug of the repository to build/return.
|
74 |
+
*
|
75 |
+
* @return Tribe__Repository__Interface An instance of the requested repository
|
76 |
+
* class.
|
77 |
+
*/
|
78 |
+
function tec_tc_attendees( $repository = 'default' ) {
|
79 |
+
$map = [
|
80 |
+
'default' => TEC\Tickets\Commerce\Repositories\Attendees_Repository::class,
|
81 |
+
];
|
82 |
+
|
83 |
+
$args = func_num_args() > 1 ? array_slice( func_get_args(), 1 ) : [];
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Filters the map relating attendees repository slugs to service container bindings.
|
87 |
+
*
|
88 |
+
* @since 5.1.9
|
89 |
+
*
|
90 |
+
* @param array $map A map in the shape [ <repository_slug> => <service_name> ]
|
91 |
+
* @param string $repository The currently requested implementation.
|
92 |
+
* @param array $args An array of additional call arguments used to call the function beside the
|
93 |
+
* repository slug.
|
94 |
+
*/
|
95 |
+
$map = apply_filters( 'tec_tickets_commerce_attendees_repository_map', $map, $repository, $args );
|
96 |
+
|
97 |
+
return tribe( Arr::get( $map, $repository, $map['default'] ) );
|
98 |
+
}
|
src/functions/commerce/tickets.php
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Functions and template tags dedicated to tickets in Ticket Commerce.
|
4 |
+
*
|
5 |
+
* @since 5.1.9
|
6 |
+
*/
|
7 |
+
|
8 |
+
use TEC\Tickets\Commerce\Models\Ticket_Model;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Fetches and returns a decorated post object representing an ticket.
|
12 |
+
*
|
13 |
+
* @since 5.1.9
|
14 |
+
*
|
15 |
+
* @param null|int|WP_Post $ticket The ticket ID or post object or `null` to use the global one.
|
16 |
+
* @param string|null $output The required return type. One of `OBJECT`, `ARRAY_A`, or `ARRAY_N`, which
|
17 |
+
* correspond to a WP_Post object, an associative array, or a numeric array,
|
18 |
+
* respectively. Defaults to `OBJECT`.
|
19 |
+
* @param string $filter Type of filter to apply.
|
20 |
+
* @param bool $force Whether to force a re-fetch ignoring cached results or not.
|
21 |
+
*
|
22 |
+
* @return array|mixed|void|WP_Post|null The Order post object or array, `null` if not found.
|
23 |
+
*/
|
24 |
+
function tec_tc_get_ticket( $ticket = null, $output = OBJECT, $filter = 'raw', $force = false ) {
|
25 |
+
/**
|
26 |
+
* Filters the ticket result before any logic applies.
|
27 |
+
*
|
28 |
+
* Returning a non `null` value here will short-circuit the function and return the value.
|
29 |
+
* Note: this value will not be cached and the caching of this value is a duty left to the filtering function.
|
30 |
+
*
|
31 |
+
* @since 5.1.9
|
32 |
+
*
|
33 |
+
* @param mixed $return The ticket object to return.
|
34 |
+
* @param mixed $ticket The ticket object to fetch.
|
35 |
+
* @param string|null $output The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
|
36 |
+
* correspond to a `WP_Post` object, an associative array, or a numeric array,
|
37 |
+
* respectively. Defaults to `OBJECT`.
|
38 |
+
* @param string $filter Type of filter to apply.
|
39 |
+
*/
|
40 |
+
$return = apply_filters( 'tec_tickets_commerce_get_ticket_before', null, $ticket, $output, $filter );
|
41 |
+
|
42 |
+
if ( null !== $return ) {
|
43 |
+
return $return;
|
44 |
+
}
|
45 |
+
|
46 |
+
$post = false;
|
47 |
+
|
48 |
+
/** @var Tribe__Cache $cache */
|
49 |
+
$cache = tribe( 'cache' );
|
50 |
+
|
51 |
+
$cache_post = get_post( $ticket );
|
52 |
+
|
53 |
+
if ( empty( $cache_post ) ) {
|
54 |
+
return null;
|
55 |
+
}
|
56 |
+
|
57 |
+
$key_fields = [
|
58 |
+
$cache_post->ID,
|
59 |
+
$cache_post->post_modified,
|
60 |
+
// Use the `post_password` field as we show/hide some information depending on that.
|
61 |
+
$cache_post->post_password,
|
62 |
+
// We must include options on cache key, because options influence the hydrated data on the Order object.
|
63 |
+
wp_json_encode( Tribe__Settings_Manager::get_options() ),
|
64 |
+
wp_json_encode( [
|
65 |
+
get_option( 'start_of_week' ),
|
66 |
+
get_option( 'timezone_string' ),
|
67 |
+
get_option( 'gmt_offset' )
|
68 |
+
] ),
|
69 |
+
$output,
|
70 |
+
$filter,
|
71 |
+
];
|
72 |
+
|
73 |
+
$cache_key = 'tec_tc_get_ticket_' . md5( wp_json_encode( $key_fields ) );
|
74 |
+
|
75 |
+
if ( ! $force ) {
|
76 |
+
$post = $cache->get( $cache_key, Tribe__Cache_Listener::TRIGGER_SAVE_POST );
|
77 |
+
}
|
78 |
+
|
79 |
+
if ( false === $post ) {
|
80 |
+
$post = Ticket_Model::from_post( $ticket )->to_post( $output, $filter );
|
81 |
+
|
82 |
+
if ( empty( $post ) ) {
|
83 |
+
return null;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Filters the ticket post object before caching it and returning it.
|
88 |
+
*
|
89 |
+
* Note: this value will be cached; as such this filter might not run on each request.
|
90 |
+
* If you need to filter the output value on each call of this function then use the `tec_tickets_commerce_get_ticket_before`
|
91 |
+
* filter.
|
92 |
+
*
|
93 |
+
* @since 5.1.9
|
94 |
+
*
|
95 |
+
* @param WP_Post $post The ticket post object, decorated with a set of custom properties.
|
96 |
+
* @param string $output The output format to use.
|
97 |
+
* @param string $filter The filter, or context of the fetch.
|
98 |
+
*/
|
99 |
+
$post = apply_filters( 'tec_tickets_commerce_get_ticket', $post, $output, $filter );
|
100 |
+
|
101 |
+
// Dont try to reset cache when forcing.
|
102 |
+
if ( ! $force ) {
|
103 |
+
$cache->set( $cache_key, $post, WEEK_IN_SECONDS, Tribe__Cache_Listener::TRIGGER_SAVE_POST );
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Filters the ticket result after the ticket has been built from the function.
|
109 |
+
*
|
110 |
+
* Note: this value will not be cached and the caching of this value is a duty left to the filtering function.
|
111 |
+
*
|
112 |
+
* @since 5.1.9
|
113 |
+
*
|
114 |
+
* @param WP_Post $post The ticket post object to filter and return.
|
115 |
+
* @param int|WP_Post $ticket The ticket object to fetch.
|
116 |
+
* @param string|null $output The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
|
117 |
+
* correspond to a `WP_Post` object, an associative array, or a numeric array,
|
118 |
+
* respectively. Defaults to `OBJECT`.
|
119 |
+
* @param string $filter Type of filter to apply.
|
120 |
+
*/
|
121 |
+
$post = apply_filters( 'tec_tickets_commerce_get_ticket_after', $post, $ticket, $output, $filter );
|
122 |
+
|
123 |
+
if ( OBJECT !== $output ) {
|
124 |
+
$post = ARRAY_A === $output ? (array) $post : array_values( (array) $post );
|
125 |
+
}
|
126 |
+
|
127 |
+
return $post;
|
128 |
+
}
|
src/modules/blocks/rsvp/move-delete/style.pcss
CHANGED
@@ -9,7 +9,7 @@
|
|
9 |
&:first-child {
|
10 |
color: #009fd4;
|
11 |
|
12 |
-
|
13 |
color: #8d949b;
|
14 |
content: '|';
|
15 |
margin: 0 10px;
|
9 |
&:first-child {
|
10 |
color: #009fd4;
|
11 |
|
12 |
+
&:after {
|
13 |
color: #8d949b;
|
14 |
content: '|';
|
15 |
margin: 0 10px;
|
src/modules/blocks/ticket/container-content/advanced-options/move-delete/style.pcss
CHANGED
@@ -9,7 +9,7 @@
|
|
9 |
&:first-child {
|
10 |
color: #009fd4;
|
11 |
|
12 |
-
|
13 |
color: #8d949b;
|
14 |
content: '|';
|
15 |
margin: 0 10px;
|
9 |
&:first-child {
|
10 |
color: #009fd4;
|
11 |
|
12 |
+
&:after {
|
13 |
color: #8d949b;
|
14 |
content: '|';
|
15 |
margin: 0 10px;
|
src/resources/css/app/rsvp/frontend.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.tribe-block__rsvp{font-family:
|
1 |
+
.tribe-block__rsvp{font-family:var(--tec-font-family-sans-serif);margin-bottom:30px;margin-top:30px;max-width:580px;position:relative}.tribe-block__rsvp__ticket{border:1px solid #e1e3e6;display:flex;flex-wrap:wrap;position:relative;width:100%}.tribe-block__rsvp__icon{align-items:center;background:#fff;border-bottom:1px dashed #b5bcc2;color:#434343;display:flex;flex:none;flex-direction:column;font-size:14px;font-weight:700;line-height:17px;padding:20px 17px;width:100%}.tribe-block__rsvp__icon svg{margin-bottom:7px}.tribe-block__rsvp__content{background-color:#f5f8f9;flex:auto}.tribe-block__rsvp__details{padding:25px 20px 20px}.tribe-block__rsvp__title{color:#000;font-size:21px;font-weight:700;line-height:28px;margin-bottom:12px}.tribe-block__rsvp__description{color:#545d66;font-size:14px;line-height:18px;margin-bottom:15px}.tribe-block__rsvp__availability{color:#545d66;display:flex;align-items:center;font-size:12px;line-height:18px}.tribe-block__rsvp__quantity{font-size:18px;font-weight:700;margin-right:6px}.tribe-block__rsvp__status{display:flex;flex-wrap:nowrap;padding:0 20px 25px;text-align:center}.tribe-block__rsvp__status>span{flex:none;margin-right:15px;width:calc(50% - 7.5px)}.tribe-block__rsvp__status>span:last-child{margin-right:0}.tribe-block__rsvp__status-button{align-items:center;border:1px solid #545d66;border-radius:4px;background:#fff;color:#545d66;display:flex;font-family:var(--tec-font-family-sans-serif);font-size:14px;font-weight:700;height:44px;justify-content:center;line-height:1;padding:0;width:100%}.tribe-block__rsvp__status-button svg{margin-left:9px}.tribe-block__rsvp__status-button:focus,.tribe-block__rsvp__status-button:hover{background:#fff;border:1px solid #000;color:#000}.tribe-block__rsvp__status-button.tribe-active{border:1px solid #000;color:#000}.tribe-block__rsvp__status-button.tribe-inactive{border:1px solid #e1e3e6;color:#a2aab2}.tribe-block__rsvp__status-button.tribe-inactive:focus,.tribe-block__rsvp__status-button.tribe-inactive:hover{background:#fff;border:1px solid #545d66;color:#545d66}.tribe-block__rsvp__status-button[disabled=disabled]{cursor:default}.tribe-block__rsvp__going-icon,.tribe-block__rsvp__not-going-icon{fill:#a2aab2}.tribe-active .tribe-block__rsvp__going-icon,.tribe-active .tribe-block__rsvp__not-going-icon,.tribe-block__rsvp__status-button:focus .tribe-block__rsvp__going-icon,.tribe-block__rsvp__status-button:focus .tribe-block__rsvp__not-going-icon,.tribe-block__rsvp__status-button:hover .tribe-block__rsvp__going-icon,.tribe-block__rsvp__status-button:hover .tribe-block__rsvp__not-going-icon{fill:#191e23}.tribe-inactive .tribe-block__rsvp__going-icon,.tribe-inactive .tribe-block__rsvp__not-going-icon{fill:#e1e3e6}.tribe-inactive:focus .tribe-block__rsvp__going-icon,.tribe-inactive:focus .tribe-block__rsvp__not-going-icon,.tribe-inactive:hover .tribe-block__rsvp__going-icon,.tribe-inactive:hover .tribe-block__rsvp__not-going-icon{fill:#a2aab2}.tribe-block__rsvp__form{padding:0 20px}.tribe-block__rsvp__form form{border-top:1px solid #e1e3e6;display:flex;padding:30px 0}.tribe-left{flex:none}.tribe-block__rsvp__number-input{padding-right:20px}.tribe-block__rsvp__number-input-inner{align-items:center;display:flex}.tribe-block__rsvp__number-input-inner input[type=number]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield;background:transparent;border:none;color:#000;font-family:var(--tec-font-family-sans-serif);font-size:30px;font-weight:700;height:40px;max-width:48px;padding:4px 0;text-align:center}.tribe-block__rsvp__number-input-inner input[type=number]::-webkit-inner-spin-button,.tribe-block__rsvp__number-input-inner input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;appearance:none}.tribe-block__rsvp__number-input-label{display:block;font-size:14px;font-weight:700;line-height:18px;margin-top:9px;text-align:center}.tribe-block__rsvp__number-input-button{background-color:transparent;height:30px;padding:0;position:relative;width:20px}.tribe-block__rsvp__number-input-button:after,.tribe-block__rsvp__number-input-button:before{background-color:#aeb4bb;content:"";height:2px;position:absolute;width:10px}.tribe-block__rsvp__number-input-button:focus,.tribe-block__rsvp__number-input-button:hover{background:none}.tribe-block__rsvp__number-input-button:focus:after,.tribe-block__rsvp__number-input-button:focus:before,.tribe-block__rsvp__number-input-button:hover:after,.tribe-block__rsvp__number-input-button:hover:before{background-color:#545d66}.tribe-block__rsvp__number-input-button--minus{margin-left:-10px}.tribe-block__rsvp__number-input-button--minus:after,.tribe-block__rsvp__number-input-button--minus:before{right:0}.tribe-block__rsvp__number-input-button--plus{margin-right:-10px}.tribe-block__rsvp__number-input-button--plus:after,.tribe-block__rsvp__number-input-button--plus:before{left:0}.tribe-block__rsvp__number-input-button--plus:after{transform:rotate(90deg)}.tribe-right{flex:auto}.tribe-right input[type=email],.tribe-right input[type=text]{border-color:#e1e3e6;color:#000;display:block;font-family:var(--tec-font-family-sans-serif);font-size:16px;height:40px;line-height:18px;margin-bottom:15px;padding:10px 15px;width:100%}.tribe-right input[type=email]::-moz-placeholder,.tribe-right input[type=text]::-moz-placeholder{color:#a2aab2}.tribe-right input[type=email]:-ms-input-placeholder,.tribe-right input[type=text]:-ms-input-placeholder{color:#a2aab2}.tribe-right input[type=email]::placeholder,.tribe-right input[type=text]::placeholder{color:#a2aab2}.tribe-right label{cursor:pointer;font-size:var(--tec-font-size-2);font-weight:400}.tribe-right label[for^=tribe-tickets-attendees-list-optout]{align-items:flex-start;display:flex;margin:0 0 15px;padding-top:7px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border:1px solid #e1e3e6;border-radius:0;cursor:pointer;flex:none;height:16px;margin:1px 10px 0 0;width:16px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]:focus{box-shadow:0 0 0 1px #e1e3e6;outline:2px solid transparent;outline-offset:-2px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]:checked:before{color:#009fd4;content:"\F147";display:inline-block;float:left;font:normal 21px/1 dashicons;margin:-3px 0 0 -4px;speak:none;vertical-align:middle;width:16px}.tribe-tickets-meta-option-label{color:#000;font-size:14px;line-height:18px}.tribe-block__rsvp__message__error,.tribe-block__rsvp__message__success{color:#000;font-size:14px;line-height:18px;padding:20px}.tribe-block__rsvp__message__error{background:#ffebe8;border:1px solid #c00;display:none;margin-bottom:20px}.tribe-block__rsvp__message__success{background:#ecfae5;border:1px solid #1bd800;margin-top:20px}.tribe-block__rsvp__submit-button{background:#009fd4;color:#fff;font-family:var(--tec-font-family-sans-serif);font-size:15px;font-weight:700;line-height:18px;margin:10px 0 0;padding:10px 23px}.tribe-block__rsvp__submit-button:focus,.tribe-block__rsvp__submit-button:hover{background:#007bb4}.tribe-block__rsvp__submit-button:disabled{cursor:not-allowed;background:#a2aab2}.tribe-block__rsvp__form__attendee-meta{margin:0}.tribe-block__rsvp__form__attendee-meta td,.tribe-block__rsvp__form__attendee-meta th{padding:0;border:none;word-break:normal}.tribe-common-c-loader.tribe-block__rsvp__loading{align-items:center;background:hsla(0,0%,100%,.7);height:100%;justify-content:center;left:0;margin:0;padding:0;position:absolute;text-align:center;top:0;width:100%;z-index:99}.tribe-common-c-loader.tribe-block__rsvp__loading svg{max-width:70px;position:absolute;top:35%}.tribe-common-c-loader.tribe-block__rsvp__loading svg circle{fill:#888}@media (min-width:600px){.tribe-block__rsvp__ticket{align-items:stretch;flex-wrap:nowrap}.tribe-block__rsvp__icon{border-bottom:none;border-right:1px dashed #b5bcc2;padding:28px 17px;width:84px}.tribe-block__rsvp__number-input-inner input[type=number]{font-size:36px;height:48px}.tribe-block__rsvp__message__success{padding:10px 30px;text-align:center}}
|
src/resources/css/app/rsvp/frontend.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.tribe-block__rsvp{font-family:
|
1 |
+
.tribe-block__rsvp{font-family:var(--tec-font-family-sans-serif);margin-bottom:30px;margin-top:30px;max-width:580px;position:relative}.tribe-block__rsvp__ticket{border:1px solid #e1e3e6;display:flex;flex-wrap:wrap;position:relative;width:100%}.tribe-block__rsvp__icon{align-items:center;background:#fff;border-bottom:1px dashed #b5bcc2;color:#434343;display:flex;flex:none;flex-direction:column;font-size:14px;font-weight:700;line-height:17px;padding:20px 17px;width:100%}.tribe-block__rsvp__icon svg{margin-bottom:7px}.tribe-block__rsvp__content{background-color:#f5f8f9;flex:auto}.tribe-block__rsvp__details{padding:25px 20px 20px}.tribe-block__rsvp__title{color:#000;font-size:21px;font-weight:700;line-height:28px;margin-bottom:12px}.tribe-block__rsvp__description{color:#545d66;font-size:14px;line-height:18px;margin-bottom:15px}.tribe-block__rsvp__availability{color:#545d66;display:flex;align-items:center;font-size:12px;line-height:18px}.tribe-block__rsvp__quantity{font-size:18px;font-weight:700;margin-right:6px}.tribe-block__rsvp__status{display:flex;flex-wrap:nowrap;padding:0 20px 25px;text-align:center}.tribe-block__rsvp__status>span{flex:none;margin-right:15px;width:calc(50% - 7.5px)}.tribe-block__rsvp__status>span:last-child{margin-right:0}.tribe-block__rsvp__status-button{align-items:center;border:1px solid #545d66;border-radius:4px;background:#fff;color:#545d66;display:flex;font-family:var(--tec-font-family-sans-serif);font-size:14px;font-weight:700;height:44px;justify-content:center;line-height:1;padding:0;width:100%}.tribe-block__rsvp__status-button svg{margin-left:9px}.tribe-block__rsvp__status-button:focus,.tribe-block__rsvp__status-button:hover{background:#fff;border:1px solid #000;color:#000}.tribe-block__rsvp__status-button.tribe-active{border:1px solid #000;color:#000}.tribe-block__rsvp__status-button.tribe-inactive{border:1px solid #e1e3e6;color:#a2aab2}.tribe-block__rsvp__status-button.tribe-inactive:focus,.tribe-block__rsvp__status-button.tribe-inactive:hover{background:#fff;border:1px solid #545d66;color:#545d66}.tribe-block__rsvp__status-button[disabled=disabled]{cursor:default}.tribe-block__rsvp__going-icon,.tribe-block__rsvp__not-going-icon{fill:#a2aab2}.tribe-active .tribe-block__rsvp__going-icon,.tribe-active .tribe-block__rsvp__not-going-icon,.tribe-block__rsvp__status-button:focus .tribe-block__rsvp__going-icon,.tribe-block__rsvp__status-button:focus .tribe-block__rsvp__not-going-icon,.tribe-block__rsvp__status-button:hover .tribe-block__rsvp__going-icon,.tribe-block__rsvp__status-button:hover .tribe-block__rsvp__not-going-icon{fill:#191e23}.tribe-inactive .tribe-block__rsvp__going-icon,.tribe-inactive .tribe-block__rsvp__not-going-icon{fill:#e1e3e6}.tribe-inactive:focus .tribe-block__rsvp__going-icon,.tribe-inactive:focus .tribe-block__rsvp__not-going-icon,.tribe-inactive:hover .tribe-block__rsvp__going-icon,.tribe-inactive:hover .tribe-block__rsvp__not-going-icon{fill:#a2aab2}.tribe-block__rsvp__form{padding:0 20px}.tribe-block__rsvp__form form{border-top:1px solid #e1e3e6;display:flex;padding:30px 0}.tribe-left{flex:none}.tribe-block__rsvp__number-input{padding-right:20px}.tribe-block__rsvp__number-input-inner{align-items:center;display:flex}.tribe-block__rsvp__number-input-inner input[type=number]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield;background:transparent;border:none;color:#000;font-family:var(--tec-font-family-sans-serif);font-size:30px;font-weight:700;height:40px;max-width:48px;padding:4px 0;text-align:center}.tribe-block__rsvp__number-input-inner input[type=number]::-webkit-inner-spin-button,.tribe-block__rsvp__number-input-inner input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;appearance:none}.tribe-block__rsvp__number-input-label{display:block;font-size:14px;font-weight:700;line-height:18px;margin-top:9px;text-align:center}.tribe-block__rsvp__number-input-button{background-color:transparent;height:30px;padding:0;position:relative;width:20px}.tribe-block__rsvp__number-input-button:after,.tribe-block__rsvp__number-input-button:before{background-color:#aeb4bb;content:"";height:2px;position:absolute;width:10px}.tribe-block__rsvp__number-input-button:focus,.tribe-block__rsvp__number-input-button:hover{background:none}.tribe-block__rsvp__number-input-button:focus:after,.tribe-block__rsvp__number-input-button:focus:before,.tribe-block__rsvp__number-input-button:hover:after,.tribe-block__rsvp__number-input-button:hover:before{background-color:#545d66}.tribe-block__rsvp__number-input-button--minus{margin-left:-10px}.tribe-block__rsvp__number-input-button--minus:after,.tribe-block__rsvp__number-input-button--minus:before{right:0}.tribe-block__rsvp__number-input-button--plus{margin-right:-10px}.tribe-block__rsvp__number-input-button--plus:after,.tribe-block__rsvp__number-input-button--plus:before{left:0}.tribe-block__rsvp__number-input-button--plus:after{transform:rotate(90deg)}.tribe-right{flex:auto}.tribe-right input[type=email],.tribe-right input[type=text]{border-color:#e1e3e6;color:#000;display:block;font-family:var(--tec-font-family-sans-serif);font-size:16px;height:40px;line-height:18px;margin-bottom:15px;padding:10px 15px;width:100%}.tribe-right input[type=email]::-moz-placeholder,.tribe-right input[type=text]::-moz-placeholder{color:#a2aab2}.tribe-right input[type=email]:-ms-input-placeholder,.tribe-right input[type=text]:-ms-input-placeholder{color:#a2aab2}.tribe-right input[type=email]::placeholder,.tribe-right input[type=text]::placeholder{color:#a2aab2}.tribe-right label{cursor:pointer;font-size:var(--tec-font-size-2);font-weight:400}.tribe-right label[for^=tribe-tickets-attendees-list-optout]{align-items:flex-start;display:flex;margin:0 0 15px;padding-top:7px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border:1px solid #e1e3e6;border-radius:0;cursor:pointer;flex:none;height:16px;margin:1px 10px 0 0;width:16px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]:focus{box-shadow:0 0 0 1px #e1e3e6;outline:2px solid transparent;outline-offset:-2px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]:checked:before{color:#009fd4;content:"\F147";display:inline-block;float:left;font:normal 21px/1 dashicons;margin:-3px 0 0 -4px;speak:none;vertical-align:middle;width:16px}.tribe-tickets-meta-option-label{color:#000;font-size:14px;line-height:18px}.tribe-block__rsvp__message__error,.tribe-block__rsvp__message__success{color:#000;font-size:14px;line-height:18px;padding:20px}.tribe-block__rsvp__message__error{background:#ffebe8;border:1px solid #c00;display:none;margin-bottom:20px}.tribe-block__rsvp__message__success{background:#ecfae5;border:1px solid #1bd800;margin-top:20px}.tribe-block__rsvp__submit-button{background:#009fd4;color:#fff;font-family:var(--tec-font-family-sans-serif);font-size:15px;font-weight:700;line-height:18px;margin:10px 0 0;padding:10px 23px}.tribe-block__rsvp__submit-button:focus,.tribe-block__rsvp__submit-button:hover{background:#007bb4}.tribe-block__rsvp__submit-button:disabled{cursor:not-allowed;background:#a2aab2}.tribe-block__rsvp__form__attendee-meta{margin:0}.tribe-block__rsvp__form__attendee-meta td,.tribe-block__rsvp__form__attendee-meta th{padding:0;border:none;word-break:normal}.tribe-common-c-loader.tribe-block__rsvp__loading{align-items:center;background:hsla(0,0%,100%,.7);height:100%;justify-content:center;left:0;margin:0;padding:0;position:absolute;text-align:center;top:0;width:100%;z-index:99}.tribe-common-c-loader.tribe-block__rsvp__loading svg{max-width:70px;position:absolute;top:35%}.tribe-common-c-loader.tribe-block__rsvp__loading svg circle{fill:#888}@media (min-width:600px){.tribe-block__rsvp__ticket{align-items:stretch;flex-wrap:nowrap}.tribe-block__rsvp__icon{border-bottom:none;border-right:1px dashed #b5bcc2;padding:28px 17px;width:84px}.tribe-block__rsvp__number-input-inner input[type=number]{font-size:36px;height:48px}.tribe-block__rsvp__message__success{padding:10px 30px;text-align:center}}
|
src/resources/css/attendees.css
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
-
* @see:
|
9 |
*/
|
10 |
|
11 |
/**
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
+
* @see: https://the-events-calendar.github.io/products-engineering/docs/code-standards/css/
|
9 |
*/
|
10 |
|
11 |
/**
|
src/resources/css/common-responsive.css
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
-
* @see:
|
9 |
*/
|
10 |
|
11 |
/**
|
@@ -15,6 +15,20 @@
|
|
15 |
* @todo @juanfra: Check this once we define https://github.com/the-events-calendar/tribe-common/pull/1379
|
16 |
*/
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/* -----------------------------------------------------------------------------
|
19 |
*
|
20 |
* Utilities
|
@@ -303,9 +317,331 @@
|
|
303 |
* Visually Show: Show element after has been hidden with %visually-hide
|
304 |
* ----------------------------------------------------------------------------- */
|
305 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
.event-tickets {
|
307 |
|
308 |
-
/* From: base/full/typography/_body.pcss*/
|
309 |
|
310 |
/* From: base/full/typography/_headings.pcss */
|
311 |
|
@@ -384,7 +720,7 @@
|
|
384 |
|
385 |
/* From: base/skeleton/forms/_text.pcss */
|
386 |
|
387 |
-
/* From: base/skeleton/grid/_rows.pcss*/
|
388 |
|
389 |
/* -------------------------------------------------------------------------
|
390 |
* Theme Overrides - Twenty Twenty
|
@@ -394,7 +730,21 @@
|
|
394 |
background-color: transparent;
|
395 |
}
|
396 |
|
397 |
-
@media(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
398 |
|
399 |
.event-tickets .tribe-common-form-control-text__input {
|
400 |
color: var(--tec-color-text-primary);
|
@@ -487,16 +837,16 @@
|
|
487 |
}
|
488 |
|
489 |
.event-tickets .tribe-common-form-control-text__input {
|
490 |
-
padding: var(--spacer-4) var(--spacer-4) var(--spacer-4) var(--spacer-8)
|
491 |
}
|
492 |
|
493 |
.event-tickets .tribe-common-g-row--gutters {
|
494 |
-
margin-left: var(--grid-gutter-half-negative);
|
495 |
-
margin-right: var(--grid-gutter-half-negative)
|
496 |
}
|
497 |
|
498 |
.event-tickets .tribe-common-g-row--gutters > .tribe-common-g-col {
|
499 |
-
padding-left: var(--grid-gutter-half);
|
500 |
-
padding-right: var(--grid-gutter-half)
|
501 |
}
|
502 |
}
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
+
* @see: https://the-events-calendar.github.io/products-engineering/docs/code-standards/css/
|
9 |
*/
|
10 |
|
11 |
/**
|
15 |
* @todo @juanfra: Check this once we define https://github.com/the-events-calendar/tribe-common/pull/1379
|
16 |
*/
|
17 |
|
18 |
+
/* Import Mixins */
|
19 |
+
|
20 |
+
/*
|
21 |
+
* Common CSS
|
22 |
+
*
|
23 |
+
* DO NOT EDIT THIS CSS FILE DIRECTLY.
|
24 |
+
* -------------------------------------------------------------
|
25 |
+
* This file is just a clearing-house, see the pcss directory
|
26 |
+
*
|
27 |
+
and edit the source files found there.
|
28 |
+
*/
|
29 |
+
|
30 |
+
/* Event Tickets Utilities */
|
31 |
+
|
32 |
/* -----------------------------------------------------------------------------
|
33 |
*
|
34 |
* Utilities
|
317 |
* Visually Show: Show element after has been hidden with %visually-hide
|
318 |
* ----------------------------------------------------------------------------- */
|
319 |
|
320 |
+
/* Event Tickets Components */
|
321 |
+
|
322 |
+
/* Accordion Styles */
|
323 |
+
|
324 |
+
.accordion-header {
|
325 |
+
background: none;
|
326 |
+
border: 0;
|
327 |
+
color: inherit;
|
328 |
+
cursor: pointer;
|
329 |
+
font-size: 12px;
|
330 |
+
font-weight: bold;
|
331 |
+
padding: 10px 20px;
|
332 |
+
box-sizing: border-box;
|
333 |
+
position: relative;
|
334 |
+
text-align: left;
|
335 |
+
width: 100%;
|
336 |
+
}
|
337 |
+
|
338 |
+
.accordion-header:before {
|
339 |
+
background-color: #000;
|
340 |
+
border-radius: 100%;
|
341 |
+
box-sizing: border-box;
|
342 |
+
color: #fff;
|
343 |
+
content: '\f132';
|
344 |
+
font-family: 'dashicons';
|
345 |
+
font-size: 10px;
|
346 |
+
line-height: 17px;
|
347 |
+
font-weight: 400;
|
348 |
+
height: 14px;
|
349 |
+
left: 0;
|
350 |
+
padding: 0;
|
351 |
+
position: absolute;
|
352 |
+
top: 12px;
|
353 |
+
width: 15px;
|
354 |
+
text-align: center;
|
355 |
+
padding-right: 1px;
|
356 |
+
}
|
357 |
+
|
358 |
+
.accordion-header:after {
|
359 |
+
content: '';
|
360 |
+
border-bottom: 1px solid #ddd;
|
361 |
+
position: absolute;
|
362 |
+
right: 0;
|
363 |
+
width: 80%;
|
364 |
+
top: 50%;
|
365 |
+
transform: translateY(-50%);
|
366 |
+
}
|
367 |
+
|
368 |
+
.accordion-header.is-active:before {
|
369 |
+
content: '\f460';
|
370 |
+
line-height: 15px;
|
371 |
+
}
|
372 |
+
|
373 |
+
.accordion-header:focus {
|
374 |
+
outline: 1px solid #5b9dd9;
|
375 |
+
}
|
376 |
+
|
377 |
+
.accordion-header:hover {
|
378 |
+
background: none;
|
379 |
+
}
|
380 |
+
|
381 |
+
.tribe-tickets-editor-history::after {
|
382 |
+
width: calc(100% - 80px);
|
383 |
+
}
|
384 |
+
|
385 |
+
.tribe_attendee_meta::after {
|
386 |
+
width: calc(100% - 170px);
|
387 |
+
}
|
388 |
+
|
389 |
+
.tribe_advanced_meta::after {
|
390 |
+
width: calc(100% - 105px);
|
391 |
+
}
|
392 |
+
|
393 |
+
.accordion-label:focus {
|
394 |
+
outline: none;
|
395 |
+
}
|
396 |
+
|
397 |
+
.accordion-content {
|
398 |
+
display: none;
|
399 |
+
}
|
400 |
+
|
401 |
+
.ticket_panel .accordion-content {
|
402 |
+
margin: 1em 0 2em;
|
403 |
+
}
|
404 |
+
|
405 |
+
.accordion-content.is-active {
|
406 |
+
display: block;
|
407 |
+
}
|
408 |
+
|
409 |
+
.tribe-common-c-loader.tribe-tickets-loader__tickets-block,
|
410 |
+
.tribe-common-c-loader.tribe-tickets-loader__modal {
|
411 |
+
align-items: center;
|
412 |
+
background: var(--tec-color-background-transparent);
|
413 |
+
display: flex;
|
414 |
+
height: 100%;
|
415 |
+
justify-content: center;
|
416 |
+
left: 0;
|
417 |
+
padding: 0;
|
418 |
+
position: absolute;
|
419 |
+
top: 0;
|
420 |
+
width: 100%;
|
421 |
+
z-index: var(--tec-z-index-spinner-container);
|
422 |
+
}
|
423 |
+
|
424 |
+
.tribe-common-c-loader.tribe-tickets-loader__modal {
|
425 |
+
height: 100vh;
|
426 |
+
position: fixed;
|
427 |
+
width: 100vw;
|
428 |
+
}
|
429 |
+
|
430 |
+
.event-tickets .tribe-common-c-loader {
|
431 |
+
align-items: center;
|
432 |
+
background: var(--tec-color-background-transparent);
|
433 |
+
display: flex;
|
434 |
+
height: 100%;
|
435 |
+
justify-content: center;
|
436 |
+
left: 0;
|
437 |
+
padding: 0;
|
438 |
+
position: absolute;
|
439 |
+
top: 0;
|
440 |
+
width: 100%;
|
441 |
+
z-index: var(--tec-z-index-spinner-container);
|
442 |
+
}
|
443 |
+
|
444 |
+
.tribe-common .tribe-tickets__notice {
|
445 |
+
padding: var(--tec-spacer-3);
|
446 |
+
background-color: var(--tec-color-background-secondary);
|
447 |
+
border-radius: var(--tec-border-radius-default);
|
448 |
+
margin: var(--tec-spacer-4) 0;
|
449 |
+
}
|
450 |
+
|
451 |
+
.tribe-common .tribe-tickets__notice > *:last-child {
|
452 |
+
padding-bottom: 0;
|
453 |
+
margin-bottom: 0;
|
454 |
+
}
|
455 |
+
|
456 |
+
.tribe-common .tribe-tickets-notice__title {
|
457 |
+
margin: 0;
|
458 |
+
position: relative;
|
459 |
+
}
|
460 |
+
|
461 |
+
.tribe-common .tribe-tickets-notice__title:empty {
|
462 |
+
display: none;
|
463 |
+
}
|
464 |
+
|
465 |
+
/*
|
466 |
+
Error Notices
|
467 |
+
*/
|
468 |
+
|
469 |
+
.tribe-common .tribe-tickets__notice--error {
|
470 |
+
background-color: var(--tec-color-background-error);
|
471 |
+
display: none;
|
472 |
+
padding-left: 50px;
|
473 |
+
}
|
474 |
+
|
475 |
+
.tribe-common .tribe-tickets__notice--error .tribe-tickets-notice__title {
|
476 |
+
position: relative;
|
477 |
+
}
|
478 |
+
|
479 |
+
.tribe-common .tribe-tickets__notice--error .tribe-tickets-notice__title:before {
|
480 |
+
background-image: url( "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cg fill='none' fill-rule='evenodd' transform='translate(1 1)'%3E%3Ccircle cx='8' cy='8' r='7.467' stroke='%23141827' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5'/%3E%3Ccircle cx='8' cy='11.733' r='1.067' fill='%23141827' fill-rule='nonzero'/%3E%3Cpath stroke='%23141827' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M8 3.733v4.8' fill='%23141827'/%3E%3C/g%3E%3C/svg%3E" );
|
481 |
+
background-size: contain;
|
482 |
+
content: '';
|
483 |
+
height: var(--tec-spacer-3);
|
484 |
+
left: calc(var(--tec-spacer-7)*-1);
|
485 |
+
position: absolute;
|
486 |
+
top: 2px;
|
487 |
+
width: var(--tec-spacer-3);
|
488 |
+
}
|
489 |
+
|
490 |
+
/*
|
491 |
+
"Barred" Notices (visible side borders)
|
492 |
+
*/
|
493 |
+
|
494 |
+
.tribe-common .tribe-tickets__notice--barred {
|
495 |
+
background-color: var(--tec-color-background);
|
496 |
+
border: var(--tec-spacer-0) solid var(--tec-color-border-secondary);
|
497 |
+
border-bottom: 0;
|
498 |
+
border-radius: 0;
|
499 |
+
border-top: 0;
|
500 |
+
padding: 0 var(--tec-spacer-2);
|
501 |
+
}
|
502 |
+
|
503 |
+
.tribe-common .tribe-tickets__notice--barred-left {
|
504 |
+
border-right: 0;
|
505 |
+
padding: 0 0 0 var(--tec-spacer-2);
|
506 |
+
}
|
507 |
+
|
508 |
+
.tribe-common .tribe-tickets__notice--barred-right {
|
509 |
+
border-left: 0;
|
510 |
+
padding: 0 var(--tec-spacer-2) 0 0;
|
511 |
+
}
|
512 |
+
|
513 |
+
/* -------------------------------------------------------------------------
|
514 |
+
* SVG Icons
|
515 |
+
* ------------------------------------------------------------------------- */
|
516 |
+
|
517 |
+
.event-tickets .tribe-tickets-svgicon {
|
518 |
+
background-repeat: no-repeat;
|
519 |
+
background-size: contain;
|
520 |
+
}
|
521 |
+
|
522 |
+
/* -----------------------------------------------------------------------------
|
523 |
+
*
|
524 |
+
* Tooltip
|
525 |
+
*
|
526 |
+
* ----------------------------------------------------------------------------- */
|
527 |
+
|
528 |
+
/* Defining our tooltipster theme. */
|
529 |
+
|
530 |
+
.tooltipster-base.tribe-tickets-tooltip-theme {
|
531 |
+
background-color: var(--tec-color-background);
|
532 |
+
border: 1px solid var(--tec-color-border-default);
|
533 |
+
border-radius: var(--tec-border-radius-default);
|
534 |
+
box-shadow: var(--tec-box-shadow-tooltip);
|
535 |
+
height: auto !important;
|
536 |
+
padding: var(--tec-spacer-5);
|
537 |
+
max-width: 254px;
|
538 |
+
}
|
539 |
+
|
540 |
+
.tooltipster-base.tribe-tickets-tooltip-theme .tooltipster-box {
|
541 |
+
background-color: transparent;
|
542 |
+
border: 0;
|
543 |
+
border-radius: 0;
|
544 |
+
box-shadow: none;
|
545 |
+
margin: 0;
|
546 |
+
}
|
547 |
+
|
548 |
+
.tooltipster-base.tribe-tickets-tooltip-theme .tooltipster-box .tooltipster-content {
|
549 |
+
color: var(--tec-color-text-primary);
|
550 |
+
overflow: inherit;
|
551 |
+
padding: 0;
|
552 |
+
word-break: break-word;
|
553 |
+
}
|
554 |
+
|
555 |
+
.tooltipster-base.tribe-tickets-tooltip-theme .tooltipster-arrow {
|
556 |
+
display: none;
|
557 |
+
}
|
558 |
+
|
559 |
+
/* -----------------------------------------------------------------------------
|
560 |
+
*
|
561 |
+
* Button: Small
|
562 |
+
*
|
563 |
+
* Example:
|
564 |
+
* <button class="tribe-common-c-btn tribe-common-c-btn--small">...</button>
|
565 |
+
* <a href="#" class="tribe-common-c-btn tribe-common-c-btn--small">...</a>
|
566 |
+
*
|
567 |
+
* ----------------------------------------------------------------------------- */
|
568 |
+
|
569 |
+
.tribe-common button.tribe-common-c-btn--small, .tribe-common input[type="button"].tribe-common-c-btn--small, .tribe-common input[type="submit"].tribe-common-c-btn--small, .tribe-common a.tribe-common-c-btn--small {
|
570 |
+
background-color: var(--tec-color-accent-primary);
|
571 |
+
padding: 11px 14px;
|
572 |
+
width: auto;
|
573 |
+
}
|
574 |
+
|
575 |
+
/* -----------------------------------------------------------------------------
|
576 |
+
*
|
577 |
+
* Button: Link
|
578 |
+
*
|
579 |
+
* Example:
|
580 |
+
* <button class="tribe-common-c-btn-link">...</button>
|
581 |
+
* <a href="#" class="tribe-common-c-btn-link">...</a>
|
582 |
+
*
|
583 |
+
* ----------------------------------------------------------------------------- */
|
584 |
+
|
585 |
+
.tribe-common button.tribe-common-c-btn-link, .tribe-common input[type="button"].tribe-common-c-btn-link, .tribe-common input[type="submit"].tribe-common-c-btn-link, .tribe-common a.tribe-common-c-btn-link {
|
586 |
+
color: var(--tec-color-text-primary);
|
587 |
+
font-family: var(--tec-font-family-sans-serif);
|
588 |
+
font-size: var(--tec-font-size-2);
|
589 |
+
line-height: var(--tec-line-height-3);
|
590 |
+
font-weight: var(--tec-font-weight-regular);
|
591 |
+
border: 0;
|
592 |
+
cursor: pointer;
|
593 |
+
display: inline-block;
|
594 |
+
height: auto;
|
595 |
+
padding: 0;
|
596 |
+
text-decoration: none;
|
597 |
+
width: auto;
|
598 |
+
background-color: transparent;
|
599 |
+
text-align: center;
|
600 |
+
text-decoration: underline;
|
601 |
+
transition: var(--tec-transition-color);
|
602 |
+
}
|
603 |
+
|
604 |
+
.tribe-common button.tribe-common-c-btn-link:hover,
|
605 |
+
.tribe-common button.tribe-common-c-btn-link:focus,
|
606 |
+
.tribe-common input[type="button"].tribe-common-c-btn-link:hover,
|
607 |
+
.tribe-common input[type="button"].tribe-common-c-btn-link:focus,
|
608 |
+
.tribe-common input[type="submit"].tribe-common-c-btn-link:hover,
|
609 |
+
.tribe-common input[type="submit"].tribe-common-c-btn-link:focus,
|
610 |
+
.tribe-common a.tribe-common-c-btn-link:hover,
|
611 |
+
.tribe-common a.tribe-common-c-btn-link:focus {
|
612 |
+
background-color: transparent;
|
613 |
+
}
|
614 |
+
|
615 |
+
.tribe-common button.tribe-common-c-btn-link, .tribe-common input[type="button"].tribe-common-c-btn-link, .tribe-common input[type="submit"].tribe-common-c-btn-link, .tribe-common a.tribe-common-c-btn-link {
|
616 |
+
|
617 |
+
background-color: transparent;
|
618 |
+
color: var(--tec-color-accent-primary);
|
619 |
+
padding: 11px 20px;
|
620 |
+
width: 100%;
|
621 |
+
}
|
622 |
+
|
623 |
+
.tribe-common button.tribe-common-c-btn-link:focus,
|
624 |
+
.tribe-common button.tribe-common-c-btn-link:hover,
|
625 |
+
.tribe-common input[type="button"].tribe-common-c-btn-link:focus,
|
626 |
+
.tribe-common input[type="button"].tribe-common-c-btn-link:hover,
|
627 |
+
.tribe-common input[type="submit"].tribe-common-c-btn-link:focus,
|
628 |
+
.tribe-common input[type="submit"].tribe-common-c-btn-link:hover,
|
629 |
+
.tribe-common a.tribe-common-c-btn-link:focus,
|
630 |
+
.tribe-common a.tribe-common-c-btn-link:hover {
|
631 |
+
color: var(--tec-color-accent-primary-hover);
|
632 |
+
}
|
633 |
+
|
634 |
+
.tribe-common button.tribe-common-c-btn-link:active, .tribe-common input[type="button"].tribe-common-c-btn-link:active, .tribe-common input[type="submit"].tribe-common-c-btn-link:active, .tribe-common a.tribe-common-c-btn-link:active {
|
635 |
+
color: var(--tec-color-accent-primary-active);
|
636 |
+
}
|
637 |
+
|
638 |
+
.tribe-common button.tribe-common-c-btn-link:disabled, .tribe-common input[type="button"].tribe-common-c-btn-link:disabled, .tribe-common input[type="submit"].tribe-common-c-btn-link:disabled, .tribe-common a.tribe-common-c-btn-link:disabled {
|
639 |
+
color: var(--tec-color-accent-primary-background);
|
640 |
+
}
|
641 |
+
|
642 |
.event-tickets {
|
643 |
|
644 |
+
/* From: base/full/typography/_body.pcss */
|
645 |
|
646 |
/* From: base/full/typography/_headings.pcss */
|
647 |
|
720 |
|
721 |
/* From: base/skeleton/forms/_text.pcss */
|
722 |
|
723 |
+
/* From: base/skeleton/grid/_rows.pcss */
|
724 |
|
725 |
/* -------------------------------------------------------------------------
|
726 |
* Theme Overrides - Twenty Twenty
|
730 |
background-color: transparent;
|
731 |
}
|
732 |
|
733 |
+
@media (min-width: 768px) {
|
734 |
+
|
735 |
+
.tribe-common-c-loader.tribe-tickets-loader__tickets-block,
|
736 |
+
.tribe-common-c-loader.tribe-tickets-loader__modal {
|
737 |
+
padding: 0
|
738 |
+
}
|
739 |
+
|
740 |
+
.event-tickets .tribe-common-c-loader {
|
741 |
+
padding: 0
|
742 |
+
}
|
743 |
+
|
744 |
+
.tribe-common button.tribe-common-c-btn-link, .tribe-common input[type="button"].tribe-common-c-btn-link, .tribe-common input[type="submit"].tribe-common-c-btn-link, .tribe-common a.tribe-common-c-btn-link {
|
745 |
+
background-color: transparent;
|
746 |
+
width: auto
|
747 |
+
}
|
748 |
|
749 |
.event-tickets .tribe-common-form-control-text__input {
|
750 |
color: var(--tec-color-text-primary);
|
837 |
}
|
838 |
|
839 |
.event-tickets .tribe-common-form-control-text__input {
|
840 |
+
padding: var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-8)
|
841 |
}
|
842 |
|
843 |
.event-tickets .tribe-common-g-row--gutters {
|
844 |
+
margin-left: var(--tec-grid-gutter-half-negative);
|
845 |
+
margin-right: var(--tec-grid-gutter-half-negative)
|
846 |
}
|
847 |
|
848 |
.event-tickets .tribe-common-g-row--gutters > .tribe-common-g-col {
|
849 |
+
padding-left: var(--tec-grid-gutter-half);
|
850 |
+
padding-right: var(--tec-grid-gutter-half)
|
851 |
}
|
852 |
}
|
src/resources/css/common-responsive.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.tribe-theme-twentytwenty .event-tickets{background-color:transparent}@media(
|
1 |
+
.accordion-header{background:none;border:0;color:inherit;cursor:pointer;font-size:12px;font-weight:700;padding:10px 20px;box-sizing:border-box;position:relative;text-align:left;width:100%}.accordion-header:before{background-color:#000;border-radius:100%;box-sizing:border-box;color:#fff;content:"\f132";font-family:dashicons;font-size:10px;line-height:17px;font-weight:400;height:14px;left:0;padding:0;position:absolute;top:12px;width:15px;text-align:center;padding-right:1px}.accordion-header:after{content:"";border-bottom:1px solid #ddd;position:absolute;right:0;width:80%;top:50%;transform:translateY(-50%)}.accordion-header.is-active:before{content:"\f460";line-height:15px}.accordion-header:focus{outline:1px solid #5b9dd9}.accordion-header:hover{background:none}.tribe-tickets-editor-history:after{width:calc(100% - 80px)}.tribe_attendee_meta:after{width:calc(100% - 170px)}.tribe_advanced_meta:after{width:calc(100% - 105px)}.accordion-label:focus{outline:none}.accordion-content{display:none}.ticket_panel .accordion-content{margin:1em 0 2em}.accordion-content.is-active{display:block}.tribe-common-c-loader.tribe-tickets-loader__modal,.tribe-common-c-loader.tribe-tickets-loader__tickets-block{align-items:center;background:var(--tec-color-background-transparent);display:flex;height:100%;justify-content:center;left:0;padding:0;position:absolute;top:0;width:100%;z-index:var(--tec-z-index-spinner-container)}.tribe-common-c-loader.tribe-tickets-loader__modal{height:100vh;position:fixed;width:100vw}.event-tickets .tribe-common-c-loader{align-items:center;background:var(--tec-color-background-transparent);display:flex;height:100%;justify-content:center;left:0;padding:0;position:absolute;top:0;width:100%;z-index:var(--tec-z-index-spinner-container)}.tribe-common .tribe-tickets__notice{padding:var(--tec-spacer-3);background-color:var(--tec-color-background-secondary);border-radius:var(--tec-border-radius-default);margin:var(--tec-spacer-4) 0}.tribe-common .tribe-tickets__notice>:last-child{padding-bottom:0;margin-bottom:0}.tribe-common .tribe-tickets-notice__title{margin:0;position:relative}.tribe-common .tribe-tickets-notice__title:empty{display:none}.tribe-common .tribe-tickets__notice--error{background-color:var(--tec-color-background-error);display:none;padding-left:50px}.tribe-common .tribe-tickets__notice--error .tribe-tickets-notice__title{position:relative}.tribe-common .tribe-tickets__notice--error .tribe-tickets-notice__title:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cg fill='none' fill-rule='evenodd' transform='translate(1 1)'%3E%3Ccircle cx='8' cy='8' r='7.467' stroke='%23141827' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5'/%3E%3Ccircle cx='8' cy='11.733' r='1.067' fill='%23141827' fill-rule='nonzero'/%3E%3Cpath stroke='%23141827' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M8 3.733v4.8' fill='%23141827'/%3E%3C/g%3E%3C/svg%3E");background-size:contain;content:"";height:var(--tec-spacer-3);left:calc(var(--tec-spacer-7)*-1);position:absolute;top:2px;width:var(--tec-spacer-3)}.tribe-common .tribe-tickets__notice--barred{background-color:var(--tec-color-background);border:var(--tec-spacer-0) solid var(--tec-color-border-secondary);border-bottom:0;border-radius:0;border-top:0;padding:0 var(--tec-spacer-2)}.tribe-common .tribe-tickets__notice--barred-left{border-right:0;padding:0 0 0 var(--tec-spacer-2)}.tribe-common .tribe-tickets__notice--barred-right{border-left:0;padding:0 var(--tec-spacer-2) 0 0}.event-tickets .tribe-tickets-svgicon{background-repeat:no-repeat;background-size:contain}.tooltipster-base.tribe-tickets-tooltip-theme{background-color:var(--tec-color-background);border:1px solid var(--tec-color-border-default);border-radius:var(--tec-border-radius-default);box-shadow:var(--tec-box-shadow-tooltip);height:auto!important;padding:var(--tec-spacer-5);max-width:254px}.tooltipster-base.tribe-tickets-tooltip-theme .tooltipster-box{background-color:transparent;border:0;border-radius:0;box-shadow:none;margin:0}.tooltipster-base.tribe-tickets-tooltip-theme .tooltipster-box .tooltipster-content{color:var(--tec-color-text-primary);overflow:inherit;padding:0;word-break:break-word}.tooltipster-base.tribe-tickets-tooltip-theme .tooltipster-arrow{display:none}.tribe-common a.tribe-common-c-btn--small,.tribe-common button.tribe-common-c-btn--small,.tribe-common input[type=button].tribe-common-c-btn--small,.tribe-common input[type=submit].tribe-common-c-btn--small{background-color:var(--tec-color-accent-primary);padding:11px 14px;width:auto}.tribe-common a.tribe-common-c-btn-link,.tribe-common button.tribe-common-c-btn-link,.tribe-common input[type=button].tribe-common-c-btn-link,.tribe-common input[type=submit].tribe-common-c-btn-link{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;text-align:center;text-decoration:underline;transition:var(--tec-transition-color)}.tribe-common a.tribe-common-c-btn-link:focus,.tribe-common a.tribe-common-c-btn-link:hover,.tribe-common button.tribe-common-c-btn-link:focus,.tribe-common button.tribe-common-c-btn-link:hover,.tribe-common input[type=button].tribe-common-c-btn-link:focus,.tribe-common input[type=button].tribe-common-c-btn-link:hover,.tribe-common input[type=submit].tribe-common-c-btn-link:focus,.tribe-common input[type=submit].tribe-common-c-btn-link:hover{background-color:transparent}.tribe-common a.tribe-common-c-btn-link,.tribe-common button.tribe-common-c-btn-link,.tribe-common input[type=button].tribe-common-c-btn-link,.tribe-common input[type=submit].tribe-common-c-btn-link{background-color:transparent;color:var(--tec-color-accent-primary);padding:11px 20px;width:100%}.tribe-common a.tribe-common-c-btn-link:focus,.tribe-common a.tribe-common-c-btn-link:hover,.tribe-common button.tribe-common-c-btn-link:focus,.tribe-common button.tribe-common-c-btn-link:hover,.tribe-common input[type=button].tribe-common-c-btn-link:focus,.tribe-common input[type=button].tribe-common-c-btn-link:hover,.tribe-common input[type=submit].tribe-common-c-btn-link:focus,.tribe-common input[type=submit].tribe-common-c-btn-link:hover{color:var(--tec-color-accent-primary-hover)}.tribe-common a.tribe-common-c-btn-link:active,.tribe-common button.tribe-common-c-btn-link:active,.tribe-common input[type=button].tribe-common-c-btn-link:active,.tribe-common input[type=submit].tribe-common-c-btn-link:active{color:var(--tec-color-accent-primary-active)}.tribe-common a.tribe-common-c-btn-link:disabled,.tribe-common button.tribe-common-c-btn-link:disabled,.tribe-common input[type=button].tribe-common-c-btn-link:disabled,.tribe-common input[type=submit].tribe-common-c-btn-link:disabled{color:var(--tec-color-accent-primary-background)}.tribe-theme-twentytwenty .event-tickets{background-color:transparent}@media (min-width:768px){.event-tickets .tribe-common-c-loader,.tribe-common-c-loader.tribe-tickets-loader__modal,.tribe-common-c-loader.tribe-tickets-loader__tickets-block{padding:0}.tribe-common a.tribe-common-c-btn-link,.tribe-common button.tribe-common-c-btn-link,.tribe-common input[type=button].tribe-common-c-btn-link,.tribe-common input[type=submit].tribe-common-c-btn-link{background-color:transparent;width:auto}.event-tickets .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);border:0}.event-tickets .tribe-common-b1{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.event-tickets .tribe-common-b2{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.event-tickets .tribe-common-b3{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.event-tickets .tribe-common-h1{font-size:var(--tec-font-size-10);line-height:var(--tec-line-height-0)}.event-tickets .tribe-common-h2{font-size:var(--tec-font-size-9);line-height:var(--tec-line-height-0)}.event-tickets .tribe-common-h3{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.event-tickets .tribe-common-h4{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.event-tickets .tribe-common-b1--min-medium,.event-tickets .tribe-common-h6{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.event-tickets .tribe-common-b2--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.event-tickets .tribe-common-b3--min-medium{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.event-tickets .tribe-common-h3--min-medium{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.event-tickets .tribe-common-h4--min-medium{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.event-tickets .tribe-common-h5--min-medium{font-size:var(--tec-font-size-4);line-height:var(--tec-line-height-2)}.event-tickets .tribe-common-h6--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.event-tickets .tribe-common-h7--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.event-tickets .tribe-common-form-control-text__input{padding:var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-4) var(--tec-spacer-8)}.event-tickets .tribe-common-g-row--gutters{margin-left:var(--tec-grid-gutter-half-negative);margin-right:var(--tec-grid-gutter-half-negative)}.event-tickets .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:var(--tec-grid-gutter-half);padding-right:var(--tec-grid-gutter-half)}}
|
src/resources/css/details.css
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
-
* @see:
|
9 |
*/
|
10 |
|
11 |
.tribe__details__poly .tribe__details__summary:before {
|
@@ -17,7 +17,7 @@
|
|
17 |
.tribe__details__poly.tribe__details--open .tribe__details__content {
|
18 |
display: block;
|
19 |
}
|
20 |
-
@media(
|
21 |
.tribe__details__poly .tribe__details__poly.tribe__details--mobile .tribe__details__summary {
|
22 |
display: none;
|
23 |
}
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
+
* @see: https://the-events-calendar.github.io/products-engineering/docs/code-standards/css/
|
9 |
*/
|
10 |
|
11 |
.tribe__details__poly .tribe__details__summary:before {
|
17 |
.tribe__details__poly.tribe__details--open .tribe__details__content {
|
18 |
display: block;
|
19 |
}
|
20 |
+
@media (min-width: 768px) {
|
21 |
.tribe__details__poly .tribe__details__poly.tribe__details--mobile .tribe__details__summary {
|
22 |
display: none;
|
23 |
}
|
src/resources/css/details.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.tribe__details__poly .tribe__details__summary:before{content:"\25bc"}.tribe__details__poly .tribe__details__content{display:none}.tribe__details__poly.tribe__details--open .tribe__details__content{display:block}@media(
|
1 |
+
.tribe__details__poly .tribe__details__summary:before{content:"\25bc"}.tribe__details__poly .tribe__details__content{display:none}.tribe__details__poly.tribe__details--open .tribe__details__content{display:block}@media (min-width:768px){.tribe__details__poly .tribe__details__poly.tribe__details--mobile .tribe__details__summary{display:none}.tribe__details__poly .tribe__details__poly.tribe__details--mobile .tribe__details__content{display:block}}
|
src/resources/css/freemius.css
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
-
* @see:
|
9 |
*/
|
10 |
|
11 |
.events-cal #fs_connect, .toplevel_page_tribe-common #fs_connect, .toplevel_page_tribe-help #fs_connect, .toplevel_page_tribe-app-shop #fs_connect {
|
@@ -77,7 +77,7 @@
|
|
77 |
visibility: hidden;
|
78 |
}
|
79 |
|
80 |
-
.events-cal #fs_connect .fs-visual .fs-site-icon
|
81 |
background-image: url( ../images/event-tickets.svg );
|
82 |
background-position: center center;
|
83 |
background-repeat: no-repeat;
|
@@ -93,7 +93,7 @@
|
|
93 |
visibility: hidden;
|
94 |
}
|
95 |
|
96 |
-
.events-cal #fs_connect .fs-visual .fs-plugin-icon
|
97 |
background-image: url( ../icons/stethoscope.svg );
|
98 |
background-position: center center;
|
99 |
background-repeat: no-repeat;
|
@@ -226,7 +226,7 @@
|
|
226 |
background-size: 65%;
|
227 |
}
|
228 |
|
229 |
-
.events-cal #fs_connect .fs-permissions.fs-open ul .dashicons
|
230 |
content: '';
|
231 |
}
|
232 |
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
+
* @see: https://the-events-calendar.github.io/products-engineering/docs/code-standards/css/
|
9 |
*/
|
10 |
|
11 |
.events-cal #fs_connect, .toplevel_page_tribe-common #fs_connect, .toplevel_page_tribe-help #fs_connect, .toplevel_page_tribe-app-shop #fs_connect {
|
77 |
visibility: hidden;
|
78 |
}
|
79 |
|
80 |
+
.events-cal #fs_connect .fs-visual .fs-site-icon:before, .toplevel_page_tribe-common #fs_connect .fs-visual .fs-site-icon:before, .toplevel_page_tribe-help #fs_connect .fs-visual .fs-site-icon:before, .toplevel_page_tribe-app-shop #fs_connect .fs-visual .fs-site-icon:before {
|
81 |
background-image: url( ../images/event-tickets.svg );
|
82 |
background-position: center center;
|
83 |
background-repeat: no-repeat;
|
93 |
visibility: hidden;
|
94 |
}
|
95 |
|
96 |
+
.events-cal #fs_connect .fs-visual .fs-plugin-icon:before, .toplevel_page_tribe-common #fs_connect .fs-visual .fs-plugin-icon:before, .toplevel_page_tribe-help #fs_connect .fs-visual .fs-plugin-icon:before, .toplevel_page_tribe-app-shop #fs_connect .fs-visual .fs-plugin-icon:before {
|
97 |
background-image: url( ../icons/stethoscope.svg );
|
98 |
background-position: center center;
|
99 |
background-repeat: no-repeat;
|
226 |
background-size: 65%;
|
227 |
}
|
228 |
|
229 |
+
.events-cal #fs_connect .fs-permissions.fs-open ul .dashicons:before, .toplevel_page_tribe-common #fs_connect .fs-permissions.fs-open ul .dashicons:before, .toplevel_page_tribe-help #fs_connect .fs-permissions.fs-open ul .dashicons:before, .toplevel_page_tribe-app-shop #fs_connect .fs-permissions.fs-open ul .dashicons:before {
|
230 |
content: '';
|
231 |
}
|
232 |
|
src/resources/css/rsvp-v1.css
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
-
* @see:
|
9 |
*/
|
10 |
|
11 |
.tribe-rsvp {
|
@@ -40,7 +40,7 @@
|
|
40 |
border-width: 1px;
|
41 |
font-size: 12px;
|
42 |
margin: 0 0 5px;
|
43 |
-
padding: 0 .6em;
|
44 |
}
|
45 |
|
46 |
.tribe-rsvp-message-success {
|
@@ -119,7 +119,7 @@
|
|
119 |
}
|
120 |
|
121 |
.user-details p {
|
122 |
-
margin: 0 0 .5em;
|
123 |
}
|
124 |
|
125 |
.tribe-answer {
|
@@ -128,7 +128,7 @@
|
|
128 |
|
129 |
.tribe-answer .type-label {
|
130 |
margin-bottom: 0;
|
131 |
-
padding-right: .5em;
|
132 |
}
|
133 |
|
134 |
.tribe-answer label {
|
@@ -177,7 +177,7 @@
|
|
177 |
}
|
178 |
|
179 |
/* = Tickets & RSVP Modules Front End Styles
|
180 |
-
|
181 |
|
182 |
/* Title */
|
183 |
|
@@ -196,7 +196,7 @@
|
|
196 |
/* RSVP & Tickets Table */
|
197 |
|
198 |
.tribe-events-tickets {
|
199 |
-
background:
|
200 |
border: 0;
|
201 |
border-radius: 3px;
|
202 |
max-width: 100%;
|
@@ -234,7 +234,7 @@
|
|
234 |
order: 2;
|
235 |
}
|
236 |
|
237 |
-
.tribe-events-tickets td.quantity input[type=
|
238 |
background-color: #fff;
|
239 |
border-radius: 3px;
|
240 |
margin-bottom: 5px;
|
@@ -255,7 +255,7 @@
|
|
255 |
}
|
256 |
|
257 |
.tribe-events-tickets .tribe-link-tickets-message {
|
258 |
-
background: rgba(200, 200, 200, .8);
|
259 |
bottom: 0;
|
260 |
left: 0;
|
261 |
position: absolute;
|
@@ -273,18 +273,18 @@
|
|
273 |
}
|
274 |
|
275 |
.tribe-events-tickets .tribe-tickets-remaining {
|
276 |
-
color:
|
277 |
display: block;
|
278 |
font-size: 11px;
|
279 |
}
|
280 |
|
281 |
.tribe-events-tickets .tribe-tickets-attendees-list-optout label {
|
282 |
-
color:
|
283 |
font-size: 13px;
|
284 |
}
|
285 |
|
286 |
-
.tribe-events-tickets .tribe-tickets-attendees-list-optout input[type=
|
287 |
-
.tribe-events-tickets .tribe-tickets-attendees-list-optout input[type=
|
288 |
display: inline-block;
|
289 |
}
|
290 |
|
@@ -292,23 +292,23 @@
|
|
292 |
.tribe-events-tickets .tickets_name p,
|
293 |
.tribe-events-tickets .tickets_description,
|
294 |
.tribe-events-tickets .tickets_price {
|
295 |
-
color:
|
296 |
font-size: 15px;
|
297 |
padding: 16px 10px;
|
298 |
}
|
299 |
|
300 |
-
.tribe-events-tickets input[type=
|
301 |
-
.tribe-events-tickets input[type=
|
302 |
-
.tribe-events-tickets input[type=
|
303 |
-
.tribe-events-tickets input[type=
|
304 |
-
.tribe-events-tickets input[type=
|
305 |
-
.tribe-events-tickets input[type=
|
306 |
-
.tribe-events-tickets input[type=
|
307 |
-
.tribe-events-tickets input[type=
|
308 |
-
.tribe-events-tickets input[type=
|
309 |
-
.tribe-events-tickets input[type=
|
310 |
-
.tribe-events-tickets input[type=
|
311 |
-
.tribe-events-tickets input[type=
|
312 |
.tribe-events-tickets textarea,
|
313 |
.tribe-events-tickets select {
|
314 |
background: #fff;
|
@@ -345,7 +345,7 @@
|
|
345 |
*/
|
346 |
|
347 |
.tribe-block__rsvp {
|
348 |
-
font-family:
|
349 |
margin-bottom: 30px;
|
350 |
margin-top: 30px;
|
351 |
max-width: 580px;
|
@@ -362,7 +362,7 @@
|
|
362 |
|
363 |
.tribe-block__rsvp__icon {
|
364 |
align-items: center;
|
365 |
-
background: #
|
366 |
border-bottom: 1px dashed #b5bcc2;
|
367 |
color: #434343;
|
368 |
display: flex;
|
@@ -384,14 +384,12 @@
|
|
384 |
flex: auto;
|
385 |
}
|
386 |
|
387 |
-
.tribe-block__rsvp__details__status {}
|
388 |
-
|
389 |
.tribe-block__rsvp__details {
|
390 |
padding: 25px 20px 20px;
|
391 |
}
|
392 |
|
393 |
.tribe-block__rsvp__title {
|
394 |
-
color: #
|
395 |
font-size: 21px;
|
396 |
font-weight: bold;
|
397 |
line-height: 28px;
|
@@ -440,10 +438,10 @@
|
|
440 |
align-items: center;
|
441 |
border: 1px solid #545d66;
|
442 |
border-radius: 4px;
|
443 |
-
background: #
|
444 |
color: #545d66;
|
445 |
display: flex;
|
446 |
-
font-family:
|
447 |
font-size: 14px;
|
448 |
font-weight: bold;
|
449 |
height: 44px;
|
@@ -459,14 +457,14 @@
|
|
459 |
|
460 |
.tribe-block__rsvp__status-button:hover,
|
461 |
.tribe-block__rsvp__status-button:focus {
|
462 |
-
background: #
|
463 |
-
border: 1px solid #
|
464 |
-
color: #
|
465 |
}
|
466 |
|
467 |
.tribe-block__rsvp__status-button.tribe-active {
|
468 |
-
border: 1px solid #
|
469 |
-
color: #
|
470 |
}
|
471 |
|
472 |
.tribe-block__rsvp__status-button.tribe-inactive {
|
@@ -476,12 +474,12 @@
|
|
476 |
|
477 |
.tribe-block__rsvp__status-button.tribe-inactive:hover,
|
478 |
.tribe-block__rsvp__status-button.tribe-inactive:focus {
|
479 |
-
background: #
|
480 |
border: 1px solid #545d66;
|
481 |
color: #545d66;
|
482 |
}
|
483 |
|
484 |
-
.tribe-block__rsvp__status-button[disabled=
|
485 |
cursor: default;
|
486 |
}
|
487 |
|
@@ -533,14 +531,14 @@
|
|
533 |
display: flex;
|
534 |
}
|
535 |
|
536 |
-
.tribe-block__rsvp__number-input-inner input[type=
|
537 |
-webkit-appearance: textfield;
|
538 |
-moz-appearance: textfield;
|
539 |
appearance: textfield;
|
540 |
background: transparent;
|
541 |
border: none;
|
542 |
-
color: #
|
543 |
-
font-family:
|
544 |
font-size: 30px;
|
545 |
font-weight: bold;
|
546 |
height: 40px;
|
@@ -549,8 +547,8 @@
|
|
549 |
text-align: center;
|
550 |
}
|
551 |
|
552 |
-
.tribe-block__rsvp__number-input-inner input[type=
|
553 |
-
.tribe-block__rsvp__number-input-inner input[type=
|
554 |
-webkit-appearance: none;
|
555 |
appearance: none;
|
556 |
}
|
@@ -619,12 +617,12 @@
|
|
619 |
flex: auto;
|
620 |
}
|
621 |
|
622 |
-
.tribe-right input[type=
|
623 |
-
.tribe-right input[type=
|
624 |
border-color: #e1e3e6;
|
625 |
-
color: #
|
626 |
display: block;
|
627 |
-
font-family:
|
628 |
font-size: 16px;
|
629 |
height: 40px;
|
630 |
line-height: 18px;
|
@@ -633,15 +631,15 @@
|
|
633 |
width: 100%;
|
634 |
}
|
635 |
|
636 |
-
.tribe-right input[type=
|
637 |
color: #a2aab2;
|
638 |
}
|
639 |
|
640 |
-
.tribe-right input[type=
|
641 |
color: #a2aab2;
|
642 |
}
|
643 |
|
644 |
-
.tribe-right input[type=
|
645 |
color: #a2aab2;
|
646 |
}
|
647 |
|
@@ -651,18 +649,18 @@
|
|
651 |
font-weight: normal;
|
652 |
}
|
653 |
|
654 |
-
.tribe-right label[for^=
|
655 |
align-items: flex-start;
|
656 |
display: flex;
|
657 |
margin: 0 0 15px;
|
658 |
padding-top: 7px;
|
659 |
}
|
660 |
|
661 |
-
.tribe-right label[for^=
|
662 |
-webkit-appearance: none;
|
663 |
-moz-appearance: none;
|
664 |
appearance: none;
|
665 |
-
background-color: #
|
666 |
border: 1px solid #e1e3e6;
|
667 |
border-radius: 0;
|
668 |
cursor: pointer;
|
@@ -672,15 +670,15 @@
|
|
672 |
width: 16px;
|
673 |
}
|
674 |
|
675 |
-
.tribe-right label[for^=
|
676 |
box-shadow: 0 0 0 1px #e1e3e6;
|
677 |
outline: 2px solid transparent;
|
678 |
outline-offset: -2px;
|
679 |
}
|
680 |
|
681 |
-
.tribe-right label[for^=
|
682 |
color: #009fd4;
|
683 |
-
content:
|
684 |
display: inline-block;
|
685 |
float: left;
|
686 |
font: normal 21px/1 dashicons;
|
@@ -691,7 +689,7 @@
|
|
691 |
}
|
692 |
|
693 |
.tribe-tickets-meta-option-label {
|
694 |
-
color: #
|
695 |
font-size: 14px;
|
696 |
line-height: 18px;
|
697 |
font-weight: normal;
|
@@ -699,7 +697,7 @@
|
|
699 |
|
700 |
.tribe-block__rsvp__message__error,
|
701 |
.tribe-block__rsvp__message__success {
|
702 |
-
color: #
|
703 |
font-size: 14px;
|
704 |
line-height: 18px;
|
705 |
padding: 20px;
|
@@ -707,7 +705,7 @@
|
|
707 |
|
708 |
.tribe-block__rsvp__message__error {
|
709 |
background: #ffebe8;
|
710 |
-
border: 1px solid #
|
711 |
display: none;
|
712 |
margin-bottom: 20px;
|
713 |
}
|
@@ -720,8 +718,8 @@
|
|
720 |
|
721 |
.tribe-block__rsvp__submit-button {
|
722 |
background: #009fd4;
|
723 |
-
color: #
|
724 |
-
font-family:
|
725 |
font-size: 15px;
|
726 |
font-weight: bold;
|
727 |
line-height: 18px;
|
@@ -752,7 +750,7 @@
|
|
752 |
|
753 |
.tribe-common-c-loader.tribe-block__rsvp__loading {
|
754 |
align-items: center;
|
755 |
-
background: rgba(
|
756 |
height: 100%;
|
757 |
justify-content: center;
|
758 |
left: 0;
|
@@ -782,16 +780,13 @@
|
|
782 |
}
|
783 |
}
|
784 |
|
785 |
-
@media (min-width: 768px
|
786 |
|
787 |
.tribe-events-tickets td {
|
788 |
width: auto
|
789 |
}
|
790 |
-
}
|
791 |
|
792 |
-
|
793 |
-
|
794 |
-
.tribe-events-tickets td.quantity input[type="number"], .tribe-events-tickets td.woocommerce input[type="number"] {
|
795 |
width: 4.375em
|
796 |
}
|
797 |
|
@@ -803,18 +798,18 @@
|
|
803 |
margin: 10px
|
804 |
}
|
805 |
|
806 |
-
.tribe-events-tickets input[type=
|
807 |
-
.tribe-events-tickets input[type=
|
808 |
-
.tribe-events-tickets input[type=
|
809 |
-
.tribe-events-tickets input[type=
|
810 |
-
.tribe-events-tickets input[type=
|
811 |
-
.tribe-events-tickets input[type=
|
812 |
-
.tribe-events-tickets input[type=
|
813 |
-
.tribe-events-tickets input[type=
|
814 |
-
.tribe-events-tickets input[type=
|
815 |
-
.tribe-events-tickets input[type=
|
816 |
-
.tribe-events-tickets input[type=
|
817 |
-
.tribe-events-tickets input[type=
|
818 |
.tribe-events-tickets textarea,
|
819 |
.tribe-events-tickets select {
|
820 |
width: auto
|
@@ -827,7 +822,7 @@
|
|
827 |
.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta > td, .tribe-events-tickets-rsvp tr.tribe-tickets-meta-row > td {
|
828 |
display: table-cell
|
829 |
}
|
830 |
-
|
831 |
|
832 |
@media (min-width: 600px) {
|
833 |
|
@@ -843,7 +838,7 @@
|
|
843 |
width: 84px
|
844 |
}
|
845 |
|
846 |
-
.tribe-block__rsvp__number-input-inner input[type=
|
847 |
font-size: 36px;
|
848 |
height: 48px
|
849 |
}
|
5 |
* src/resources/postcss/ file. For more information, check out our engineering
|
6 |
* docs on how we handle CSS in our engineering docs.
|
7 |
*
|
8 |
+
* @see: https://the-events-calendar.github.io/products-engineering/docs/code-standards/css/
|
9 |
*/
|
10 |
|
11 |
.tribe-rsvp {
|
40 |
border-width: 1px;
|
41 |
font-size: 12px;
|
42 |
margin: 0 0 5px;
|
43 |
+
padding: 0 0.6em;
|
44 |
}
|
45 |
|
46 |
.tribe-rsvp-message-success {
|
119 |
}
|
120 |
|
121 |
.user-details p {
|
122 |
+
margin: 0 0 0.5em;
|
123 |
}
|
124 |
|
125 |
.tribe-answer {
|
128 |
|
129 |
.tribe-answer .type-label {
|
130 |
margin-bottom: 0;
|
131 |
+
padding-right: 0.5em;
|
132 |
}
|
133 |
|
134 |
.tribe-answer label {
|
177 |
}
|
178 |
|
179 |
/* = Tickets & RSVP Modules Front End Styles
|
180 |
+
============================================= */
|
181 |
|
182 |
/* Title */
|
183 |
|
196 |
/* RSVP & Tickets Table */
|
197 |
|
198 |
.tribe-events-tickets {
|
199 |
+
background: var(--tec-color-background-secondary);
|
200 |
border: 0;
|
201 |
border-radius: 3px;
|
202 |
max-width: 100%;
|
234 |
order: 2;
|
235 |
}
|
236 |
|
237 |
+
.tribe-events-tickets td.quantity input[type='number'], .tribe-events-tickets td.woocommerce input[type='number'] {
|
238 |
background-color: #fff;
|
239 |
border-radius: 3px;
|
240 |
margin-bottom: 5px;
|
255 |
}
|
256 |
|
257 |
.tribe-events-tickets .tribe-link-tickets-message {
|
258 |
+
background: rgba(200, 200, 200, 0.8);
|
259 |
bottom: 0;
|
260 |
left: 0;
|
261 |
position: absolute;
|
273 |
}
|
274 |
|
275 |
.tribe-events-tickets .tribe-tickets-remaining {
|
276 |
+
color: var(--tec-color-text-secondary);
|
277 |
display: block;
|
278 |
font-size: 11px;
|
279 |
}
|
280 |
|
281 |
.tribe-events-tickets .tribe-tickets-attendees-list-optout label {
|
282 |
+
color: var(--tec-color-text-secondary);
|
283 |
font-size: 13px;
|
284 |
}
|
285 |
|
286 |
+
.tribe-events-tickets .tribe-tickets-attendees-list-optout input[type='radio'] + label,
|
287 |
+
.tribe-events-tickets .tribe-tickets-attendees-list-optout input[type='checkbox'] + label {
|
288 |
display: inline-block;
|
289 |
}
|
290 |
|
292 |
.tribe-events-tickets .tickets_name p,
|
293 |
.tribe-events-tickets .tickets_description,
|
294 |
.tribe-events-tickets .tickets_price {
|
295 |
+
color: var(--tec-color-text-secondary);
|
296 |
font-size: 15px;
|
297 |
padding: 16px 10px;
|
298 |
}
|
299 |
|
300 |
+
.tribe-events-tickets input[type='date'],
|
301 |
+
.tribe-events-tickets input[type='time'],
|
302 |
+
.tribe-events-tickets input[type='datetime-local'],
|
303 |
+
.tribe-events-tickets input[type='week'],
|
304 |
+
.tribe-events-tickets input[type='month'],
|
305 |
+
.tribe-events-tickets input[type='text'],
|
306 |
+
.tribe-events-tickets input[type='email'],
|
307 |
+
.tribe-events-tickets input[type='url'],
|
308 |
+
.tribe-events-tickets input[type='password'],
|
309 |
+
.tribe-events-tickets input[type='search'],
|
310 |
+
.tribe-events-tickets input[type='tel'],
|
311 |
+
.tribe-events-tickets input[type='number'],
|
312 |
.tribe-events-tickets textarea,
|
313 |
.tribe-events-tickets select {
|
314 |
background: #fff;
|
345 |
*/
|
346 |
|
347 |
.tribe-block__rsvp {
|
348 |
+
font-family: var(--tec-font-family-sans-serif);
|
349 |
margin-bottom: 30px;
|
350 |
margin-top: 30px;
|
351 |
max-width: 580px;
|
362 |
|
363 |
.tribe-block__rsvp__icon {
|
364 |
align-items: center;
|
365 |
+
background: #fff;
|
366 |
border-bottom: 1px dashed #b5bcc2;
|
367 |
color: #434343;
|
368 |
display: flex;
|
384 |
flex: auto;
|
385 |
}
|
386 |
|
|
|
|
|
387 |
.tribe-block__rsvp__details {
|
388 |
padding: 25px 20px 20px;
|
389 |
}
|
390 |
|
391 |
.tribe-block__rsvp__title {
|
392 |
+
color: #000;
|
393 |
font-size: 21px;
|
394 |
font-weight: bold;
|
395 |
line-height: 28px;
|
438 |
align-items: center;
|
439 |
border: 1px solid #545d66;
|
440 |
border-radius: 4px;
|
441 |
+
background: #fff;
|
442 |
color: #545d66;
|
443 |
display: flex;
|
444 |
+
font-family: var(--tec-font-family-sans-serif);
|
445 |
font-size: 14px;
|
446 |
font-weight: bold;
|
447 |
height: 44px;
|
457 |
|
458 |
.tribe-block__rsvp__status-button:hover,
|
459 |
.tribe-block__rsvp__status-button:focus {
|
460 |
+
background: #fff;
|
461 |
+
border: 1px solid #000;
|
462 |
+
color: #000;
|
463 |
}
|
464 |
|
465 |
.tribe-block__rsvp__status-button.tribe-active {
|
466 |
+
border: 1px solid #000;
|
467 |
+
color: #000;
|
468 |
}
|
469 |
|
470 |
.tribe-block__rsvp__status-button.tribe-inactive {
|
474 |
|
475 |
.tribe-block__rsvp__status-button.tribe-inactive:hover,
|
476 |
.tribe-block__rsvp__status-button.tribe-inactive:focus {
|
477 |
+
background: #fff;
|
478 |
border: 1px solid #545d66;
|
479 |
color: #545d66;
|
480 |
}
|
481 |
|
482 |
+
.tribe-block__rsvp__status-button[disabled='disabled'] {
|
483 |
cursor: default;
|
484 |
}
|
485 |
|
531 |
display: flex;
|
532 |
}
|
533 |
|
534 |
+
.tribe-block__rsvp__number-input-inner input[type='number'] {
|
535 |
-webkit-appearance: textfield;
|
536 |
-moz-appearance: textfield;
|
537 |
appearance: textfield;
|
538 |
background: transparent;
|
539 |
border: none;
|
540 |
+
color: #000;
|
541 |
+
font-family: var(--tec-font-family-sans-serif);
|
542 |
font-size: 30px;
|
543 |
font-weight: bold;
|
544 |
height: 40px;
|
547 |
text-align: center;
|
548 |
}
|
549 |
|
550 |
+
.tribe-block__rsvp__number-input-inner input[type='number']::-webkit-inner-spin-button,
|
551 |
+
.tribe-block__rsvp__number-input-inner input[type='number']::-webkit-outer-spin-button {
|
552 |
-webkit-appearance: none;
|
553 |
appearance: none;
|
554 |
}
|
617 |
flex: auto;
|
618 |
}
|
619 |
|
620 |
+
.tribe-right input[type='text'],
|
621 |
+
.tribe-right input[type='email'] {
|
622 |
border-color: #e1e3e6;
|
623 |
+
color: #000;
|
624 |
display: block;
|
625 |
+
font-family: var(--tec-font-family-sans-serif);
|
626 |
font-size: 16px;
|
627 |
height: 40px;
|
628 |
line-height: 18px;
|
631 |
width: 100%;
|
632 |
}
|
633 |
|
634 |
+
.tribe-right input[type='text']::-moz-placeholder, .tribe-right input[type='email']::-moz-placeholder {
|
635 |
color: #a2aab2;
|
636 |
}
|
637 |
|
638 |
+
.tribe-right input[type='text']:-ms-input-placeholder, .tribe-right input[type='email']:-ms-input-placeholder {
|
639 |
color: #a2aab2;
|
640 |
}
|
641 |
|
642 |
+
.tribe-right input[type='text']::placeholder, .tribe-right input[type='email']::placeholder {
|
643 |
color: #a2aab2;
|
644 |
}
|
645 |
|
649 |
font-weight: normal;
|
650 |
}
|
651 |
|
652 |
+
.tribe-right label[for^='tribe-tickets-attendees-list-optout'] {
|
653 |
align-items: flex-start;
|
654 |
display: flex;
|
655 |
margin: 0 0 15px;
|
656 |
padding-top: 7px;
|
657 |
}
|
658 |
|
659 |
+
.tribe-right label[for^='tribe-tickets-attendees-list-optout'] input[type='checkbox'] {
|
660 |
-webkit-appearance: none;
|
661 |
-moz-appearance: none;
|
662 |
appearance: none;
|
663 |
+
background-color: #fff;
|
664 |
border: 1px solid #e1e3e6;
|
665 |
border-radius: 0;
|
666 |
cursor: pointer;
|
670 |
width: 16px;
|
671 |
}
|
672 |
|
673 |
+
.tribe-right label[for^='tribe-tickets-attendees-list-optout'] input[type='checkbox']:focus {
|
674 |
box-shadow: 0 0 0 1px #e1e3e6;
|
675 |
outline: 2px solid transparent;
|
676 |
outline-offset: -2px;
|
677 |
}
|
678 |
|
679 |
+
.tribe-right label[for^='tribe-tickets-attendees-list-optout'] input[type='checkbox']:checked:before {
|
680 |
color: #009fd4;
|
681 |
+
content: '\f147';
|
682 |
display: inline-block;
|
683 |
float: left;
|
684 |
font: normal 21px/1 dashicons;
|
689 |
}
|
690 |
|
691 |
.tribe-tickets-meta-option-label {
|
692 |
+
color: #000;
|
693 |
font-size: 14px;
|
694 |
line-height: 18px;
|
695 |
font-weight: normal;
|
697 |
|
698 |
.tribe-block__rsvp__message__error,
|
699 |
.tribe-block__rsvp__message__success {
|
700 |
+
color: #000;
|
701 |
font-size: 14px;
|
702 |
line-height: 18px;
|
703 |
padding: 20px;
|
705 |
|
706 |
.tribe-block__rsvp__message__error {
|
707 |
background: #ffebe8;
|
708 |
+
border: 1px solid #c00;
|
709 |
display: none;
|
710 |
margin-bottom: 20px;
|
711 |
}
|
718 |
|
719 |
.tribe-block__rsvp__submit-button {
|
720 |
background: #009fd4;
|
721 |
+
color: #fff;
|
722 |
+
font-family: var(--tec-font-family-sans-serif);
|
723 |
font-size: 15px;
|
724 |
font-weight: bold;
|
725 |
line-height: 18px;
|
750 |
|
751 |
.tribe-common-c-loader.tribe-block__rsvp__loading {
|
752 |
align-items: center;
|
753 |
+
background: rgba(255, 255, 255, 0.7);
|
754 |
height: 100%;
|
755 |
justify-content: center;
|
756 |
left: 0;
|
780 |
}
|
781 |
}
|
782 |
|
783 |
+
@media (min-width: 768px) {
|
784 |
|
785 |
.tribe-events-tickets td {
|
786 |
width: auto
|
787 |
}
|
|
|
788 |
|
789 |
+
.tribe-events-tickets td.quantity input[type='number'], .tribe-events-tickets td.woocommerce input[type='number'] {
|
|
|
|
|
790 |
width: 4.375em
|
791 |
}
|
792 |
|
798 |
margin: 10px
|
799 |
}
|
800 |
|
801 |
+
.tribe-events-tickets input[type='date'],
|
802 |
+
.tribe-events-tickets input[type='time'],
|
803 |
+
.tribe-events-tickets input[type='datetime-local'],
|
804 |
+
.tribe-events-tickets input[type='week'],
|
805 |
+
.tribe-events-tickets input[type='month'],
|
806 |
+
.tribe-events-tickets input[type='text'],
|
807 |
+
.tribe-events-tickets input[type='email'],
|
808 |
+
.tribe-events-tickets input[type='url'],
|
809 |
+
.tribe-events-tickets input[type='password'],
|
810 |
+
.tribe-events-tickets input[type='search'],
|
811 |
+
.tribe-events-tickets input[type='tel'],
|
812 |
+
.tribe-events-tickets input[type='number'],
|
813 |
.tribe-events-tickets textarea,
|
814 |
.tribe-events-tickets select {
|
815 |
width: auto
|
822 |
.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta > td, .tribe-events-tickets-rsvp tr.tribe-tickets-meta-row > td {
|
823 |
display: table-cell
|
824 |
}
|
825 |
+
}
|
826 |
|
827 |
@media (min-width: 600px) {
|
828 |
|
838 |
width: 84px
|
839 |
}
|
840 |
|
841 |
+
.tribe-block__rsvp__number-input-inner input[type='number'] {
|
842 |
font-size: 36px;
|
843 |
height: 48px
|
844 |
}
|
src/resources/css/rsvp-v1.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.tribe-rsvp{padding:20px 0}.tribe-tickets-attendee{padding:10px}.tribe-events-style-full .tribe-events-tickets .tribe-tickets-attendee table,.tribe-events-style-full .tribe-events-tickets .tribe-tickets-attendee td,.tribe-events-style-full .tribe-events-tickets .tribe-tickets-attendee tr,.tribe-events-tickets .tribe-tickets-attendee table,.tribe-events-tickets .tribe-tickets-attendee td,.tribe-events-tickets .tribe-tickets-attendee tr{border:0}.tribe-rsvp-message-display .tribe-rsvp-messages{display:block}.tribe-rsvp-messages{display:none;padding:10px 10px 5px}.tribe-rsvp-message{border-radius:3px;border-style:solid;border-width:1px;font-size:12px;margin:0 0 5px;padding:0 .6em}.tribe-rsvp-message-success{background-color:#ffffe0;border-color:#e6db55}.tribe-rsvp-message-error{background-color:#ffebe8;border-color:#c00}.tribe-tickets-quantity{width:100%}.tickets-unavailable{font-style:italic}.tribe-rsvp-list{list-style:none;padding:0;margin:0}.tribe-rsvp-list>.tribe-item{min-height:105px;padding:20px;border:1px solid #ededed;border-bottom:0}.tribe-rsvp-list>.tribe-item:last-child{border-bottom:1px solid #ededed;margin-bottom:20px}.tribe-rsvp-list>.tribe-item.tribe-disabled{background-color:#efefef;border-color:#ddd;color:#717171}.tribe-rsvp-list>.tribe-item.tribe-disabled:last-child{border-bottom-color:#ddd}.tribe-rsvp-list>.tribe-item .tribe-answer{float:right;display:inline-block}.tribe-rsvp-list>.tribe-item table{border:0;margin:0}.tribe-rsvp-list>.tribe-item td{border:0}.list-attendee{color:#999;display:inline-block;letter-spacing:1px;text-transform:uppercase}.tribe-submit-tickets-form{margin-top:20px}.user-details{margin:0 0 1.5em}.user-details p{margin:0 0 .5em}.tribe-answer{line-height:2}.tribe-answer .type-label{margin-bottom:0;padding-right:.5em}.tribe-answer label{display:block}.tribe-answer select{background:#fff;border:1px solid #ddd;height:30px;line-height:1;margin-left:5px}.tribe-rsvp h2{margin-bottom:20px;line-height:1.2}.event-tickets-meta-label{font-weight:700;margin:0 1em 0 0}.tribe-theme-parent-twentysixteen .comment-content a,.tribe-theme-parent-twentysixteen .entry-content a,.tribe-theme-parent-twentysixteen .entry-footer a:hover,.tribe-theme-parent-twentysixteen .entry-summary a,.tribe-theme-parent-twentysixteen .logged-in-as a,.tribe-theme-parent-twentysixteen .pingback .comment-body>a,.tribe-theme-parent-twentysixteen .site-info a:hover,.tribe-theme-parent-twentysixteen .taxonomy-description a,.tribe-theme-parent-twentysixteen .textwidget a,.tribe-theme-twentysixteen .comment-content a,.tribe-theme-twentysixteen .entry-content a,.tribe-theme-twentysixteen .entry-footer a:hover,.tribe-theme-twentysixteen .entry-summary a,.tribe-theme-twentysixteen .logged-in-as a,.tribe-theme-twentysixteen .pingback .comment-body>a,.tribe-theme-twentysixteen .site-info a:hover,.tribe-theme-twentysixteen .taxonomy-description a,.tribe-theme-twentysixteen .textwidget a{box-shadow:none}.tribe-events-tickets-title.tribe--rsvp{margin:0}.tribe-events-style-full.tribe-events-style-theme h2.tribe-events-tickets-title{font-size:90%}.tribe-link-view-attendee{margin:15px 0}.tribe-events-tickets{background:#f8f8f8;border:0;border-radius:3px;max-width:100%;position:relative}.tribe-events-tickets table,.tribe-events-tickets td,.tribe-events-tickets th{border:0}.tribe-events-tickets tr{display:flex;flex-flow:row wrap}.tribe-events-tickets tr:not(:first-child){border-top:2px solid #dfdfdf}.tribe-events-tickets td{flex:none;padding:8px 10px;width:100%;word-break:normal}.tribe-events-tickets td.tickets_name{font-weight:700}.tribe-events-tickets td.quantity,.tribe-events-tickets td.woocommerce{order:2}.tribe-events-tickets td.quantity input[type=number],.tribe-events-tickets td.woocommerce input[type=number]{background-color:#fff;border-radius:3px;margin-bottom:5px;padding:5px 10px;text-align:left}.tribe-events-tickets td.tickets_submit{order:3}.tribe-events-tickets td.tickets_submit .tribe-button{margin:0 0 10px}.tribe-events-tickets .woocommerce.add-to-cart .tribe-button{margin:10px 0}.tribe-events-tickets .tribe-link-tickets-message{background:hsla(0,0%,78%,.8);bottom:0;left:0;position:absolute;right:0;text-align:center;top:0}.tribe-events-tickets .tribe-link-tickets-message .no-javascript-msg{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:90%}.tribe-events-tickets .tribe-tickets-remaining{color:#777;display:block;font-size:11px}.tribe-events-tickets .tribe-tickets-attendees-list-optout label{color:#777;font-size:13px}.tribe-events-tickets .tribe-tickets-attendees-list-optout input[type=checkbox]+label,.tribe-events-tickets .tribe-tickets-attendees-list-optout input[type=radio]+label{display:inline-block}.tribe-events-tickets .tickets_description,.tribe-events-tickets .tickets_name,.tribe-events-tickets .tickets_name p,.tribe-events-tickets .tickets_price{color:#464646;font-size:15px;padding:16px 10px}.tribe-events-tickets input[type=date],.tribe-events-tickets input[type=datetime-local],.tribe-events-tickets input[type=email],.tribe-events-tickets input[type=month],.tribe-events-tickets input[type=number],.tribe-events-tickets input[type=password],.tribe-events-tickets input[type=search],.tribe-events-tickets input[type=tel],.tribe-events-tickets input[type=text],.tribe-events-tickets input[type=time],.tribe-events-tickets input[type=url],.tribe-events-tickets input[type=week],.tribe-events-tickets select,.tribe-events-tickets textarea{background:#fff;width:100%}.tribe-events-tickets header{height:auto}.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta,.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row{display:none}.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta>td,.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row>td,.tribe-tickets-has-rsvp.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta,.tribe-tickets-has-rsvp.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row{display:block}.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta tr,.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row tr{border:0}.tribe-block__rsvp{font-family:Helvetica,sans-serif;margin-bottom:30px;margin-top:30px;max-width:580px;position:relative}.tribe-block__rsvp__ticket{border:1px solid #e1e3e6;display:flex;flex-wrap:wrap;position:relative;width:100%}.tribe-block__rsvp__icon{align-items:center;background:#fff;border-bottom:1px dashed #b5bcc2;color:#434343;display:flex;flex:none;flex-direction:column;font-size:14px;font-weight:700;line-height:17px;padding:20px 17px;width:100%}.tribe-block__rsvp__icon svg{margin-bottom:7px}.tribe-block__rsvp__content{background-color:#f5f8f9;flex:auto}.tribe-block__rsvp__details{padding:25px 20px 20px}.tribe-block__rsvp__title{color:#000;font-size:21px;font-weight:700;line-height:28px;margin-bottom:12px}.tribe-block__rsvp__description{color:#545d66;font-size:14px;line-height:18px;margin-bottom:15px}.tribe-block__rsvp__availability{color:#545d66;display:flex;align-items:center;font-size:12px;line-height:18px}.tribe-block__rsvp__quantity{font-size:18px;font-weight:700;margin-right:6px}.tribe-block__rsvp__status{display:flex;flex-wrap:nowrap;padding:0 20px 25px;text-align:center}.tribe-block__rsvp__status>span{flex:none;margin-right:15px;width:calc(50% - 7.5px)}.tribe-block__rsvp__status>span:last-child{margin-right:0}.tribe-block__rsvp__status-button{align-items:center;border:1px solid #545d66;border-radius:4px;background:#fff;color:#545d66;display:flex;font-family:Helvetica,sans-serif;font-size:14px;font-weight:700;height:44px;justify-content:center;line-height:1;padding:0;width:100%}.tribe-block__rsvp__status-button svg{margin-left:9px}.tribe-block__rsvp__status-button:focus,.tribe-block__rsvp__status-button:hover{background:#fff;border:1px solid #000;color:#000}.tribe-block__rsvp__status-button.tribe-active{border:1px solid #000;color:#000}.tribe-block__rsvp__status-button.tribe-inactive{border:1px solid #e1e3e6;color:#a2aab2}.tribe-block__rsvp__status-button.tribe-inactive:focus,.tribe-block__rsvp__status-button.tribe-inactive:hover{background:#fff;border:1px solid #545d66;color:#545d66}.tribe-block__rsvp__status-button[disabled=disabled]{cursor:default}.tribe-block__rsvp__going-icon,.tribe-block__rsvp__not-going-icon{fill:#a2aab2}.tribe-active .tribe-block__rsvp__going-icon,.tribe-active .tribe-block__rsvp__not-going-icon,.tribe-block__rsvp__status-button:focus .tribe-block__rsvp__going-icon,.tribe-block__rsvp__status-button:focus .tribe-block__rsvp__not-going-icon,.tribe-block__rsvp__status-button:hover .tribe-block__rsvp__going-icon,.tribe-block__rsvp__status-button:hover .tribe-block__rsvp__not-going-icon{fill:#191e23}.tribe-inactive .tribe-block__rsvp__going-icon,.tribe-inactive .tribe-block__rsvp__not-going-icon{fill:#e1e3e6}.tribe-inactive:focus .tribe-block__rsvp__going-icon,.tribe-inactive:focus .tribe-block__rsvp__not-going-icon,.tribe-inactive:hover .tribe-block__rsvp__going-icon,.tribe-inactive:hover .tribe-block__rsvp__not-going-icon{fill:#a2aab2}.tribe-block__rsvp__form{padding:0 20px}.tribe-block__rsvp__form form{border-top:1px solid #e1e3e6;display:flex;padding:30px 0}.tribe-left{flex:none}.tribe-block__rsvp__number-input{padding-right:20px}.tribe-block__rsvp__number-input-inner{align-items:center;display:flex}.tribe-block__rsvp__number-input-inner input[type=number]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield;background:transparent;border:none;color:#000;font-family:Helvetica,sans-serif;font-size:30px;font-weight:700;height:40px;max-width:48px;padding:4px 0;text-align:center}.tribe-block__rsvp__number-input-inner input[type=number]::-webkit-inner-spin-button,.tribe-block__rsvp__number-input-inner input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;appearance:none}.tribe-block__rsvp__number-input-label{display:block;font-size:14px;font-weight:700;line-height:18px;margin-top:9px;text-align:center}.tribe-block__rsvp__number-input-button{background-color:transparent;height:30px;padding:0;position:relative;width:20px}.tribe-block__rsvp__number-input-button:after,.tribe-block__rsvp__number-input-button:before{background-color:#aeb4bb;content:"";height:2px;position:absolute;width:10px}.tribe-block__rsvp__number-input-button:focus,.tribe-block__rsvp__number-input-button:hover{background:none}.tribe-block__rsvp__number-input-button:focus:after,.tribe-block__rsvp__number-input-button:focus:before,.tribe-block__rsvp__number-input-button:hover:after,.tribe-block__rsvp__number-input-button:hover:before{background-color:#545d66}.tribe-block__rsvp__number-input-button--minus{margin-left:-10px}.tribe-block__rsvp__number-input-button--minus:after,.tribe-block__rsvp__number-input-button--minus:before{right:0}.tribe-block__rsvp__number-input-button--plus{margin-right:-10px}.tribe-block__rsvp__number-input-button--plus:after,.tribe-block__rsvp__number-input-button--plus:before{left:0}.tribe-block__rsvp__number-input-button--plus:after{transform:rotate(90deg)}.tribe-right{flex:auto}.tribe-right input[type=email],.tribe-right input[type=text]{border-color:#e1e3e6;color:#000;display:block;font-family:Helvetica,sans-serif;font-size:16px;height:40px;line-height:18px;margin-bottom:15px;padding:10px 15px;width:100%}.tribe-right input[type=email]:-ms-input-placeholder,.tribe-right input[type=text]:-ms-input-placeholder{color:#a2aab2}.tribe-right input[type=email]::placeholder,.tribe-right input[type=text]::placeholder{color:#a2aab2}.tribe-right label{cursor:pointer;font-size:14px;font-weight:400}.tribe-right label[for^=tribe-tickets-attendees-list-optout]{align-items:flex-start;display:flex;margin:0 0 15px;padding-top:7px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border:1px solid #e1e3e6;border-radius:0;cursor:pointer;flex:none;height:16px;margin:1px 10px 0 0;width:16px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]:focus{box-shadow:0 0 0 1px #e1e3e6;outline:2px solid transparent;outline-offset:-2px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]:checked:before{color:#009fd4;content:"\f147";display:inline-block;float:left;font:normal 21px/1 dashicons;margin:-3px 0 0 -4px;speak:none;vertical-align:middle;width:16px}.tribe-tickets-meta-option-label{color:#000;font-size:14px;line-height:18px;font-weight:400}.tribe-block__rsvp__message__error,.tribe-block__rsvp__message__success{color:#000;font-size:14px;line-height:18px;padding:20px}.tribe-block__rsvp__message__error{background:#ffebe8;border:1px solid #c00;display:none;margin-bottom:20px}.tribe-block__rsvp__message__success{background:#ecfae5;border:1px solid #1bd800;margin-top:20px}.tribe-block__rsvp__submit-button{background:#009fd4;color:#fff;font-family:Helvetica,sans-serif;font-size:15px;font-weight:700;line-height:18px;margin:10px 0 0;padding:10px 23px}.tribe-block__rsvp__submit-button:focus,.tribe-block__rsvp__submit-button:hover{background:#007bb4}.tribe-block__rsvp__submit-button:disabled{cursor:not-allowed;background:#a2aab2}.tribe-block__rsvp__form__attendee-meta{margin:0}.tribe-block__rsvp__form__attendee-meta td,.tribe-block__rsvp__form__attendee-meta th{padding:0;border:none;word-break:normal}.tribe-common-c-loader.tribe-block__rsvp__loading{align-items:center;background:hsla(0,0%,100%,.7);height:100%;justify-content:center;left:0;margin:0;padding:0;position:absolute;text-align:center;top:0;width:100%;z-index:99}.tribe-common-c-loader.tribe-block__rsvp__loading svg{max-width:70px;position:absolute;top:35%}.tribe-common-c-loader.tribe-block__rsvp__loading svg circle{fill:#888}@media only screen and (min-width:768px){.tribe-events-tickets tr{display:table-row}}@media (min-width:768px){.tribe-events-tickets td{width:auto}}@media (min-width:768px){.tribe-events-tickets td.quantity input[type=number],.tribe-events-tickets td.woocommerce input[type=number]{width:4.375em}.tribe-events-tickets .woocommerce.add-to-cart{padding:16px}.tribe-events-tickets .woocommerce.add-to-cart .tribe-button{margin:10px}.tribe-events-tickets input[type=date],.tribe-events-tickets input[type=datetime-local],.tribe-events-tickets input[type=email],.tribe-events-tickets input[type=month],.tribe-events-tickets input[type=number],.tribe-events-tickets input[type=password],.tribe-events-tickets input[type=search],.tribe-events-tickets input[type=tel],.tribe-events-tickets input[type=text],.tribe-events-tickets input[type=time],.tribe-events-tickets input[type=url],.tribe-events-tickets input[type=week],.tribe-events-tickets select,.tribe-events-tickets textarea{width:auto}.tribe-tickets-has-rsvp.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta,.tribe-tickets-has-rsvp.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row{display:table-row}.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta>td,.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row>td{display:table-cell}}@media (min-width:600px){.tribe-block__rsvp__ticket{align-items:stretch;flex-wrap:nowrap}.tribe-block__rsvp__icon{border-bottom:none;border-right:1px dashed #b5bcc2;padding:28px 17px;width:84px}.tribe-block__rsvp__number-input-inner input[type=number]{font-size:36px;height:48px}.tribe-block__rsvp__message__success{padding:10px 30px;text-align:center}}
|
1 |
+
.tribe-rsvp{padding:20px 0}.tribe-tickets-attendee{padding:10px}.tribe-events-style-full .tribe-events-tickets .tribe-tickets-attendee table,.tribe-events-style-full .tribe-events-tickets .tribe-tickets-attendee td,.tribe-events-style-full .tribe-events-tickets .tribe-tickets-attendee tr,.tribe-events-tickets .tribe-tickets-attendee table,.tribe-events-tickets .tribe-tickets-attendee td,.tribe-events-tickets .tribe-tickets-attendee tr{border:0}.tribe-rsvp-message-display .tribe-rsvp-messages{display:block}.tribe-rsvp-messages{display:none;padding:10px 10px 5px}.tribe-rsvp-message{border-radius:3px;border-style:solid;border-width:1px;font-size:12px;margin:0 0 5px;padding:0 .6em}.tribe-rsvp-message-success{background-color:#ffffe0;border-color:#e6db55}.tribe-rsvp-message-error{background-color:#ffebe8;border-color:#c00}.tribe-tickets-quantity{width:100%}.tickets-unavailable{font-style:italic}.tribe-rsvp-list{list-style:none;padding:0;margin:0}.tribe-rsvp-list>.tribe-item{min-height:105px;padding:20px;border:1px solid #ededed;border-bottom:0}.tribe-rsvp-list>.tribe-item:last-child{border-bottom:1px solid #ededed;margin-bottom:20px}.tribe-rsvp-list>.tribe-item.tribe-disabled{background-color:#efefef;border-color:#ddd;color:#717171}.tribe-rsvp-list>.tribe-item.tribe-disabled:last-child{border-bottom-color:#ddd}.tribe-rsvp-list>.tribe-item .tribe-answer{float:right;display:inline-block}.tribe-rsvp-list>.tribe-item table{border:0;margin:0}.tribe-rsvp-list>.tribe-item td{border:0}.list-attendee{color:#999;display:inline-block;letter-spacing:1px;text-transform:uppercase}.tribe-submit-tickets-form{margin-top:20px}.user-details{margin:0 0 1.5em}.user-details p{margin:0 0 .5em}.tribe-answer{line-height:2}.tribe-answer .type-label{margin-bottom:0;padding-right:.5em}.tribe-answer label{display:block}.tribe-answer select{background:#fff;border:1px solid #ddd;height:30px;line-height:1;margin-left:5px}.tribe-rsvp h2{margin-bottom:20px;line-height:1.2}.event-tickets-meta-label{font-weight:700;margin:0 1em 0 0}.tribe-theme-parent-twentysixteen .comment-content a,.tribe-theme-parent-twentysixteen .entry-content a,.tribe-theme-parent-twentysixteen .entry-footer a:hover,.tribe-theme-parent-twentysixteen .entry-summary a,.tribe-theme-parent-twentysixteen .logged-in-as a,.tribe-theme-parent-twentysixteen .pingback .comment-body>a,.tribe-theme-parent-twentysixteen .site-info a:hover,.tribe-theme-parent-twentysixteen .taxonomy-description a,.tribe-theme-parent-twentysixteen .textwidget a,.tribe-theme-twentysixteen .comment-content a,.tribe-theme-twentysixteen .entry-content a,.tribe-theme-twentysixteen .entry-footer a:hover,.tribe-theme-twentysixteen .entry-summary a,.tribe-theme-twentysixteen .logged-in-as a,.tribe-theme-twentysixteen .pingback .comment-body>a,.tribe-theme-twentysixteen .site-info a:hover,.tribe-theme-twentysixteen .taxonomy-description a,.tribe-theme-twentysixteen .textwidget a{box-shadow:none}.tribe-events-tickets-title.tribe--rsvp{margin:0}.tribe-events-style-full.tribe-events-style-theme h2.tribe-events-tickets-title{font-size:90%}.tribe-link-view-attendee{margin:15px 0}.tribe-events-tickets{background:var(--tec-color-background-secondary);border:0;border-radius:3px;max-width:100%;position:relative}.tribe-events-tickets table,.tribe-events-tickets td,.tribe-events-tickets th{border:0}.tribe-events-tickets tr{display:flex;flex-flow:row wrap}.tribe-events-tickets tr:not(:first-child){border-top:2px solid #dfdfdf}.tribe-events-tickets td{flex:none;padding:8px 10px;width:100%;word-break:normal}.tribe-events-tickets td.tickets_name{font-weight:700}.tribe-events-tickets td.quantity,.tribe-events-tickets td.woocommerce{order:2}.tribe-events-tickets td.quantity input[type=number],.tribe-events-tickets td.woocommerce input[type=number]{background-color:#fff;border-radius:3px;margin-bottom:5px;padding:5px 10px;text-align:left}.tribe-events-tickets td.tickets_submit{order:3}.tribe-events-tickets td.tickets_submit .tribe-button{margin:0 0 10px}.tribe-events-tickets .woocommerce.add-to-cart .tribe-button{margin:10px 0}.tribe-events-tickets .tribe-link-tickets-message{background:hsla(0,0%,78%,.8);bottom:0;left:0;position:absolute;right:0;text-align:center;top:0}.tribe-events-tickets .tribe-link-tickets-message .no-javascript-msg{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:90%}.tribe-events-tickets .tribe-tickets-remaining{color:var(--tec-color-text-secondary);display:block;font-size:11px}.tribe-events-tickets .tribe-tickets-attendees-list-optout label{color:var(--tec-color-text-secondary);font-size:13px}.tribe-events-tickets .tribe-tickets-attendees-list-optout input[type=checkbox]+label,.tribe-events-tickets .tribe-tickets-attendees-list-optout input[type=radio]+label{display:inline-block}.tribe-events-tickets .tickets_description,.tribe-events-tickets .tickets_name,.tribe-events-tickets .tickets_name p,.tribe-events-tickets .tickets_price{color:var(--tec-color-text-secondary);font-size:15px;padding:16px 10px}.tribe-events-tickets input[type=date],.tribe-events-tickets input[type=datetime-local],.tribe-events-tickets input[type=email],.tribe-events-tickets input[type=month],.tribe-events-tickets input[type=number],.tribe-events-tickets input[type=password],.tribe-events-tickets input[type=search],.tribe-events-tickets input[type=tel],.tribe-events-tickets input[type=text],.tribe-events-tickets input[type=time],.tribe-events-tickets input[type=url],.tribe-events-tickets input[type=week],.tribe-events-tickets select,.tribe-events-tickets textarea{background:#fff;width:100%}.tribe-events-tickets header{height:auto}.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta,.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row{display:none}.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta>td,.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row>td,.tribe-tickets-has-rsvp.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta,.tribe-tickets-has-rsvp.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row{display:block}.tribe-events-tickets-rsvp tr.tribe-event-tickets-plus-meta tr,.tribe-events-tickets-rsvp tr.tribe-tickets-meta-row tr{border:0}.tribe-block__rsvp{font-family:var(--tec-font-family-sans-serif);margin-bottom:30px;margin-top:30px;max-width:580px;position:relative}.tribe-block__rsvp__ticket{border:1px solid #e1e3e6;display:flex;flex-wrap:wrap;position:relative;width:100%}.tribe-block__rsvp__icon{align-items:center;background:#fff;border-bottom:1px dashed #b5bcc2;color:#434343;display:flex;flex:none;flex-direction:column;font-size:14px;font-weight:700;line-height:17px;padding:20px 17px;width:100%}.tribe-block__rsvp__icon svg{margin-bottom:7px}.tribe-block__rsvp__content{background-color:#f5f8f9;flex:auto}.tribe-block__rsvp__details{padding:25px 20px 20px}.tribe-block__rsvp__title{color:#000;font-size:21px;font-weight:700;line-height:28px;margin-bottom:12px}.tribe-block__rsvp__description{color:#545d66;font-size:14px;line-height:18px;margin-bottom:15px}.tribe-block__rsvp__availability{color:#545d66;display:flex;align-items:center;font-size:12px;line-height:18px}.tribe-block__rsvp__quantity{font-size:18px;font-weight:700;margin-right:6px}.tribe-block__rsvp__status{display:flex;flex-wrap:nowrap;padding:0 20px 25px;text-align:center}.tribe-block__rsvp__status>span{flex:none;margin-right:15px;width:calc(50% - 7.5px)}.tribe-block__rsvp__status>span:last-child{margin-right:0}.tribe-block__rsvp__status-button{align-items:center;border:1px solid #545d66;border-radius:4px;background:#fff;color:#545d66;display:flex;font-family:var(--tec-font-family-sans-serif);font-size:14px;font-weight:700;height:44px;justify-content:center;line-height:1;padding:0;width:100%}.tribe-block__rsvp__status-button svg{margin-left:9px}.tribe-block__rsvp__status-button:focus,.tribe-block__rsvp__status-button:hover{background:#fff;border:1px solid #000;color:#000}.tribe-block__rsvp__status-button.tribe-active{border:1px solid #000;color:#000}.tribe-block__rsvp__status-button.tribe-inactive{border:1px solid #e1e3e6;color:#a2aab2}.tribe-block__rsvp__status-button.tribe-inactive:focus,.tribe-block__rsvp__status-button.tribe-inactive:hover{background:#fff;border:1px solid #545d66;color:#545d66}.tribe-block__rsvp__status-button[disabled=disabled]{cursor:default}.tribe-block__rsvp__going-icon,.tribe-block__rsvp__not-going-icon{fill:#a2aab2}.tribe-active .tribe-block__rsvp__going-icon,.tribe-active .tribe-block__rsvp__not-going-icon,.tribe-block__rsvp__status-button:focus .tribe-block__rsvp__going-icon,.tribe-block__rsvp__status-button:focus .tribe-block__rsvp__not-going-icon,.tribe-block__rsvp__status-button:hover .tribe-block__rsvp__going-icon,.tribe-block__rsvp__status-button:hover .tribe-block__rsvp__not-going-icon{fill:#191e23}.tribe-inactive .tribe-block__rsvp__going-icon,.tribe-inactive .tribe-block__rsvp__not-going-icon{fill:#e1e3e6}.tribe-inactive:focus .tribe-block__rsvp__going-icon,.tribe-inactive:focus .tribe-block__rsvp__not-going-icon,.tribe-inactive:hover .tribe-block__rsvp__going-icon,.tribe-inactive:hover .tribe-block__rsvp__not-going-icon{fill:#a2aab2}.tribe-block__rsvp__form{padding:0 20px}.tribe-block__rsvp__form form{border-top:1px solid #e1e3e6;display:flex;padding:30px 0}.tribe-left{flex:none}.tribe-block__rsvp__number-input{padding-right:20px}.tribe-block__rsvp__number-input-inner{align-items:center;display:flex}.tribe-block__rsvp__number-input-inner input[type=number]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield;background:transparent;border:none;color:#000;font-family:var(--tec-font-family-sans-serif);font-size:30px;font-weight:700;height:40px;max-width:48px;padding:4px 0;text-align:center}.tribe-block__rsvp__number-input-inner input[type=number]::-webkit-inner-spin-button,.tribe-block__rsvp__number-input-inner input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;appearance:none}.tribe-block__rsvp__number-input-label{display:block;font-size:14px;font-weight:700;line-height:18px;margin-top:9px;text-align:center}.tribe-block__rsvp__number-input-button{background-color:transparent;height:30px;padding:0;position:relative;width:20px}.tribe-block__rsvp__number-input-button:after,.tribe-block__rsvp__number-input-button:before{background-color:#aeb4bb;content:"";height:2px;position:absolute;width:10px}.tribe-block__rsvp__number-input-button:focus,.tribe-block__rsvp__number-input-button:hover{background:none}.tribe-block__rsvp__number-input-button:focus:after,.tribe-block__rsvp__number-input-button:focus:before,.tribe-block__rsvp__number-input-button:hover:after,.tribe-block__rsvp__number-input-button:hover:before{background-color:#545d66}.tribe-block__rsvp__number-input-button--minus{margin-left:-10px}.tribe-block__rsvp__number-input-button--minus:after,.tribe-block__rsvp__number-input-button--minus:before{right:0}.tribe-block__rsvp__number-input-button--plus{margin-right:-10px}.tribe-block__rsvp__number-input-button--plus:after,.tribe-block__rsvp__number-input-button--plus:before{left:0}.tribe-block__rsvp__number-input-button--plus:after{transform:rotate(90deg)}.tribe-right{flex:auto}.tribe-right input[type=email],.tribe-right input[type=text]{border-color:#e1e3e6;color:#000;display:block;font-family:var(--tec-font-family-sans-serif);font-size:16px;height:40px;line-height:18px;margin-bottom:15px;padding:10px 15px;width:100%}.tribe-right input[type=email]:-ms-input-placeholder,.tribe-right input[type=text]:-ms-input-placeholder{color:#a2aab2}.tribe-right input[type=email]::placeholder,.tribe-right input[type=text]::placeholder{color:#a2aab2}.tribe-right label{cursor:pointer;font-size:14px;font-weight:400}.tribe-right label[for^=tribe-tickets-attendees-list-optout]{align-items:flex-start;display:flex;margin:0 0 15px;padding-top:7px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border:1px solid #e1e3e6;border-radius:0;cursor:pointer;flex:none;height:16px;margin:1px 10px 0 0;width:16px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]:focus{box-shadow:0 0 0 1px #e1e3e6;outline:2px solid transparent;outline-offset:-2px}.tribe-right label[for^=tribe-tickets-attendees-list-optout] input[type=checkbox]:checked:before{color:#009fd4;content:"\f147";display:inline-block;float:left;font:normal 21px/1 dashicons;margin:-3px 0 0 -4px;speak:none;vertical-align:middle;width:16px}.tribe-tickets-meta-option-label{color:#000;font-size:14px;line-height:18px;font-weight:400}.tribe-block__rsvp__message__error,.tribe-block__rsvp__message__success{color:#000;font-size:14px;line-height:18px;padding:20px}.tribe-block__rsvp__message__error{background:#ffebe8;border:1px solid #c00;display:none;margin-bottom:20px}.tribe-block__rsvp__message__success{background:#ecfae5;border:1px solid #1bd800;margin-top:20px}.tribe-block__rsvp__submit-button{background:#009fd4;color:#fff;font-family:var(--tec-font-family-sans-serif);font-size:15px;font-weight:700;line-height:18px;margin:10px 0 0;padding:10px 23px}.tribe-block__rsvp__submit-button:focus,.tribe-block__rsvp__submit-button:hover{background:#007bb4}.tribe-block__rsvp__submit-button:disabled{cursor:not-allowed;background:#a2aab2}.tribe-block__rsvp__form__attendee-meta{margin:0}.tribe-block__rsvp__form__attendee-meta td,.tribe-block__rsvp__form__attendee-meta th{padding:0;border:none;word-break:normal}.tribe-common
|