diff --git a/.github/workflows/tests-php.yml b/.github/workflows/tests-php.yml index e095bc54b9..c41a53d761 100644 --- a/.github/workflows/tests-php.yml +++ b/.github/workflows/tests-php.yml @@ -7,6 +7,7 @@ jobs: matrix: suite: # - acceptance + - ct1_integration - functional - integration - restv1 --group="capacity" diff --git a/.github/workflows/zip.yml b/.github/workflows/zip.yml index 66a0d5995b..a27e1f8048 100644 --- a/.github/workflows/zip.yml +++ b/.github/workflows/zip.yml @@ -7,6 +7,12 @@ on: description: 'Zip type: 0 = dev, 1 = production' required: false default: '0' + slack_channel: + description: 'Slack channel ID to post to' + required: false + slack_thread: + description: 'Slack thread to post to' + required: false jobs: zip: runs-on: ubuntu-latest @@ -25,18 +31,16 @@ jobs: - name: Setup branch for consumption in subsequent steps id: settings run: | - echo "::set-output name=branch::${JOB_BRANCH}" + echo "branch=${JOB_BRANCH}" >> $GITHUB_OUTPUT # ----------------------------------------------------------------------------- # Setup SSH keys and known_hosts # ------------------------------------------------------------------------------ - - name: Setup SSH keys and known_hosts - env: - SSH_AUTH_SOCK: /tmp/ssh_agent.sock - run: | - mkdir -p ~/.ssh - ssh-keyscan github.com >> ~/.ssh/known_hosts - ssh-agent -a $SSH_AUTH_SOCK > /dev/null - ssh-add - <<< "${{ secrets.GH_ACTIONS_SSH_KEY }}" + - name: Install SSH key + uses: shimataro/ssh-key-action@v2 + with: + key: ${{ secrets.GH_ACTIONS_SSH_KEY }} + name: id_rsa + known_hosts: github.com # ------------------------------------------------------------------------------ # Checkout the repo and tut # ------------------------------------------------------------------------------ @@ -55,6 +59,14 @@ jobs: ref: main path: tut fetch-depth: 1 + - name: Checkout jenkins-scripts + uses: actions/checkout@v2 + with: + token: ${{ secrets.GH_BOT_TOKEN }} + repository: the-events-calendar/jenkins-scripts + ref: main + path: jenkins-scripts + fetch-depth: 1 # ------------------------------------------------------------------------------ # Determine if we need to zip # ------------------------------------------------------------------------------ @@ -74,10 +86,11 @@ jobs: if [ "${JOB_FINAL}" == "1" ]; then FILENAME="${ZIP_NAME}.${VERSION}.zip" fi - echo "::set-output name=value::${FILENAME}" + echo "value=${FILENAME}" >> $GITHUB_OUTPUT echo $FILENAME - name: Check if zip already exists uses: the-events-calendar/action-s3-utility@main + if: github.event.inputs.final != '1' id: s3_zip continue-on-error: true env: @@ -95,7 +108,7 @@ jobs: if: steps.s3_zip.outcome != 'success' id: get-composer-cache-dir run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - uses: actions/cache@v2 if: steps.s3_zip.outcome != 'success' id: composer-cache @@ -130,6 +143,11 @@ jobs: working-directory: ./tut run: | composer install --no-dev -o --ignore-platform-reqs + - name: Install jenkins-scripts composer dependencies + working-directory: ./jenkins-scripts + run: | + composer install --no-dev -o --ignore-platform-reqs + cp script-config-sample.yml script-config.yml # ------------------------------------------------------------------------------ # Zip # ------------------------------------------------------------------------------ @@ -144,10 +162,13 @@ jobs: REPO_NAME=$( echo $GITHUB_REPOSITORY | sed "s/the-events-calendar\///") mkdir zip if [ "${JOB_FINAL}" == "1" ]; then - $TUT_BIN package --plugin=$REPO_NAME --branch="${{ steps.settings.outputs.branch }}" --ignore-view-versions --output="./zip" --final -v + output=$($TUT_BIN package --plugin=$REPO_NAME --branch="${{ steps.settings.outputs.branch }}" --ignore-view-versions --output=./zip --final -v) else - $TUT_BIN package --plugin=$REPO_NAME --branch="${{ steps.settings.outputs.branch }}" --ignore-view-versions --output="./zip" -v + output=$($TUT_BIN package --plugin=$REPO_NAME --branch="${{ steps.settings.outputs.branch }}" --ignore-view-versions --output=./zip -v) fi + echo "$output" + touch ${GITHUB_WORKSPACE}/results.txt + echo "$output" > ${GITHUB_WORKSPACE}/results.txt mv zip ${GITHUB_WORKSPACE}/zip - uses: the-events-calendar/action-s3-utility@main if: steps.s3_zip.outcome != 'success' @@ -161,3 +182,19 @@ jobs: S3_ENDPOINT: ${{ secrets.S3_ENDPOINT }} COMMAND: sync SOURCE_DIR: /github/workspace/zip + - name: Maybe prep data for Slack message + if: github.event_name == 'workflow_dispatch' && github.event.inputs.slack_channel != '' && github.event.inputs.slack_thread != '' && steps.s3_zip.outcome == 'success' + working-directory: ../ + run: | + touch ${GITHUB_WORKSPACE}/results.txt + echo "Packaging results" >> ${GITHUB_WORKSPACE}/results.txt + echo "-----------------" >> ${GITHUB_WORKSPACE}/results.txt + echo "" >> ${GITHUB_WORKSPACE}/results.txt + echo "Successfully packaged:" >> ${GITHUB_WORKSPACE}/results.txt + echo "* ./zip/\"${{ steps.file_name.outputs.value }}\"" >> ${GITHUB_WORKSPACE}/results.txt + echo "" >> ${GITHUB_WORKSPACE}/results.txt + - name: Maybe notify in Slack + if: github.event_name == 'workflow_dispatch' && github.event.inputs.slack_channel != '' && github.event.inputs.slack_thread != '' + working-directory: ../ + run: | + php ${GITHUB_WORKSPACE}/jenkins-scripts/mt-jenkins package:send-results --channel ${{ github.event.inputs.slack_channel }} --ts ${{ github.event.inputs.slack_thread }} --results-file "${GITHUB_WORKSPACE}/results.txt" --slack-token ${{ secrets.SLACK_TOKEN }} --build-url https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID} diff --git a/changelog.txt b/changelog.txt index da3d927b14..a17f3ccf11 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,8 +1,21 @@ == Changelog == -= [TBD] TBD = += [5.5.7] TBD = +* Fix - Resolve provisional IDs properly on the event edit screen for ticket management actions. [ET-1632] +* Fix - Fixed Ticket Commerce cart cookies not getting saved. [ET-1629] +* Tweak - Updated Currency options in Tickets Commerce settings for Croatian users from Kuna (HRK) to Euro (EUR). [ET-1625] +* Tweak - Updated Attendee Registration Fields upsell notice to only display in admin dashboard. [CT-67] +* Enhancement - Added currency format options to alter currency decimal separator, thousand separator, and number of decimal places. [ET-1608] + += [5.5.6] 2023-01-16 = + +* Tweak - Updated the settings description for stock handling options. [ET-1603] * Tweak - Added the `tribe-tickets__tickets-item--shared-capacity` wrapper class for tickets having shared capacity. [ETP-841] +* Tweak - Added a dashboard notice for sites running PHP versions lower than 7.4 to alert them that the minimum version of PHP is changing to 7.4 in February 2023. +* Enhancement - Added search capabilities to the Tickets Commerce Orders report page. [ET-1259] +* Fix - Allow loading attendance page with `event_id` params that use The Events Calendar provisional IDs. [ET-1624] +* Language - 4 new strings added, 43 updated, 0 fuzzied, and 2 obsoleted = [5.5.5] 2022-12-08 = diff --git a/common b/common index c45b41b56b..cca67a481c 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit c45b41b56bbf56da2f176ad0bcf5ba04fa846f88 +Subproject commit cca67a481cff1f12942cfc1cc64d7e83cbbf8e59 diff --git a/event-tickets.php b/event-tickets.php index c4a3387abe..9960e730fe 100644 --- a/event-tickets.php +++ b/event-tickets.php @@ -3,7 +3,7 @@ Plugin Name: Event Tickets Plugin URI: https://evnt.is/1acb Description: Event Tickets allows you to sell basic tickets and collect RSVPs from any post, page, or event. -Version: 5.5.6 +Version: 5.5.7 Author: The Events Calendar Author URI: https://evnt.is/1aor License: GPLv2 or later diff --git a/lang/event-tickets.pot b/lang/event-tickets.pot index e959593769..b76316b458 100644 --- a/lang/event-tickets.pot +++ b/lang/event-tickets.pot @@ -2,24 +2,25 @@ # This file is distributed under the GPLv2 or later. msgid "" msgstr "" -"Project-Id-Version: Event Tickets 5.5.6\n" +"Project-Id-Version: Event Tickets 5.5.7\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/event-tickets\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2023-01-11T05:14:12-08:00\n" -"PO-Revision-Date: 2023-01-11 13:14\n" +"POT-Creation-Date: 2023-02-06T07:23:40-08:00\n" +"PO-Revision-Date: 2023-02-06 15:23\n" "X-Generator: WP-CLI 2.7.1\n" "X-Domain: event-tickets\n" #. Plugin Name of the plugin #: event-tickets.php:61 #: src/admin-views/admin-welcome-message.php:73 -#: src/Tribe/Admin/Notices.php:92 +#: src/Tribe/Admin/Notices.php:95 #: src/Tribe/Main.php:690 #: src/Tribe/Privacy.php:59 +#: src/views/v2/emails/email-template/body/footer-credit.php:19 msgid "Event Tickets" msgstr "" @@ -64,7 +65,7 @@ msgstr "" #: src/admin-views/admin-welcome-message.php:71 #: src/admin-views/tribe-commerce-settings.php:4 #: src/Tickets/Commerce/Payments_Tab.php:300 -#: src/Tribe/Admin/Notices.php:214 +#: src/Tribe/Admin/Notices.php:217 #: src/Tribe/Main.php:665 msgid "Event Tickets Plus" msgstr "" @@ -138,7 +139,7 @@ msgid "Illustration of a thought lightbulb coming from a book" msgstr "" #: src/admin-views/admin-welcome-message.php:151 -#: src/Tickets/Emails/Emails_Tab.php:127 +#: src/Tickets/Emails/Emails_Tab.php:142 msgid "Knowledgebase" msgstr "" @@ -1004,7 +1005,7 @@ msgid "Enable \"Can't Go\" responses" msgstr "" #: src/admin-views/settings/featured/link.php:33 -#: src/Tickets/Commerce/Settings.php:415 +#: src/Tickets/Commerce/Settings.php:467 msgid "Learn more about configuring payment options with Tickets Commerce" msgstr "" @@ -1247,7 +1248,7 @@ msgid "You are now connected to Stripe! What's next?" msgstr "" #: src/admin-views/settings/tickets-commerce/stripe/modal/signup-complete/content.php:16 -#: src/Tickets/Commerce/Settings.php:285 +#: src/Tickets/Commerce/Settings.php:312 msgid "Currency" msgstr "" @@ -1406,7 +1407,7 @@ msgid "Enables PayPal Sandbox mode for testing." msgstr "" #: src/admin-views/tribe-commerce-settings.php:136 -#: src/Tickets/Commerce/Settings.php:289 +#: src/Tickets/Commerce/Settings.php:316 msgid "Currency Code" msgstr "" @@ -1415,7 +1416,7 @@ msgid "The currency that will be used for Tribe Commerce transactions." msgstr "" #: src/admin-views/tribe-commerce-settings.php:144 -#: src/Tickets/Commerce/Settings.php:255 +#: src/Tickets/Commerce/Settings.php:282 msgid "Stock Handling" msgstr "" @@ -1433,7 +1434,7 @@ msgid "Only decrease available %s stock if an order is confirmed as Completed by msgstr "" #: src/admin-views/tribe-commerce-settings.php:162 -#: src/Tickets/Commerce/Settings.php:327 +#: src/Tickets/Commerce/Settings.php:379 msgid "Success page" msgstr "" @@ -1442,7 +1443,7 @@ msgid "After a successful PayPal order users will be redirected to this page; us msgstr "" #: src/admin-views/tribe-commerce-settings.php:176 -#: src/Tickets/Commerce/Settings.php:346 +#: src/Tickets/Commerce/Settings.php:398 msgid "Confirmation email sender address" msgstr "" @@ -1452,32 +1453,32 @@ msgid "Email address PayPal %s customers will receive confirmation from. Leave e msgstr "" #: src/admin-views/tribe-commerce-settings.php:185 -#: src/Tickets/Commerce/Settings.php:361 +#: src/Tickets/Commerce/Settings.php:413 msgid "Confirmation email sender name" msgstr "" #. Translators: %s: The word "ticket" in lowercase. #: src/admin-views/tribe-commerce-settings.php:186 -#: src/Tickets/Commerce/Settings.php:365 +#: src/Tickets/Commerce/Settings.php:417 msgctxt "tickets fields settings paypal email sender" msgid "Sender name of the confirmation email sent to customers when confirming a %s purchase." msgstr "" #: src/admin-views/tribe-commerce-settings.php:194 -#: src/Tickets/Commerce/Settings.php:376 +#: src/Tickets/Commerce/Settings.php:428 msgid "Confirmation email subject" msgstr "" #. Translators: %s: The word "ticket" in lowercase. #: src/admin-views/tribe-commerce-settings.php:195 -#: src/Tickets/Commerce/Settings.php:380 +#: src/Tickets/Commerce/Settings.php:432 msgctxt "tickets fields settings paypal email subject" msgid "Subject of the confirmation email sent to customers when confirming a %s purchase." msgstr "" #. Translators: %s: The word "tickets" in lowercase. #: src/admin-views/tribe-commerce-settings.php:197 -#: src/Tickets/Commerce/Settings.php:388 +#: src/Tickets/Commerce/Settings.php:440 msgctxt "tickets fields settings paypal email subject" msgid "You have %s!" msgstr "" @@ -1772,12 +1773,12 @@ msgid "Getting started" msgstr "" #. Translators: %s: Link to "Event Tickets Plus" plugin. -#: src/Tickets/Admin/Upsell.php:43 +#: src/Tickets/Admin/Upsell.php:44 msgid "Get individual information collection from each attendee and advanced capacity options with %s" msgstr "" #. Translators: %s: Link to "Event Tickets Plus" plugin. -#: src/Tickets/Admin/Upsell.php:74 +#: src/Tickets/Admin/Upsell.php:76 msgid "Manually add attendees with %s" msgstr "" @@ -6519,7 +6520,7 @@ msgid "Stripe Settings" msgstr "" #: src/Tickets/Commerce/Gateways/Stripe/Settings.php:252 -#: src/Tickets/Commerce/Settings.php:244 +#: src/Tickets/Commerce/Settings.php:271 #: src/Tribe/Admin/Settings.php:235 msgid "General" msgstr "" @@ -6852,92 +6853,116 @@ msgctxt "Browser title" msgid "%s - Tickets Commerce Orders" msgstr "" -#: src/Tickets/Commerce/Settings.php:192 +#: src/Tickets/Commerce/Settings.php:219 msgid "Tickets Commerce Test Mode Active" msgstr "" -#: src/Tickets/Commerce/Settings.php:232 +#: src/Tickets/Commerce/Settings.php:259 msgid "-- No page set --" msgstr "" -#: src/Tickets/Commerce/Settings.php:248 +#: src/Tickets/Commerce/Settings.php:275 msgid "Enable Test Mode" msgstr "" -#: src/Tickets/Commerce/Settings.php:249 +#: src/Tickets/Commerce/Settings.php:276 msgid "Enables Test mode for testing payments. Any payments made will be done on \"sandbox\" accounts." msgstr "" #. Translators: %s: The word "ticket" in lowercase. -#: src/Tickets/Commerce/Settings.php:259 +#: src/Tickets/Commerce/Settings.php:286 msgctxt "tickets fields settings paypal stock handling" msgid "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." msgstr "" #. Translators: %1$s: The word "ticket" in lowercase. %2$s: `` opening tag. %3$s: `` closing tag. -#: src/Tickets/Commerce/Settings.php:268 +#: src/Tickets/Commerce/Settings.php:295 msgid "Decrease available %1$s stock and send the %1$s to the customer as soon as a %2$sPending%3$s order is created." msgstr "" #. Translators: %1$s: The word "ticket" in lowercase. %2$s: `` opening tag. %3$s: `` closing tag. -#: src/Tickets/Commerce/Settings.php:275 +#: src/Tickets/Commerce/Settings.php:302 msgid "Only decrease available %1$s stock and send the %1$s to the customer if an order is confirmed as %2$sCompleted%3$s by the payment gateway." msgstr "" -#: src/Tickets/Commerce/Settings.php:290 +#: src/Tickets/Commerce/Settings.php:317 msgid "The currency that will be used for Tickets Commerce transactions." msgstr "" -#: src/Tickets/Commerce/Settings.php:297 +#: src/Tickets/Commerce/Settings.php:325 +msgid "Decimal Separator" +msgstr "" + +#: src/Tickets/Commerce/Settings.php:326 +msgid "This sets the decimal separator of displayed prices." +msgstr "" + +#: src/Tickets/Commerce/Settings.php:333 +msgid "Thousands Separator" +msgstr "" + +#: src/Tickets/Commerce/Settings.php:334 +msgid "This sets the thousand separator of displayed prices" +msgstr "" + +#: src/Tickets/Commerce/Settings.php:341 +msgid "Number of Decimals" +msgstr "" + +#: src/Tickets/Commerce/Settings.php:342 +msgid "This sets the number of decimal points shown in displayed prices." +msgstr "" + +#: src/Tickets/Commerce/Settings.php:349 msgid "Currency Position" msgstr "" -#: src/Tickets/Commerce/Settings.php:298 +#: src/Tickets/Commerce/Settings.php:350 msgid "The position of the currency symbol as it relates to the ticket values." msgstr "" -#: src/Tickets/Commerce/Settings.php:302 +#: src/Tickets/Commerce/Settings.php:354 msgid "Before" msgstr "" -#: src/Tickets/Commerce/Settings.php:303 +#: src/Tickets/Commerce/Settings.php:355 msgid "After" msgstr "" -#: src/Tickets/Commerce/Settings.php:308 +#: src/Tickets/Commerce/Settings.php:360 msgid "Pages Configuration" msgstr "" -#: src/Tickets/Commerce/Settings.php:312 +#: src/Tickets/Commerce/Settings.php:364 msgid "Checkout page" msgstr "" #. Translators: %s: The [shortcode] for the success page. -#: src/Tickets/Commerce/Settings.php:316 +#: src/Tickets/Commerce/Settings.php:368 msgid "This is the page where customers go to complete their purchase. Use the %s shortcode to display the checkout experience in the page content." msgstr "" #. Translators: %s: The [shortcode] for the success page. -#: src/Tickets/Commerce/Settings.php:331 +#: src/Tickets/Commerce/Settings.php:383 msgid "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." msgstr "" -#: src/Tickets/Commerce/Settings.php:342 +#: src/Tickets/Commerce/Settings.php:394 #: src/Tickets/Emails/Emails_Tab.php:54 msgid "Emails" msgstr "" #. Translators: %s: The word "tickets" in lowercase. -#: src/Tickets/Commerce/Settings.php:350 +#: src/Tickets/Commerce/Settings.php:402 msgctxt "tickets fields settings confirmation email" msgid "Email address that %s customers will receive confirmation from. Leave empty to use the default WordPress site email address." msgstr "" -#: src/Tickets/Commerce/Settings.php:403 +#: src/Tickets/Commerce/Settings.php:455 msgid "Payment Gateways" msgstr "" -#: src/Tickets/Commerce/Settings.php:404 +#: src/Tickets/Commerce/Settings.php:456 msgid "Set up a payment gateway to get started with Tickets Commerce. Enable multiple gateways for providing users additional options for users when purchasing tickets." msgstr "" @@ -7036,573 +7061,577 @@ msgstr "" msgid "unavailable" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:333 +#: src/Tickets/Commerce/Utils/Currency.php:384 #: src/Tribe/Commerce/Currency.php:197 msgid "Australian Dollar (AUD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:341 +#: src/Tickets/Commerce/Utils/Currency.php:392 #: src/Tribe/Commerce/Currency.php:203 msgid "Brazilian Real (BRL)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:349 +#: src/Tickets/Commerce/Utils/Currency.php:400 #: src/Tribe/Commerce/Currency.php:209 msgid "Canadian Dollar (CAD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:357 +#: src/Tickets/Commerce/Utils/Currency.php:408 #: src/Tribe/Commerce/Currency.php:215 msgid "Swiss Franc (CHF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:365 +#: src/Tickets/Commerce/Utils/Currency.php:416 #: src/Tribe/Commerce/Currency.php:221 msgid "Czech Koruna (CZK)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:374 +#: src/Tickets/Commerce/Utils/Currency.php:425 #: src/Tribe/Commerce/Currency.php:228 msgid "Danish Krone (DKK)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:382 +#: src/Tickets/Commerce/Utils/Currency.php:433 #: src/Tribe/Commerce/Currency.php:234 msgid "Euro (EUR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:390 +#: src/Tickets/Commerce/Utils/Currency.php:441 #: src/Tribe/Commerce/Currency.php:240 msgid "Pound Sterling (GBP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:398 +#: src/Tickets/Commerce/Utils/Currency.php:449 #: src/Tribe/Commerce/Currency.php:246 msgid "Hong Kong Dollar (HKD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:406 +#: src/Tickets/Commerce/Utils/Currency.php:457 #: src/Tribe/Commerce/Currency.php:252 msgid "Hungarian Forint (HUF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:414 +#: src/Tickets/Commerce/Utils/Currency.php:465 #: src/Tribe/Commerce/Currency.php:258 msgid "Israeli New Sheqel (ILS)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:422 +#: src/Tickets/Commerce/Utils/Currency.php:473 #: src/Tribe/Commerce/Currency.php:264 msgid "Indian Rupee (INR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:430 +#: src/Tickets/Commerce/Utils/Currency.php:481 #: src/Tribe/Commerce/Currency.php:270 msgid "Japanese Yen (JPY)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:438 +#: src/Tickets/Commerce/Utils/Currency.php:489 #: src/Tribe/Commerce/Currency.php:276 msgid "Malaysian Ringgit (MYR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:446 +#: src/Tickets/Commerce/Utils/Currency.php:497 #: src/Tribe/Commerce/Currency.php:282 msgid "Mexican Peso (MXN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:454 +#: src/Tickets/Commerce/Utils/Currency.php:505 #: src/Tribe/Commerce/Currency.php:288 msgid "Norwegian Krone (NOK)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:462 +#: src/Tickets/Commerce/Utils/Currency.php:513 #: src/Tribe/Commerce/Currency.php:294 msgid "New Zealand Dollar (NZD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:470 +#: src/Tickets/Commerce/Utils/Currency.php:521 #: src/Tribe/Commerce/Currency.php:300 msgid "Philippine Peso (PHP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:478 +#: src/Tickets/Commerce/Utils/Currency.php:529 #: src/Tribe/Commerce/Currency.php:306 msgid "Polish Zloty (PLN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:486 +#: src/Tickets/Commerce/Utils/Currency.php:537 #: src/Tribe/Commerce/Currency.php:312 msgid "Russian Ruble (RUB)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:494 +#: src/Tickets/Commerce/Utils/Currency.php:545 #: src/Tribe/Commerce/Currency.php:318 msgid "Swedish Krona (SEK)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:502 +#: src/Tickets/Commerce/Utils/Currency.php:553 #: src/Tribe/Commerce/Currency.php:324 msgid "Singapore Dollar (SGD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:510 +#: src/Tickets/Commerce/Utils/Currency.php:561 #: src/Tribe/Commerce/Currency.php:342 msgid "U.S. Dollar (USD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:518 +#: src/Tickets/Commerce/Utils/Currency.php:569 msgid "South African Rand (ZAR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:526 +#: src/Tickets/Commerce/Utils/Currency.php:577 msgid "United Arab Emirates dirham (AED)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:534 +#: src/Tickets/Commerce/Utils/Currency.php:585 msgid "Afghan afghani (AFN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:542 +#: src/Tickets/Commerce/Utils/Currency.php:593 msgid "Albanian lek (ALL)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:550 +#: src/Tickets/Commerce/Utils/Currency.php:601 msgid "Armenian dram (AMD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:558 +#: src/Tickets/Commerce/Utils/Currency.php:609 msgid "Netherlands Antillean guilder (ANG)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:566 +#: src/Tickets/Commerce/Utils/Currency.php:617 msgid "Angolan kwanza (AOA)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:574 +#: src/Tickets/Commerce/Utils/Currency.php:625 msgid "Argentine peso (ARS)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:582 +#: src/Tickets/Commerce/Utils/Currency.php:633 msgid "Aruban florin (AWG)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:590 +#: src/Tickets/Commerce/Utils/Currency.php:641 msgid "Azerbaijani manat (AZN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:598 +#: src/Tickets/Commerce/Utils/Currency.php:649 msgid "Bosnia and Herzegovina convertible mark (BAM)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:606 +#: src/Tickets/Commerce/Utils/Currency.php:657 msgid "Brunei dollar (BND)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:614 +#: src/Tickets/Commerce/Utils/Currency.php:665 msgid "Belize dollar (BZD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:622 +#: src/Tickets/Commerce/Utils/Currency.php:673 msgid "Lebanese pound (LBP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:630 +#: src/Tickets/Commerce/Utils/Currency.php:681 msgid "Sri Lankan rupee (LKR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:638 +#: src/Tickets/Commerce/Utils/Currency.php:689 msgid "Liberian dollar (LRD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:646 +#: src/Tickets/Commerce/Utils/Currency.php:697 msgid "Lesotho loti (LSL)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:654 +#: src/Tickets/Commerce/Utils/Currency.php:705 msgid "Moroccan dirham (MAD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:662 +#: src/Tickets/Commerce/Utils/Currency.php:713 msgid "Moldovan leu (MDL)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:670 +#: src/Tickets/Commerce/Utils/Currency.php:721 msgid "Malagasy ariary (MGA)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:678 +#: src/Tickets/Commerce/Utils/Currency.php:729 msgid "Macedonian denar (MKD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:686 +#: src/Tickets/Commerce/Utils/Currency.php:737 msgid "Burmese kyat (MMK)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:694 +#: src/Tickets/Commerce/Utils/Currency.php:745 msgid "Mongolian tögrög (MNT)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:702 +#: src/Tickets/Commerce/Utils/Currency.php:753 msgid "Macanese pataca (MOP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:710 +#: src/Tickets/Commerce/Utils/Currency.php:761 msgid "Mauritian rupee (MUR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:718 +#: src/Tickets/Commerce/Utils/Currency.php:769 msgid "Maldivian rufiyaa (MVR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:726 +#: src/Tickets/Commerce/Utils/Currency.php:777 msgid "Malawian kwacha (MWK)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:734 +#: src/Tickets/Commerce/Utils/Currency.php:785 msgid "Mexican peso (MXN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:742 +#: src/Tickets/Commerce/Utils/Currency.php:793 msgid "Malaysian ringgit (MYR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:750 +#: src/Tickets/Commerce/Utils/Currency.php:801 msgid "Mozambican metical (MZN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:758 +#: src/Tickets/Commerce/Utils/Currency.php:809 msgid "Namibian dollar (NAD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:766 +#: src/Tickets/Commerce/Utils/Currency.php:817 msgid "Nigerian naira (NGN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:774 +#: src/Tickets/Commerce/Utils/Currency.php:825 msgid "Nicaraguan córdoba (NIO)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:782 +#: src/Tickets/Commerce/Utils/Currency.php:833 msgid "Nepalese rupee (NPR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:790 +#: src/Tickets/Commerce/Utils/Currency.php:841 msgid "Panamanian balboa (PAB)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:798 +#: src/Tickets/Commerce/Utils/Currency.php:849 msgid "Peruvian sol (PEN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:806 +#: src/Tickets/Commerce/Utils/Currency.php:857 msgid "Papua New Guinean kina (PGK)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:814 +#: src/Tickets/Commerce/Utils/Currency.php:865 msgid "Philippine peso (PHP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:822 +#: src/Tickets/Commerce/Utils/Currency.php:873 msgid "Pakistani rupee (PKR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:830 +#: src/Tickets/Commerce/Utils/Currency.php:881 msgid "Paraguayan guaraní (PYG)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:838 +#: src/Tickets/Commerce/Utils/Currency.php:889 msgid "Qatari riyal (QAR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:846 +#: src/Tickets/Commerce/Utils/Currency.php:897 msgid "Romanian leu (RON)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:854 +#: src/Tickets/Commerce/Utils/Currency.php:905 msgid "Serbian dinar (RSD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:862 +#: src/Tickets/Commerce/Utils/Currency.php:913 msgid "Rwandan franc (RWF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:870 +#: src/Tickets/Commerce/Utils/Currency.php:921 msgid "Saudi riyal (SAR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:878 +#: src/Tickets/Commerce/Utils/Currency.php:929 msgid "Solomon Islands dollar (SBD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:886 +#: src/Tickets/Commerce/Utils/Currency.php:937 msgid "Seychellois rupee (SCR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:894 +#: src/Tickets/Commerce/Utils/Currency.php:945 msgid "Barbadian dollar (BBD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:902 +#: src/Tickets/Commerce/Utils/Currency.php:953 msgid "Bangladeshi taka (BDT)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:910 +#: src/Tickets/Commerce/Utils/Currency.php:961 msgid "Bulgarian lev (BGN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:918 +#: src/Tickets/Commerce/Utils/Currency.php:969 msgid "Burundian franc (BIF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:926 +#: src/Tickets/Commerce/Utils/Currency.php:977 msgid "Bermudian dollar (BMD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:934 +#: src/Tickets/Commerce/Utils/Currency.php:985 msgid "Bolivian boliviano (BOB)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:942 +#: src/Tickets/Commerce/Utils/Currency.php:993 msgid "Bahamian dollar (BSD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:950 +#: src/Tickets/Commerce/Utils/Currency.php:1001 msgid "Botswana pula (BWP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:958 +#: src/Tickets/Commerce/Utils/Currency.php:1009 msgid "Belarusian ruble (BYN)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:966 +#: src/Tickets/Commerce/Utils/Currency.php:1017 msgid "Congolese franc (CDF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:974 +#: src/Tickets/Commerce/Utils/Currency.php:1025 msgid "Chilean peso (CLP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:982 +#: src/Tickets/Commerce/Utils/Currency.php:1033 msgid "Chinese yuan (CNY)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:990 +#: src/Tickets/Commerce/Utils/Currency.php:1041 msgid "Colombian peso (COP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:998 +#: src/Tickets/Commerce/Utils/Currency.php:1049 msgid "Costa Rican colón (CRC)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1006 +#: src/Tickets/Commerce/Utils/Currency.php:1057 msgid "Cape Verdean escudo (CVE)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1014 +#: src/Tickets/Commerce/Utils/Currency.php:1065 msgid "Djiboutian franc (DJF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1022 +#: src/Tickets/Commerce/Utils/Currency.php:1073 msgid "Dominican peso (DOP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1030 +#: src/Tickets/Commerce/Utils/Currency.php:1081 msgid "Algerian dinar (DZD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1038 +#: src/Tickets/Commerce/Utils/Currency.php:1089 msgid "Egyptian pound (EGP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1046 +#: src/Tickets/Commerce/Utils/Currency.php:1097 msgid "Ethiopian birr (ETB)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1054 +#: src/Tickets/Commerce/Utils/Currency.php:1105 msgid "Fijian dollar (FJD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1062 +#: src/Tickets/Commerce/Utils/Currency.php:1113 msgid "Georgian lari (GEL)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1070 +#: src/Tickets/Commerce/Utils/Currency.php:1121 msgid "Gibraltar pound (GIP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1078 +#: src/Tickets/Commerce/Utils/Currency.php:1129 msgid "Gambian dalasi (GMD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1086 +#: src/Tickets/Commerce/Utils/Currency.php:1137 msgid "Guinean franc (GNF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1094 +#: src/Tickets/Commerce/Utils/Currency.php:1145 msgid "Guatemalan quetzal (GTQ)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1102 +#: src/Tickets/Commerce/Utils/Currency.php:1153 msgid "Guyanese dollar (GYD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1110 +#: src/Tickets/Commerce/Utils/Currency.php:1161 msgid "Honduran lempira (HNL)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1118 -msgid "Croatian kuna (HRK)" -msgstr "" - -#: src/Tickets/Commerce/Utils/Currency.php:1126 +#: src/Tickets/Commerce/Utils/Currency.php:1169 msgid "Haitian gourde (HTG)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1134 +#: src/Tickets/Commerce/Utils/Currency.php:1177 msgid "Indonesian rupiah (IDR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1142 +#: src/Tickets/Commerce/Utils/Currency.php:1185 msgid "Icelandic krona (ISK)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1150 +#: src/Tickets/Commerce/Utils/Currency.php:1193 msgid "Jamaican dollar (JMD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1158 +#: src/Tickets/Commerce/Utils/Currency.php:1201 msgid "Kenyan shilling (KES)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1166 +#: src/Tickets/Commerce/Utils/Currency.php:1209 msgid "Kyrgyzstani som (KGS)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1174 +#: src/Tickets/Commerce/Utils/Currency.php:1217 msgid "Cambodian riel (KHR)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1182 +#: src/Tickets/Commerce/Utils/Currency.php:1225 msgid "Comorian franc (KMF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1190 +#: src/Tickets/Commerce/Utils/Currency.php:1233 msgid "South Korean won (KRW)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1198 +#: src/Tickets/Commerce/Utils/Currency.php:1241 msgid "Cayman Islands dollar (KYD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1206 +#: src/Tickets/Commerce/Utils/Currency.php:1249 msgid "Kazakhstani tenge (KZT)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1214 +#: src/Tickets/Commerce/Utils/Currency.php:1257 msgid "Lao kip (LAK)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1222 +#: src/Tickets/Commerce/Utils/Currency.php:1265 msgid "Saint Helena pound (SHP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1230 +#: src/Tickets/Commerce/Utils/Currency.php:1273 msgid "Sierra Leonean leone (SLL)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1238 +#: src/Tickets/Commerce/Utils/Currency.php:1281 msgid "Somali shilling (SOS)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1246 +#: src/Tickets/Commerce/Utils/Currency.php:1289 msgid "Surinamese dollar (SRD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1254 +#: src/Tickets/Commerce/Utils/Currency.php:1297 msgid "Swazi lilangeni (SZL)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1262 +#: src/Tickets/Commerce/Utils/Currency.php:1305 msgid "Thai baht (THB)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1270 +#: src/Tickets/Commerce/Utils/Currency.php:1313 msgid "Tajikistani somoni (TJS)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1278 +#: src/Tickets/Commerce/Utils/Currency.php:1321 msgid "Tongan paʻanga (TOP)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1286 +#: src/Tickets/Commerce/Utils/Currency.php:1329 msgid "Turkish lira (TRY)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1294 +#: src/Tickets/Commerce/Utils/Currency.php:1337 msgid "Trinidad and Tobago dollar (TTD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1302 +#: src/Tickets/Commerce/Utils/Currency.php:1345 msgid "New Taiwan dollar (TWD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1310 +#: src/Tickets/Commerce/Utils/Currency.php:1353 msgid "Tanzanian shilling (TZS)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1318 +#: src/Tickets/Commerce/Utils/Currency.php:1361 msgid "Ukrainian hryvnia (UAH)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1326 +#: src/Tickets/Commerce/Utils/Currency.php:1369 msgid "Ugandan shilling (UGX)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1334 +#: src/Tickets/Commerce/Utils/Currency.php:1377 msgid "Uruguayan peso (UYU)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1342 +#: src/Tickets/Commerce/Utils/Currency.php:1385 msgid "Uzbekistani som (UZS)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1350 +#: src/Tickets/Commerce/Utils/Currency.php:1393 msgid "Vietnamese dong (VND)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1358 +#: src/Tickets/Commerce/Utils/Currency.php:1401 msgid "Vanuatu vatu (VUV)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1366 +#: src/Tickets/Commerce/Utils/Currency.php:1409 msgid "Samoan tālā (WST)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1374 +#: src/Tickets/Commerce/Utils/Currency.php:1417 msgid "Central African CFA franc (XAF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1382 +#: src/Tickets/Commerce/Utils/Currency.php:1425 msgid "East Caribbean dollar (XCD)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1390 +#: src/Tickets/Commerce/Utils/Currency.php:1433 msgid "West African CFA franc (XOF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1398 +#: src/Tickets/Commerce/Utils/Currency.php:1441 msgid "CFP franc (XPF)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1406 +#: src/Tickets/Commerce/Utils/Currency.php:1449 msgid "Yemeni rial (YER)" msgstr "" -#: src/Tickets/Commerce/Utils/Currency.php:1414 +#: src/Tickets/Commerce/Utils/Currency.php:1457 msgid "Zambian kwacha (ZMW)" msgstr "" +#: src/Tickets/Commerce/Utils/Currency.php:1522 +msgid "Tickets Commerce is now selling with Euro" +msgstr "" + +#: src/Tickets/Commerce/Utils/Currency.php:1523 +msgid "From the 1st of January 2023, the euro became the official currency for Croatia. We have removed the Croatian Kuna from our currency settings and updated your settings to start selling with Euro." +msgstr "" + #: src/Tickets/Custom_Tables/V1/admin-views/migration/maintenance-mode/ticket-updates.php:6 msgid "Your changes will not be saved." msgstr "" @@ -7615,15 +7644,57 @@ msgstr "" msgid "Tickets and RSVPs have been disabled on this site while it is undergoing maintenance. Thank you for your patience." msgstr "" -#: src/Tickets/Emails/Emails_Tab.php:123 +#: src/Tickets/Emails/Admin/Preview_Modal.php:82 +msgid "Email Preview" +msgstr "" + +#: src/Tickets/Emails/Admin/Preview_Modal.php:139 +#: src/Tickets/Emails/Admin/Preview_Modal.php:148 +msgid "Preview Email" +msgstr "" + +#: src/Tickets/Emails/Admin/Preview_Modal.php:143 +msgctxt "Preview email button on the settings" +msgid "Preview Email" +msgstr "" + +#: src/Tickets/Emails/Emails_Tab.php:138 msgid "Tickets Emails" msgstr "" #. Translators: %s Link to knowledgebase article. -#: src/Tickets/Emails/Emails_Tab.php:131 +#: src/Tickets/Emails/Emails_Tab.php:146 msgid "Customize your customer communications when tickets are purchased, RSVPs are submitted, and for Tickets Commerce order notifications. Learn More about Tickets Commerce communications in our %s." msgstr "" +#: src/Tickets/Emails/Email_Template.php:179 +msgid "September 22 @ 7:00 pm - 11:00 pm" +msgstr "" + +#: src/Tickets/Emails/Email_Template.php:180 +msgid "General Admission" +msgstr "" + +#: src/Tickets/Emails/Email_Template.php:182 +msgid "Rebirth Brass Band" +msgstr "" + +#: src/Tickets/Emails/Email_Template.php:185 +msgid "Saturn" +msgstr "" + +#: src/Tickets/Emails/Email_Template.php:186 +msgid "200 41st Street South" +msgstr "" + +#: src/Tickets/Emails/Email_Template.php:187 +msgid "Birmingham, AL, 35222" +msgstr "" + +#: src/Tickets/Emails/Email_Template.php:188 +msgid "(987) 654-3210" +msgstr "" + #: src/Tickets/Emails/Settings.php:179 msgid "Sender Information" msgstr "" @@ -7684,14 +7755,6 @@ msgstr "" msgid "Add custom links and instructions to the bottom of your emails." msgstr "" -#: src/Tickets/Emails/Settings.php:329 -msgid "Footer Credit" -msgstr "" - -#: src/Tickets/Emails/Settings.php:330 -msgid "Include \"Ticket powered by Event Tickets\" in the footer" -msgstr "" - #: src/Tribe/Abstract_Attendance_Totals.php:67 msgctxt "total sold tooltip" msgid "Includes all ticketed attendees regardless of order status." @@ -7806,13 +7869,13 @@ msgstr "" msgid "%1$s type was moved to %3$s from %5$s" msgstr "" -#: src/Tribe/Admin/Notices.php:88 +#: src/Tribe/Admin/Notices.php:91 msgctxt "Admin notice link text" msgid "RSVP Display Settings" msgstr "" #. translators: %1$s: RSVP singular text, %2$s: Link to settings page. -#: src/Tribe/Admin/Notices.php:97 +#: src/Tribe/Admin/Notices.php:100 msgid "" "With this new version, we've introduced newly redesigned %1$s frontend views. If you have customized the %1$s section, this update will likely impact your customizations.\n" "\n" @@ -7820,27 +7883,27 @@ msgid "" msgstr "" #. Translators: %1$s: dynamic "Tickets" text, %2$s: dynamic "Event" text. -#: src/Tribe/Admin/Notices.php:152 +#: src/Tribe/Admin/Notices.php:155 msgctxt "heading for classic editor notice if Events Calendar Pro event has tickets" msgid "%1$s for Recurring %2$s" msgstr "" #. Translators: %1$s: dynamic "event" text, %2$s: dynamic "ticket" text, %3$s: dynamic "tickets" text, %4$s: dynamic "RSVP" text, %5$s: dynamic "Ticket" text. -#: src/Tribe/Admin/Notices.php:163 +#: src/Tribe/Admin/Notices.php:166 msgctxt "text for classic editor notice if Events Calendar Pro event has tickets" msgid "Heads up! You saved a recurring %1$s with a %2$s. Please note that we do not currently support recurring %3$s. Only the first instance of this recurring series will have your %4$s or %5$s displayed." msgstr "" -#: src/Tribe/Admin/Notices.php:218 +#: src/Tribe/Admin/Notices.php:221 msgid "WooCommerce" msgstr "" -#: src/Tribe/Admin/Notices.php:219 +#: src/Tribe/Admin/Notices.php:222 msgid "Easy Digital Downloads" msgstr "" #. translators: %1$s: The ticket commerce provider (WooCommerce, etc); %2$s: The Event Tickets Plus plugin name and link. -#: src/Tribe/Admin/Notices.php:229 +#: src/Tribe/Admin/Notices.php:232 msgid "Event Tickets does not support ticket sales via third party ecommerce plugins. If you want to sell tickets with %1$s, please purchase a license for %2$s." msgstr "" @@ -7976,7 +8039,7 @@ msgid "It looks like you have modified your shared capacity setting but have not msgstr "" #: src/Tribe/Assets.php:294 -#: src/Tribe/Metabox.php:646 +#: src/Tribe/Metabox.php:831 msgid "Please enter in without thousand separators and currency symbols." msgstr "" @@ -8358,12 +8421,12 @@ msgstr "" #: src/Tribe/Editor/REST/V1/Endpoints/Single_Ticket.php:66 #: src/Tribe/Editor/REST/V1/Endpoints/Single_Ticket.php:252 -#: src/Tribe/Metabox.php:222 -#: src/Tribe/Metabox.php:283 -#: src/Tribe/Metabox.php:327 -#: src/Tribe/Metabox.php:384 -#: src/Tribe/Metabox.php:438 -#: src/Tribe/Metabox.php:476 +#: src/Tribe/Metabox.php:258 +#: src/Tribe/Metabox.php:368 +#: src/Tribe/Metabox.php:457 +#: src/Tribe/Metabox.php:556 +#: src/Tribe/Metabox.php:623 +#: src/Tribe/Metabox.php:661 msgid "Commerce Module invalid" msgstr "" @@ -8517,55 +8580,65 @@ msgstr "" msgid "Buy" msgstr "" -#: src/Tribe/Metabox.php:114 +#: src/Tribe/Metabox.php:115 msgid "Invalid Post ID" msgstr "" -#: src/Tribe/Metabox.php:199 -#: src/Tribe/Metabox.php:267 -#: src/Tribe/Metabox.php:311 -#: src/Tribe/Metabox.php:358 +#: src/Tribe/Metabox.php:207 +#: src/Tribe/Metabox.php:326 +#: src/Tribe/Metabox.php:415 +#: src/Tribe/Metabox.php:506 msgid "Invalid parent Post" msgstr "" -#: src/Tribe/Metabox.php:209 -msgid "Failed to add the %s. Refresh the page to try again." +#. Translators: %1$s - singular ticket term. +#: src/Tribe/Metabox.php:227 +msgid "Failed to add the %1$s. Refresh the page to try again." msgstr "" -#: src/Tribe/Metabox.php:213 +#: src/Tribe/Metabox.php:241 msgid "Commerce Provider invalid" msgstr "" -#: src/Tribe/Metabox.php:239 -msgid "Failed to add the %s" +#. Translators: %1$s - Singular ticket term. +#: src/Tribe/Metabox.php:277 +msgid "Failed to add the %1$s" msgstr "" -#. Translators: %s: dynamic "ticket" text. -#: src/Tribe/Metabox.php:273 -#: src/Tribe/Metabox.php:317 -#: src/Tribe/Metabox.php:366 -msgid "Invalid %s" +#. Translators: %1$s - singular ticket term. +#. Translators: %1$s - singular ticket term +#: src/Tribe/Metabox.php:341 +#: src/Tribe/Metabox.php:430 +msgid "Invalid %1$s" msgstr "" -#: src/Tribe/Metabox.php:277 -msgid "Failed to edit the %s. Refresh the page to try again." +#. Translators: %1$s - singular ticket term. +#: src/Tribe/Metabox.php:354 +msgid "Failed to edit the %1$s. Refresh the page to try again." +msgstr "" + +#. Translators: %1$s - singular ticket term +#: src/Tribe/Metabox.php:443 +msgid "Failed to delete the %1$s. Refresh the page to try again." msgstr "" -#: src/Tribe/Metabox.php:321 -msgid "Failed to delete the %s. Refresh the page to try again." +#. Translators: %s: dynamic "ticket" text. +#: src/Tribe/Metabox.php:522 +msgid "Invalid %s" msgstr "" #. Translators: %s: dynamic "ticket" text. -#: src/Tribe/Metabox.php:374 +#: src/Tribe/Metabox.php:538 msgid "Failed to duplicate the %s. Refresh the page to try again." msgstr "" -#: src/Tribe/Metabox.php:400 -msgid "Failed to duplicate the %s" +#. Translators: %1$s - singular ticket term +#: src/Tribe/Metabox.php:573 +msgid "Failed to duplicate the %1$s" msgstr "" -#: src/Tribe/Metabox.php:430 -#: src/Tribe/Metabox.php:468 +#: src/Tribe/Metabox.php:615 +#: src/Tribe/Metabox.php:653 msgid "The attendee ID is missing from the request parameters." msgstr "" @@ -10240,6 +10313,44 @@ msgstr "" msgid "Order Received!" msgstr "" +#: src/views/v2/emails/email-template/body/add-links.php:16 +msgid "Add event to iCal" +msgstr "" + +#: src/views/v2/emails/email-template/body/add-links.php:21 +msgid "Add event to Google Calendar" +msgstr "" + +#: src/views/v2/emails/email-template/body/event-location.php:20 +msgid "Event Location" +msgstr "" + +#: src/views/v2/emails/email-template/body/event-location.php:40 +msgid "Get Directions" +msgstr "" + +#. Translators: %s - HTML link to `Event Tickets` website. +#: src/views/v2/emails/email-template/body/footer-credit.php:23 +msgid "Ticket powered by %s" +msgstr "" + +#: src/views/v2/emails/email-template/body/greeting.php:11 +msgid "Here's your ticket!" +msgstr "" + +#. Translators: %s - First name of email recipient. +#: src/views/v2/emails/email-template/body/greeting.php:14 +msgid "Here's your ticket, %s!" +msgstr "" + +#: src/views/v2/emails/email-template/body/top-link.php:14 +msgid "Having trouble viewing this email?" +msgstr "" + +#: src/views/v2/emails/email-template/body/top-link.php:15 +msgid "Click here" +msgstr "" + #: src/views/v2/rsvp/actions/full.php:22 msgid "RSVP Closed" msgstr "" diff --git a/package.json b/package.json index 3d224b7ec2..34b71fada9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "event-tickets", - "version": "5.5.6", + "version": "5.5.7", "repository": "git@github.com:the-events-calendar/event-tickets.git", "_zipname": "event-tickets", "_zipfoldername": "event-tickets", diff --git a/readme.txt b/readme.txt index 31f0b28600..a71b060ce2 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Contributors: theeventscalendar, brianjessee, camwynsp, aguseo, bordoni, borkweb Tags: tickets, registration, event registration, RSVP, ticket sales, attendee management Requires at least: 5.8.5 Tested up to: 6.1.1 -Stable tag: 5.5.6 +Stable tag: 5.5.7 Requires PHP: 7.3 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -190,6 +190,15 @@ Check out our extensive [knowledgebase](https://evnt.is/18wm) for articles on us == Changelog == += [5.5.7] 2023-02-09 = + +* Enhancement - Added currency format options to alter currency decimal separator, thousand separator, and number of decimal places. [ET-1608] +* Tweak - Updated Currency options in Tickets Commerce settings for Croatian users from Kuna (HRK) to Euro (EUR). [ET-1625] +* Tweak - Updated Attendee Registration Fields upsell notice to only display in admin dashboard. [CT-67] +* Fix - Resolve provisional IDs properly on the event edit screen for ticket management actions. [ET-1632] +* Fix - Fixed Ticket Commerce cart cookies not getting saved. [ET-1629] +* Language - 28 new strings added, 189 updated, 5 fuzzied, and 3 obsoleted + = [5.5.6] 2023-01-16 = * Tweak - Updated the settings description for stock handling options. [ET-1603] diff --git a/src/Tickets/Admin/Upsell.php b/src/Tickets/Admin/Upsell.php index 3a0c892d80..b1b4aae710 100644 --- a/src/Tickets/Admin/Upsell.php +++ b/src/Tickets/Admin/Upsell.php @@ -26,11 +26,12 @@ public function hooks() { /** * Maybe show upsell for Capacity and ARF features. * + * @since 5.5.7 - Added is_admin() to make sure upsells only display within the admin area. * @since 5.3.4 */ public function maybe_show_capacity_arf() { - // If they already have ET+ activated, then bail. - if ( class_exists( 'Tribe__Tickets_Plus__Main' ) ) { + // If they already have ET+ activated or are not within the admin area, then bail. + if ( class_exists( 'Tribe__Tickets_Plus__Main' ) || ! is_admin() ) { return; } @@ -56,11 +57,12 @@ public function maybe_show_capacity_arf() { /** * Maybe show upsell for Manual Attendees. * + * @since 5.5.7 - Added is_admin() to make sure upsells only display within the admin area. * @since 5.3.4 */ public function maybe_show_manual_attendees() { - // If they already have ET+ activated, then bail. - if ( class_exists( 'Tribe__Tickets_Plus__Main' ) ) { + // If they already have ET+ activated or are not within the admin area, then bail. + if ( class_exists( 'Tribe__Tickets_Plus__Main' ) || ! is_admin() ) { return; } diff --git a/src/Tickets/Commerce/Cart.php b/src/Tickets/Commerce/Cart.php index 1215c74b14..c3a7810d4b 100644 --- a/src/Tickets/Commerce/Cart.php +++ b/src/Tickets/Commerce/Cart.php @@ -316,23 +316,18 @@ public function set_cart_hash_cookie( $value = '' ) { * @param int $expires The expiry time, as passed to setcookie(). */ $expire = apply_filters( 'tec_tickets_commerce_cart_expiration', time() + 1 * HOUR_IN_SECONDS ); - $referer = wp_get_referer(); - - if ( $referer ) { - $secure = ( 'https' === parse_url( $referer, PHP_URL_SCHEME ) ); - } else { - $secure = false; - } // When null means we are deleting. if ( null === $value ) { $expire = 1; } - $is_cookie_set = setcookie( static::$cart_hash_cookie_name, $value, $expire, COOKIEPATH ?: '/', COOKIE_DOMAIN, $secure ); + $is_cookie_set = setcookie( static::$cart_hash_cookie_name, $value, $expire, COOKIEPATH ?: '/', COOKIE_DOMAIN, is_ssl(), true ); - // Overwrite local variable so we can use it right away. - $_COOKIE[ static::$cart_hash_cookie_name ] = $value; + if ( $is_cookie_set ) { + // Overwrite local variable, so we can use it right away. + $_COOKIE[ static::$cart_hash_cookie_name ] = $value; + } return $is_cookie_set; } diff --git a/src/Tickets/Commerce/Settings.php b/src/Tickets/Commerce/Settings.php index aafdf041dc..2159d6b9d0 100644 --- a/src/Tickets/Commerce/Settings.php +++ b/src/Tickets/Commerce/Settings.php @@ -53,6 +53,33 @@ class Settings { */ public static $option_currency_code = 'tickets-commerce-currency-code'; + /** + * The option key for currency decimal separator. + * + * @since 5.5.7 + * + * @var string + */ + public static $option_currency_decimal_separator = 'tickets-commerce-currency-decimal-separator'; + + /** + * The option key for currency thousands separator. + * + * @since 5.5.7 + * + * @var string + */ + public static $option_currency_thousands_separator = 'tickets-commerce-currency-thousands-separator'; + + /** + * The option key for currency number of decimals. + * + * @since 5.5.7 + * + * @var string + */ + public static $option_currency_number_of_decimals = 'tickets-commerce-currency-number-of-decimals'; + /** * The option key for currency position. * @@ -288,10 +315,35 @@ public function get_settings() { 'type' => 'dropdown', 'label' => esc_html__( 'Currency Code', 'event-tickets' ), 'tooltip' => esc_html__( 'The currency that will be used for Tickets Commerce transactions.', 'event-tickets' ), - 'default' => 'USD', + 'default' => Currency::$currency_code_fallback, 'validation_type' => 'options', 'options' => $tc_currency_options, ], + + static::$option_currency_decimal_separator => [ + 'type' => 'text', + 'label' => esc_html__( 'Decimal Separator', 'event-tickets' ), + 'tooltip' => esc_html__( 'This sets the decimal separator of displayed prices.', 'event-tickets' ), + 'default' => Currency::$currency_code_decimal_separator, + 'validation_callback' => 'is_string', + ], + + static::$option_currency_thousands_separator => [ + 'type' => 'text', + 'label' => esc_html__( 'Thousands Separator', 'event-tickets' ), + 'tooltip' => esc_html__( 'This sets the thousand separator of displayed prices', 'event-tickets' ), + 'default' => Currency::$currency_code_thousands_separator, + 'validation_callback' => 'is_string', + ], + + static::$option_currency_number_of_decimals => [ + 'type' => 'text', + 'label' => esc_html__( 'Number of Decimals', 'event-tickets' ), + 'tooltip' => esc_html__( 'This sets the number of decimal points shown in displayed prices.', 'event-tickets' ), + 'default' => Currency::$currency_code_number_of_decimals, + 'validation_type' => 'int', + ], + static::$option_currency_position => [ 'type' => 'dropdown', 'label' => esc_html__( 'Currency Position', 'event-tickets' ), diff --git a/src/Tickets/Commerce/Utils/Currency.php b/src/Tickets/Commerce/Utils/Currency.php index 0d2bde54fd..d608d0707e 100644 --- a/src/Tickets/Commerce/Utils/Currency.php +++ b/src/Tickets/Commerce/Utils/Currency.php @@ -42,6 +42,51 @@ class Currency { */ public static $currency_code_fallback = 'USD'; + /** + * The fallback currency code to use if none is found. + * + * @since 5.5.7 + * + * @var string + */ + public static $currency_code_fallback_symbol = '$'; + + /** + * The fallback currency thousands separator to use if none is found. + * + * @since 5.5.7 + * + * @var string + */ + public static $currency_code_thousands_separator = ','; + + /** + * The fallback currency decimal separator to use if none is found. + * + * @since 5.5.7 + * + * @var string + */ + public static $currency_code_decimal_separator = '.'; + + /** + * The fallback number of decimals for currency. + * + * @since 5.5.7 + * + * @var string + */ + public static $currency_code_number_of_decimals = '2'; + + /** + * Unsupported Currency. + * + * @since 5.5.7 + * + * @var array + */ + public static $unsupported_currency = []; + /** * Retrieves the working currency code. * @@ -163,12 +208,14 @@ public static function get_currency_name( $code ) { */ public static function get_currency_precision( $code ) { $map = static::get_default_currency_map(); - $precision = 2; + $precision = static::$currency_code_number_of_decimals; if ( isset( $map[ $code ] ) ) { $precision = $map[ $code ]['decimal_precision']; } + $precision = tribe_get_option( Settings::$option_currency_number_of_decimals, $precision ); + /** * Filter the specific currency precision before returning. $code is the 3-letter currency code. * @@ -203,12 +250,14 @@ public static function get_currency_precision( $code ) { */ public static function get_currency_separator_decimal( $code ) { $map = static::get_default_currency_map(); - $separator = ''; + $separator = static::$currency_code_decimal_separator; if ( isset( $map[ $code ] ) ) { $separator = $map[ $code ]['decimal_point']; } + $separator = tribe_get_option( Settings::$option_currency_decimal_separator, $separator ); + /** * Filter the specific currency decimal separator before returning. $code is the 3-letter currency code. * @@ -243,12 +292,14 @@ public static function get_currency_separator_decimal( $code ) { */ public static function get_currency_separator_thousands( $code ) { $map = static::get_default_currency_map(); - $separator = ''; + $separator = static::$currency_code_thousands_separator; if ( isset( $map[ $code ] ) ) { $separator = $map[ $code ]['thousands_sep']; } + $separator = tribe_get_option( Settings::$option_currency_thousands_separator, $separator ); + /** * Filter the specific currency thousands separator before returning. $code is the 3-letter currency code. * @@ -1114,14 +1165,6 @@ public static function get_default_currency_map() { 'decimal_precision' => 2, 'stripe_minimum_charge' => 25, ], - 'HRK' => [ - 'name' => __( 'Croatian kuna (HRK)', 'event-tickets' ), - 'symbol' => 'kn', - 'decimal_point' => '.', - 'thousands_sep' => ',', - 'decimal_precision' => 2, - 'stripe_minimum_charge' => 8, - ], 'HTG' => [ 'name' => __( 'Haitian gourde (HTG)', 'event-tickets' ), 'symbol' => 'G', @@ -1458,4 +1501,73 @@ public function get_currency_code_options() { */ return apply_filters( 'tec_tickets_commerce_currency_code_options', $options ); } + + /** + * Get unsupported currencies and notice texts. + * + * @since 5.5.7 + * + * @return array + */ + public static function get_unsupported_currencies(): array { + /** + * Filter all unsupported currencies before returning. + * + * @since 5.5.7 + * + * @return array + */ + return apply_filters( 'tec_tickets_commerce_unsupported_currencies', [ + 'HRK' => [ + 'heading' => __( 'Tickets Commerce is now selling with Euro', 'event-tickets' ), + 'message' => __( 'From the 1st of January 2023, the euro became the official currency for Croatia. We have removed the Croatian Kuna from our currency settings and updated your settings to start selling with Euro.', 'event-tickets' ), + 'new_value' => 'EUR', + ], + ] + ); + } + + /** + * Verify if currency is supported. + * + * @since 5.5.7 + * + * @return bool + */ + public static function is_current_currency_supported(): bool { + // Get currency code option. + $currency = tribe_get_option( static::$currency_code_option ); + + // Get unsupported currencies. + $unsupported_currencies = static::get_unsupported_currencies(); + + if ( array_key_exists( $currency, $unsupported_currencies ) ) { + // Get the unsupported currency. + static::$unsupported_currency = $unsupported_currencies[ $currency ]; + + // Get the currency symbol. + $default_map = static::get_default_currency_map(); + static::$unsupported_currency['symbol'] = $default_map[ $currency ]['symbol']; + + // Update currency option to the new value. + static::update_currency_option( $unsupported_currencies[ $currency ]['new_value'] ); + + return false; + } + + return true; + } + + /** + * Update currency option to the new value if the currency is unsupported. + * + * @since 5.5.7 + * + * @param string $new_currency_option + * @return void + */ + public static function update_currency_option( $new_currency_option ) { + // Update currency option. + tribe_update_option( static::$currency_code_option, $new_currency_option ); + } } \ No newline at end of file diff --git a/src/Tickets/Emails/Admin/Preview_Modal.php b/src/Tickets/Emails/Admin/Preview_Modal.php new file mode 100644 index 0000000000..7eb19f70ed --- /dev/null +++ b/src/Tickets/Emails/Admin/Preview_Modal.php @@ -0,0 +1,216 @@ +is_on_tab(); + } + + /** + * Render the `Emails` preview modal. + * + * @since 5.5.7 + */ + public function render_modal() { + if ( ! $this->should_render() ) { + return; + } + + // Enqueue `Emails` assets. + tribe_asset_enqueue_group( Assets::$group_key ); + + tribe_asset_enqueue_group( 'tribe-tickets-admin' ); + + // Render the modal contents. + echo $this->get_modal_content(); + } + + /** + * Get the default modal args. + * + * @since 5.5.7 + * + * @param array $args Override default args by sending them in the `$args`. + * + * @return array The default modal args. + */ + public function get_modal_args( $args = [] ): array { + $default_args = [ + 'append_target' => '#' . static::$modal_target, + 'button_display' => false, + 'close_event' => 'tribeDialogCloseEmailsPreviewModal.tribeTickets', + 'show_event' => 'tribeDialogShowEmailsPreviewModal.tribeTickets', + 'content_wrapper_classes' => 'tribe-dialog__wrapper tribe-modal__wrapper--emails-preview tribe-tickets__admin-container event-tickets tribe-common', + 'title' => esc_html__( 'Email Preview', 'event-tickets' ), + 'title_classes' => [ + 'tribe-dialog__title', + 'tribe-modal__title', + 'tribe-common-h5', + 'tribe-modal__title--emails-preview', + ], + ]; + + return wp_parse_args( $args, $default_args ); + } + + /** + * Get the default modal contents. + * + * @since 5.5.7 + * + * @param array $args Override default args by sending them in the `$args`. + * + * @return string The modal content. + */ + public function get_modal_content( $args = [] ): string { + /** @var Tribe__Tickets__Editor__Template $template */ + $template = tribe( 'tickets.editor.template' ); + + $content = $template->template( 'v2/components/loader/loader', [], false ); + + $args = $this->get_modal_args( $args ); + + $dialog_view = tribe( 'dialog.view' ); + + ob_start(); + $dialog_view->render_modal( $content, $args, static::$modal_id ); + $modal_content = ob_get_clean(); + + $modal = '
'; + $modal .= ''; + $modal .= $modal_content; + $modal .= '
'; + + return $modal; + } + + /** + * Get the default modal button args. + * + * @since 5.5.7 + * + * @param array $args Override default args by sending them in the `$args`. + * + * @return array The default modal button args. + */ + public static function get_modal_button_args( $args = [] ): array { + $default_args = [ + 'id' => static::$modal_id, + 'append_target' => '#' . static::$modal_target, + 'button_classes' => [ 'button', 'action', 'button-primary', 'tec-tickets__admin-settings-emails-preview-button' ], + 'button_attributes' => [ 'data-modal-title' => esc_html__( 'Preview Email', 'event-tickets' ) ], + 'button_display' => true, + 'button_id' => 'tec-tickets__admin-emails-preview-' . uniqid(), + 'button_name' => 'tec-tickets-emails-preview', + 'button_text' => esc_attr_x( 'Preview Email', 'Preview email button on the settings', 'event-tickets' ), + 'button_type' => 'button', + 'close_event' => 'tribeDialogCloseEmailsPreviewModal.tribeTickets', + 'show_event' => 'tribeDialogShowEmailsPreviewModal.tribeTickets', + 'content_wrapper_classes' => 'tribe-dialog__wrapper event-tickets tribe-common', + 'title' => esc_html__( 'Preview Email', 'event-tickets' ), + 'title_classes' => [ + 'tribe-dialog__title', + 'tribe-modal__title', + 'tribe-common-h5', + 'tribe-modal__title--emails-preview', + ], + ]; + + return wp_parse_args( $args, $default_args ); + } + + /** + * Get the default modal button. + * + * @since 5.5.7 + * + * @param array $args Override default args by sending them in the `$args`. + * + * @return string The modal button. + */ + public static function get_modal_button( $args = [] ): string { + $args = self::get_modal_button_args( $args ); + $dialog_view = tribe( 'dialog.view' ); + $button = $dialog_view->template( 'button', $args, false ); + + return $button; + } + + /** + * Get the `Tickets Emails` preview modal content, + * depending on the request. + * + * @since 5.5.7 + * + * @param string|\WP_Error $render_response The render response HTML content or WP_Error with list of errors. + * @param array $vars The request variables. + * + * @return string $html The response with the HTML of the form, depending on the call. + */ + public function get_modal_content_ajax( $render_response, $vars ) { + $html = ''; + + /** @var Tribe__Tickets__Editor__Template $template */ + $tickets_template = tribe( 'tickets.editor.template' ); + + $email_template = tribe( Email_Template::class ); + $email_template->set_preview( true ); + + $context = []; + + $ticket_bg_color = Arr::get( $vars, 'ticketBgColor', '' ); + + if ( ! empty( $ticket_bg_color ) ) { + $context['ticket_bg_color'] = $ticket_bg_color; + } + + $header_bg_color = Arr::get( $vars, 'headerBgColor', '' ); + + if ( ! empty( $header_bg_color ) ) { + $context['header_bg_color'] = $header_bg_color; + } + + $html = $email_template->get_html( $context ); + $html .= $tickets_template->template( 'v2/components/loader/loader', [], false ); + + return $html; + } +} diff --git a/src/Tickets/Emails/Assets.php b/src/Tickets/Emails/Assets.php index 47f94bb4cd..c9d1e8db4e 100644 --- a/src/Tickets/Emails/Assets.php +++ b/src/Tickets/Emails/Assets.php @@ -20,6 +20,15 @@ */ class Assets extends tad_DI52_ServiceProvider { + /** + * Key for this group of assets. + * + * @since 5.5.7 + * + * @var string + */ + public static $group_key = 'tec-tickets-admin-emails'; + /** * Binds and sets up implementations. * @@ -27,7 +36,24 @@ class Assets extends tad_DI52_ServiceProvider { */ public function register() { /** @var Tribe__Tickets__Main $tickets_main */ - $tickets_main = tribe( 'tickets.main' ); + $plugin = tribe( 'tickets.main' ); + tribe_asset( + $plugin, + static::$group_key . '-modal-scripts', + 'admin/tickets-emails.js', + [ + 'jquery', + 'tribe-common', + 'tribe-tickets-loader', + ], + null, + [ + 'groups' => [ + static::$group_key, + 'tribe-tickets-admin', + ], + ] + ); } -} \ No newline at end of file +} diff --git a/src/Tickets/Emails/Email_Template.php b/src/Tickets/Emails/Email_Template.php new file mode 100644 index 0000000000..9298decdaa --- /dev/null +++ b/src/Tickets/Emails/Email_Template.php @@ -0,0 +1,194 @@ +template ) ) { + $this->template = new Tribe__Template(); + $this->template->set_template_origin( Tribe__Tickets__Main::instance() ); + // @todo Move template folder into `src/views/v2` before TE release. + $this->template->set_template_folder( 'src/views/v2/emails' ); + $this->template->set_template_context_extract( true ); + } + + return $this->template; + } + + /** + * Returns the email template HTML. + * + * @since 5.5.7 + * + * @return string The HTML of the template. + */ + public function get_html( $context = [] ) { + $template = $this->get_template(); + $context = wp_parse_args( $context, $this->get_context() ); + + return $template->template( 'email-template', $context, false ); + } + + /** + * Prints the email template HTML. + * + * @since 5.5.7 + * + * @return void. + */ + public function render() { + echo $this->get_html(); + } + + /** + * Sets whether or not this will be a template preview. + * + * @since 5.5.7 + * + * @param boolean $is_preview + * + * @return void + */ + public function set_preview( $is_preview = false ) { + $this->preview = $is_preview; + } + + /** + * Is this a template preview? + * + * @since 5.5.7 + * + * @return boolean Whether or not this is a template preview. + */ + public function is_preview() { + return $this->preview; + } + + /** + * Sets the data for the template context. + * + * @since 5.5.7 + * + * @param array $data + * + * @return void + */ + public function set_data( array $data ) { + $this->context_data = $data; + } + + /** + * Returns the template context array and creates sample data if preview. + * + * @since 5.5.7 + * + * @return array Template context array. + */ + public function get_context() { + $context = [ + 'preview' => $this->preview, + 'header_image_url' => tribe_get_option( Settings::$option_header_image_url, '' ), + 'header_image_alignment' => tribe_get_option( Settings::$option_header_image_alignment, 'left' ), + 'header_bg_color' => tribe_get_option( Settings::$option_header_bg_color, '#ffffff' ), + 'ticket_bg_color' => tribe_get_option( Settings::$option_ticket_bg_color, '#007363' ), + 'footer_content' => tribe_get_option( Settings::$option_footer_content, '' ), + 'footer_credit' => true, + ]; + $context['header_text_color'] = Tribe__Utils__Color::get_contrast_color( $context['header_bg_color'] ); + $context['ticket_text_color'] = Tribe__Utils__Color::get_contrast_color( $context['ticket_bg_color'] ); + + if ( $this->preview ) { + $this->context_data = $this->get_preview_context_array(); + } + + $this->context_data = array_merge( $context, $this->context_data ); + + /** + * Allow filtering the contxt array before sending to the email template. + * + * @since 5.5.7 + * + * @param array Context array for email template. + */ + return apply_filters( 'tec_tickets_emails_email_template_context', $this->context_data ); + } + + /** + * Get the context data in the case of a template preview. + * + * @since 5.5.7 + * + * @return array Context data. + */ + private function get_preview_context_array() { + $current_user = wp_get_current_user(); + return [ + 'recipient_first_name' => $current_user->first_name, + 'recipient_last_name' => $current_user->last_name, + 'date_string' => esc_html__( 'September 22 @ 7:00 pm - 11:00 pm', 'event-tickets' ), + 'ticket_name' => esc_html__( 'General Admission', 'event-tickets' ), + 'ticket_id' => '17e4a14cec', + 'event_title' => esc_html__( 'Rebirth Brass Band', 'event-tickets' ), + 'event_image_url' => esc_url( plugins_url( '/event-tickets/src/resources/images/example-event-image.png' ) ), + 'event_venue' => [ + 'name' => esc_html__( 'Saturn', 'event-tickets' ), + 'address1' => esc_html__( '200 41st Street South', 'event-tickets' ), + 'address2' => esc_html__( 'Birmingham, AL, 35222', 'event-tickets' ), + 'phone' => esc_html__( '(987) 654-3210', 'event-tickets' ), + 'website' => esc_url( get_site_url() ), + ], + 'event_description' => '

Additional Information

Age Restriction: 18+
Door Time: 8:00PM
Event Time: 9:00PM

', + ]; + } +} diff --git a/src/Tickets/Emails/Emails_Tab.php b/src/Tickets/Emails/Emails_Tab.php index 819b76a255..2cbfd03e98 100644 --- a/src/Tickets/Emails/Emails_Tab.php +++ b/src/Tickets/Emails/Emails_Tab.php @@ -104,6 +104,21 @@ public function get_url( array $args = [] ): string { return tribe( Plugin_Settings::class )->get_url( $args ); } + /** + * Determine if is on "tab". + * + * @since 5.5.7 + * + * @return boolean True when on `emails` tab. + */ + public function is_on_tab(): bool { + $admin_pages = tribe( 'admin.pages' ); + $current_page = $admin_pages->get_current_page(); + $current_tab = tribe_get_request_var( 'tab' ); + + return $admin_pages->is_tec_page( $current_page ) && self::$slug === $current_tab; + } + /** * Gets the top level settings for Tickets Commerce. * diff --git a/src/Tickets/Emails/Hooks.php b/src/Tickets/Emails/Hooks.php index 10d6659964..c1979ecd89 100644 --- a/src/Tickets/Emails/Hooks.php +++ b/src/Tickets/Emails/Hooks.php @@ -45,6 +45,8 @@ public function register() { */ protected function add_actions() { add_action( 'tribe_settings_do_tabs', [ $this, 'register_emails_tab' ], 17 ); + add_action( 'tribe_settings_after_form_element_tab_emails', [ $this, 'action_add_preview_modal_button' ] ); + add_action( 'admin_footer', [ $this, 'action_add_preview_modal' ] ); } /** @@ -57,6 +59,9 @@ protected function add_filters() { add_filter( 'tec_tickets_emails_settings_fields', [ $this, 'filter_add_template_list' ] ); add_filter( 'tec_tickets_emails_settings_fields', [ $this, 'filter_add_sender_info_fields' ] ); add_filter( 'tec_tickets_emails_settings_fields', [ $this, 'filter_add_email_styling_fields' ] ); + + // Hook the `Tickets Emails` preview for the AJAX requests. + add_filter( 'tribe_tickets_admin_manager_request', [ $this, 'filter_add_preview_modal_content' ], 15, 2 ); } /** @@ -64,12 +69,30 @@ protected function add_filters() { * * @since 5.5.6 * - * @param $admin_page Page ID of current admin page. + * @param string $admin_page Page ID of current admin page. */ public function register_emails_tab( $admin_page ) { $this->container->make( Emails_Tab::class )->register_tab( $admin_page ); } + /** + * Action to add the preview modal button to the settings page. + * + * @since 5.5.7 + */ + public function action_add_preview_modal_button() { + echo $this->container->make( Admin\Preview_modal::class )->get_modal_button(); + } + + /** + * Action to add the preview modal to the settings page. + * + * @since 5.5.7 + */ + public function action_add_preview_modal() { + echo $this->container->make( Admin\Preview_modal::class )->render_modal(); + } + /** * Filter to add tab id to tickets emails tab. * @@ -121,4 +144,22 @@ public function filter_add_sender_info_fields( $fields ) { public function filter_add_email_styling_fields( $fields ) { return $this->container->make( Settings::class )->email_styling_fields( $fields ); } + + /** + * Filter the preview modal content. + * + * @since 5.5.7 + * + * @param string|\WP_Error $render_response The render response HTML content or WP_Error with list of errors. + * @param array $vars The request variables. + * + * @return string $content The response for the preview modal content. + */ + public function filter_add_preview_modal_content( $render_response, $vars ) { + if ( 'tec_tickets_preview_email' !== $vars['request'] ) { + return $render_response; + } + + return $this->container->make( Admin\Preview_modal::class )->get_modal_content_ajax( $render_response, $vars ); + } } diff --git a/src/Tickets/Emails/Provider.php b/src/Tickets/Emails/Provider.php index 98184a302f..81b0e760f3 100644 --- a/src/Tickets/Emails/Provider.php +++ b/src/Tickets/Emails/Provider.php @@ -39,6 +39,9 @@ public function register() { $this->container->singleton( Emails_Tab::class ); $this->container->singleton( 'tickets.emails.emails-tab', $this ); + $this->container->singleton( Admin\Preview_Modal::class ); + $this->container->singleton( 'tickets.emails.admin.preview-modal', $this ); + } /** @@ -63,7 +66,7 @@ protected function register_hooks() { $hooks = new Hooks( $this->container ); $hooks->register(); - // Allow Hooks to be removed, by having the them registered to the container + // Allow Hooks to be removed, by having the them registered to the container. $this->container->singleton( Hooks::class, $hooks ); $this->container->singleton( 'tickets.emails.hooks', $hooks ); } diff --git a/src/Tickets/Emails/Settings.php b/src/Tickets/Emails/Settings.php index 970b517874..f699872570 100644 --- a/src/Tickets/Emails/Settings.php +++ b/src/Tickets/Emails/Settings.php @@ -81,13 +81,13 @@ class Settings { public static $option_footer_content = 'tec-tickets-emails-footer-content'; /** - * The option key for the email footer credit. + * Variable to hold template object. * - * @since 5.5.6 + * @since 5.5.7 * - * @var string + * @var null|Tribe__Template */ - public static $option_footer_credit = 'tec-tickets-emails-footer-credit'; + private $template; /** * Gets the template instance used to setup the rendering html. @@ -299,17 +299,17 @@ public function email_styling_fields( array $fields ): array { 'type' => 'color', 'label' => esc_html__( 'Ticket Color', 'event-tickets' ), 'size' => 'medium', - 'default' => '#ffffff', + 'default' => '#007363', 'validation_callback' => 'is_string', 'validation_type' => 'color', ], static::$option_footer_content => [ - 'type' => 'wysiwyg', - 'label' => esc_html__( 'Footer Content', 'event-tickets' ), - 'tooltip' => esc_html__( 'Add custom links and instructions to the bottom of your emails.', 'event-tickets' ), - 'default' => '', - 'validation_type' => 'html', - 'settings' => [ + 'type' => 'wysiwyg', + 'label' => esc_html__( 'Footer Content', 'event-tickets' ), + 'tooltip' => esc_html__( 'Add custom links and instructions to the bottom of your emails.', 'event-tickets' ), + 'default' => '', + 'validation_type' => 'html', + 'settings' => [ 'media_buttons' => false, 'quicktags' => false, 'editor_height' => 200, @@ -322,14 +322,7 @@ public function email_styling_fields( array $fields ): array { 'aligncenter', 'alignright', ], - ] - ], - static::$option_footer_credit => [ - 'type' => 'checkbox_bool', - 'label' => esc_html__( 'Footer Credit', 'event-tickets' ), - 'tooltip' => esc_html__( 'Include "Ticket powered by Event Tickets" in the footer', 'event-tickets' ), - 'default' => true, - 'validation_type' => 'boolean', + ], ], ]; diff --git a/src/Tribe/Admin/Notices.php b/src/Tribe/Admin/Notices.php index dcd502e2be..ce4a2a6376 100644 --- a/src/Tribe/Admin/Notices.php +++ b/src/Tribe/Admin/Notices.php @@ -1,5 +1,7 @@ maybe_display_rsvp_new_views_options_notice(); $this->maybe_display_classic_editor_ecp_recurring_tickets_notice(); $this->maybe_display_plus_commerce_notice(); + $this->maybe_display_unsupported_currency_notice(); } /** @@ -237,4 +240,34 @@ public function maybe_display_plus_commerce_notice() { tribe_notice( "event-tickets-plus-missing-{$provider}-support", $message, 'dismiss=1&type=warning' ); } } + + /** + * Display notices for unsupported currencies. + * + * @since 5.5.7 + * + * @return void + */ + public function maybe_display_unsupported_currency_notice() { + if ( Currency::is_current_currency_supported() ) { + return; + } + + $message = sprintf( + '

%1$s

%2$s

', + esc_html( Currency::$unsupported_currency['heading'] ), + esc_html( Currency::$unsupported_currency['message'] ) + ); + + $notice_symbol = Currency::$unsupported_currency['symbol']; + + tribe_notice( + "event-tickets-unsupported-currencies-{$notice_symbol}", + $message, + [ + 'dismiss' => true, + 'type' => 'warning', + ] + ); + } } diff --git a/src/Tribe/Commerce/Currency.php b/src/Tribe/Commerce/Currency.php index c67b909c9c..2fef5ff719 100644 --- a/src/Tribe/Commerce/Currency.php +++ b/src/Tribe/Commerce/Currency.php @@ -447,7 +447,7 @@ public function get_provider_symbol( $provider, $object_id = null ) { return edd_currency_symbol(); } - if ( 'TEC\Tickets\Commerce\Module' === $provider && function_exists( 'tec_tickets_commerce_currency_symbol' ) ) { + if ( \TEC\Tickets\Commerce\Module::class === $provider && function_exists( 'tec_tickets_commerce_currency_symbol' ) ) { return tec_tickets_commerce_currency_symbol(); } @@ -529,7 +529,7 @@ public function get_provider_symbol_position( $provider, $object_id ) { return 'before' === $position ? 'prefix' : 'postfix'; } - if ( 'TEC\Tickets\Commerce\Module' === $provider && function_exists( 'tec_tickets_commerce_currency_position' ) ) { + if ( \TEC\Tickets\Commerce\Module::class === $provider && function_exists( 'tec_tickets_commerce_currency_position' ) ) { return tec_tickets_commerce_currency_position(); } @@ -639,6 +639,10 @@ public function get_currency_decimal_point( $provider = null ) { return edd_get_option( 'decimal_separator', '.' ); } + if ( \TEC\Tickets\Commerce\Module::class === $provider && function_exists( 'tec_tickets_commerce_currency_decimal_separator' ) ) { + return tec_tickets_commerce_currency_decimal_separator(); + } + return $this->get_currency_locale( 'decimal_point' ); } @@ -665,6 +669,10 @@ public function get_currency_thousands_sep( $provider = null ) { return edd_get_option( 'thousands_separator', '.' ); } + if ( \TEC\Tickets\Commerce\Module::class === $provider && function_exists( 'tec_tickets_commerce_currency_thousands_separator' ) ) { + return tec_tickets_commerce_currency_thousands_separator(); + } + return $this->get_currency_locale( 'thousands_sep' ); } @@ -700,6 +708,10 @@ public function get_number_of_decimals( $provider = null ) { return $decimals; } + if ( \TEC\Tickets\Commerce\Module::class === $provider && function_exists( 'tec_tickets_commerce_currency_number_of_decimals' ) ) { + return tec_tickets_commerce_currency_number_of_decimals(); + } + return $this->get_currency_number_of_decimals(); } diff --git a/src/Tribe/Main.php b/src/Tribe/Main.php index eeec27ec0d..2b20a011ba 100644 --- a/src/Tribe/Main.php +++ b/src/Tribe/Main.php @@ -8,7 +8,7 @@ class Tribe__Tickets__Main { /** * Current version of this plugin */ - const VERSION = '5.5.6'; + const VERSION = '5.5.7'; /** * Used to store the version history. diff --git a/src/Tribe/Metabox.php b/src/Tribe/Metabox.php index 3212ecc81e..89b3952b10 100644 --- a/src/Tribe/Metabox.php +++ b/src/Tribe/Metabox.php @@ -1,4 +1,5 @@ 400 ] + ); + } + wp_send_json_error( $output ); } /** @@ -206,11 +222,31 @@ public function ajax_ticket_add() { $data = wp_parse_args( tribe_get_request_var( array( 'data' ), array() ), array() ); if ( ! $this->has_permission( $post_id, $_POST, 'add_ticket_nonce' ) ) { - wp_send_json_error( esc_html( sprintf( __( 'Failed to add the %s. Refresh the page to try again.', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_add_error' ) ) ) ); + $output = esc_html( + /* Translators: %1$s - singular ticket term. */ + sprintf( __( 'Failed to add the %1$s. Refresh the page to try again.', 'event-tickets' ), + tribe_get_ticket_label_singular( 'ajax_ticket_add_error' ) ) + ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } if ( ! isset( $data['ticket_provider'] ) || ! $this->module_is_valid( $data['ticket_provider'] ) ) { - wp_send_json_error( esc_html__( 'Commerce Provider invalid', 'event-tickets' ) ); + $output = esc_html__( 'Commerce Provider invalid', 'event-tickets' ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } // Get the Provider @@ -236,20 +272,36 @@ public function ajax_ticket_add() { */ do_action( 'tribe_tickets_ticket_added', $post_id ); } else { - wp_send_json_error( esc_html( sprintf( __( 'Failed to add the %s', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_add_error' ) ) ) ); + $output = esc_html( + /* Translators: %1$s - Singular ticket term. */ + sprintf( __( 'Failed to add the %1$s', 'event-tickets' ), + tribe_get_ticket_label_singular( 'ajax_ticket_add_error' ) ) + ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } - $return = $this->get_panels( $post_id ); + $return = $this->get_panels( $post_id ); $return['notice'] = $this->notice( 'ticket-add' ); /** * Filters the return data for ticket add * - * @param array $return Array of data to return to the ajax call - * @param int $post_id ID of parent "event" post + * @param array $return Array of data to return to the ajax call + * @param int $post_id ID of parent "event" post */ $return = apply_filters( 'event_tickets_ajax_ticket_add_data', $return, $post_id ); + if ( $return_value ) { + return $return; + } + wp_send_json_success( $return ); } @@ -259,28 +311,69 @@ public function ajax_ticket_add() { * @since 4.6.2 * @since 4.10.9 Use customizable ticket name functions. * @since 4.12.3 Update detecting ticket provider to account for possibly inactive provider. Remove unused vars. + * @since 5.5.7 Added optional parameter to return values instead of echoing directly. + * + * @param bool $return_value Optional, flags whether to JSON output directly or return results. + * + * @return void|WP_Error|array The results depending on $return_value param, WP_Error if something went wrong. */ - public function ajax_ticket_edit() { - $post_id = absint( tribe_get_request_var( 'post_id', 0 ) ); + public function ajax_ticket_edit( $return_value = false ) { + $return_value = (bool) $return_value; + $post_id = absint( tribe_get_request_var( 'post_id', 0 ) ); + $post_id = Event::filter_event_id( $post_id ); if ( ! $post_id ) { - wp_send_json_error( esc_html__( 'Invalid parent Post', 'event-tickets' ) ); + $output = esc_html__( 'Invalid parent Post', 'event-tickets' ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } $ticket_id = absint( tribe_get_request_var( 'ticket_id', 0 ) ); if ( ! $ticket_id ) { - wp_send_json_error( esc_html( sprintf( __( 'Invalid %s', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_edit_error' ) ) ) ); + /* Translators: %1$s - singular ticket term. */ + $output = esc_html( sprintf( __( 'Invalid %1$s', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_edit_error' ) ) ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } if ( ! $this->has_permission( $post_id, $_POST, 'edit_ticket_nonce' ) ) { - wp_send_json_error( esc_html( sprintf( __( 'Failed to edit the %s. Refresh the page to try again.', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_edit_error' ) ) ) ); + /* Translators: %1$s - singular ticket term. */ + $output = esc_html( sprintf( __( 'Failed to edit the %1$s. Refresh the page to try again.', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_edit_error' ) ) ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } $provider = tribe_tickets_get_ticket_provider( $ticket_id ); if ( empty( $provider ) ) { - wp_send_json_error( esc_html__( 'Commerce Module invalid', 'event-tickets' ) ); + $output = esc_html__( 'Commerce Module invalid', 'event-tickets' ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } $return = $this->get_panels( $post_id, $ticket_id ); @@ -289,12 +382,16 @@ public function ajax_ticket_edit() { * Provides an opportunity for final adjustments to the data used to populate * the edit-ticket form. * - * @param array $return Data for the JSON response - * @param int $post_id Post ID - * @param int $ticket_id Ticket ID + * @param array $return Data for the JSON response + * @param int $post_id Post ID + * @param int $ticket_id Ticket ID */ $return = (array) apply_filters( 'tribe_events_tickets_ajax_ticket_edit', $return, $post_id, $ticket_id ); + if ( $return_value ) { + return $return; + } + wp_send_json_success( $return ); } @@ -302,29 +399,70 @@ public function ajax_ticket_edit() { * Sanitizes the data for the delete ticket ajax call, and calls the child delete_ticket * function. * - * @since 4.6.2 + * @since 4.6.2 + * @since 5.5.7 Added optional parameter to return values instead of echoing directly. + * + * @param bool $return_value Optional, flags whether to JSON output directly or return results. + * + * @return void|WP_Error|array The results depending on $return_value param, WP_Error if something went wrong. */ - public function ajax_ticket_delete() { - $post_id = absint( tribe_get_request_var( 'post_id', 0 ) ); + public function ajax_ticket_delete( $return_value = false ) { + $return_value = (bool) $return_value; + $post_id = absint( tribe_get_request_var( 'post_id', 0 ) ); + $post_id = Event::filter_event_id( $post_id ); if ( ! $post_id ) { - wp_send_json_error( esc_html__( 'Invalid parent Post', 'event-tickets' ) ); + $output = esc_html__( 'Invalid parent Post', 'event-tickets' ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } $ticket_id = absint( tribe_get_request_var( 'ticket_id', 0 ) ); if ( ! $ticket_id ) { - wp_send_json_error( esc_html( sprintf( __( 'Invalid %s', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_delete_error' ) ) ) ); + /* Translators: %1$s - singular ticket term */ + $output = esc_html( sprintf( __( 'Invalid %1$s', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_delete_error' ) ) ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } if ( ! $this->has_permission( $post_id, $_POST, 'remove_ticket_nonce' ) ) { - wp_send_json_error( esc_html( sprintf( __( 'Failed to delete the %s. Refresh the page to try again.', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_delete_error' ) ) ) ); + /* Translators: %1$s - singular ticket term */ + $output = esc_html( sprintf( __( 'Failed to delete the %1$s. Refresh the page to try again.', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_delete_error' ) ) ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } $provider = tribe_tickets_get_ticket_provider( $ticket_id ); if ( empty( $provider ) ) { - wp_send_json_error( esc_html__( 'Commerce Module invalid', 'event-tickets' ) ); + $output = esc_html__( 'Commerce Module invalid', 'event-tickets' ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } // Pass the control to the child object @@ -343,37 +481,71 @@ public function ajax_ticket_delete() { do_action( 'tribe_tickets_ticket_deleted', $post_id ); } + if ( $return_value ) { + return $return; + } wp_send_json_success( $return ); } /** * Sanitizes the data for the duplicate ticket ajax call, then duplicates the ticket and meta. * - * @since 5.2.3. + * @since 5.2.3. + * @since 5.5.7 Added optional parameter to return values instead of echoing directly. + * + * @param bool $return_value Optional, flags whether to JSON output directly or return results. + * + * @return void|WP_Error|array The results depending on $return_value param, WP_Error if something went wrong. */ - public function ajax_ticket_duplicate() { - $post_id = absint( tribe_get_request_var( 'post_id', 0 ) ); + public function ajax_ticket_duplicate( $return_value = false ) { + $return_value = (bool) $return_value; + $post_id = absint( tribe_get_request_var( 'post_id', 0 ) ); + $post_id = Event::filter_event_id( $post_id ); if ( ! $post_id ) { - wp_send_json_error( esc_html__( 'Invalid parent Post', 'event-tickets' ) ); + $output = esc_html__( 'Invalid parent Post', 'event-tickets' ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } $ticket_id = absint( tribe_get_request_var( 'ticket_id', 0 ) ); if ( ! $ticket_id ) { - wp_send_json_error( esc_html( sprintf( - // Translators: %s: dynamic "ticket" text. + $output = esc_html( sprintf( + // Translators: %s: dynamic "ticket" text. __( 'Invalid %s', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_duplicate_error' ) - ) ) ); + ) ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } if ( ! $this->has_permission( $post_id, $_POST, 'duplicate_ticket_nonce' ) ) { - wp_send_json_error( esc_html( sprintf( - // Translators: %s: dynamic "ticket" text. + $output = esc_html( sprintf( + // Translators: %s: dynamic "ticket" text. __( 'Failed to duplicate the %s. Refresh the page to try again.', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_duplicate_error' ) - ) ) ); + ) ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } $provider = tribe_tickets_get_ticket_provider( $ticket_id ); @@ -397,10 +569,19 @@ public function ajax_ticket_duplicate() { */ do_action( 'tribe_tickets_ticket_added', $post_id ); } else { - wp_send_json_error( esc_html( sprintf( __( 'Failed to duplicate the %s', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_duplicate_error' ) ) ) ); + /* Translators: %1$s - singular ticket term */ + $output = esc_html( sprintf( __( 'Failed to duplicate the %1$s', 'event-tickets' ), tribe_get_ticket_label_singular( 'ajax_ticket_duplicate_error' ) ) ); + if ( $return_value ) { + return new WP_Error( + 'bad_request', + $output, + [ 'status' => 400 ] + ); + } + wp_send_json_error( $output ); } - $return = $this->get_panels( $post_id ); + $return = $this->get_panels( $post_id ); $return['notice'] = $this->notice( 'ticket-duplicate' ); /** @@ -413,6 +594,10 @@ public function ajax_ticket_duplicate() { */ $return = apply_filters( 'event_tickets_ajax_ticket_duplicate_data', $return, $post_id ); + if ( $return_value ) { + return $return; + } + wp_send_json_success( $return ); } diff --git a/src/resources/icons/link.svg b/src/resources/icons/link.svg new file mode 100644 index 0000000000..5aa9776366 --- /dev/null +++ b/src/resources/icons/link.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/resources/icons/map-pin.svg b/src/resources/icons/map-pin.svg new file mode 100644 index 0000000000..22764ee63d --- /dev/null +++ b/src/resources/icons/map-pin.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/resources/icons/phone.svg b/src/resources/icons/phone.svg new file mode 100644 index 0000000000..77c72c29e2 --- /dev/null +++ b/src/resources/icons/phone.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/resources/images/example-event-image.png b/src/resources/images/example-event-image.png new file mode 100644 index 0000000000..9df73fa88c Binary files /dev/null and b/src/resources/images/example-event-image.png differ diff --git a/src/resources/js/admin/tickets-emails.js b/src/resources/js/admin/tickets-emails.js new file mode 100644 index 0000000000..ff7be93fbd --- /dev/null +++ b/src/resources/js/admin/tickets-emails.js @@ -0,0 +1,182 @@ +/** + * Makes sure we have all the required levels on the Tribe Object + * + * @since 5.5.7 + * @type {object} + */ +tribe.tickets = tribe.tickets || {}; +tribe.dialogs = tribe.dialogs || {}; +tribe.dialogs.events = tribe.dialogs.events || {}; + +/** + * Configures ET emails Object in the Global Tribe variable + * + * @since 5.5.7 + * @type {object} + */ +tribe.tickets.emails = {}; + +/** + * Initializes in a Strict env the code that manages the plugin Emails library. + * + * @since 5.5.7 + * @param {object} $ jQuery + * @param {object} obj tribe.tickets.emails + * @return {void} + */ +( function( $, obj ) { + const $document = $( document ); + + /* + * Manual Attendees Selectors. + * + * @since 5.5.7 + */ + obj.selectors = { + modalWrapper: '.tribe-modal__wrapper--emails-preview', + modalTitle: '.tribe-modal__title', + modalContent: '.tribe-modal__content', + form: '.tribe-tickets__manual-attendees-form', + hiddenElement: '.tribe-common-a11y-hidden', + validationNotice: '.tribe-tickets__notice--error', + formTicketBgColorName: 'tec-tickets-emails-ticket-bg-color', + formHeaderBgColorName: 'tec-tickets-emails-header-bg-color', + }; + + /** + * Handler for when the modal is being "closed". + * + * @since 5.5.7 + * @param {object} event The close event. + * @param {object} dialogEl The dialog element. + * @return {void} + */ + obj.modalClose = function( event, dialogEl ) { + const $modal = $( dialogEl ); + const $modalContent = $modal.find( obj.selectors.modalContent ); + + obj.unbindModalEvents( $modalContent ); + }; + + /** + * Bind handler for when the modal is being "closed". + * + * @since 5.5.7 + * @return {void} + */ + obj.bindModalClose = function() { + $( tribe.dialogs.events ).on( + 'tribeDialogCloseEmailsPreviewModal.tribeTickets', + obj.modalClose, + ); + }; + + /** + * Unbinds events for the modal content container. + * + * @since 5.5.7 + * @param {jQuery} $container jQuery object of the container. + */ + obj.unbindModalEvents = function( $container ) { + $container.off( 'afterAjaxSuccess.tribeTicketsAdmin', obj.bindModalEvents ); + $container.off(); + }; + + /** + * Handler for when the modal is opened. + * + * @since 5.5.7 + * @param {object} event The show event. + * @param {object} dialogEl The dialog element. + * @param {object} trigger The event. + * @return {void} + */ + obj.modalOpen = function( event, dialogEl, trigger ) { + const $modal = $( dialogEl ); + const $trigger = $( trigger.target ).closest( 'button' ); + const title = $trigger.data( 'modal-title' ); + const request = 'tec_tickets_preview_email'; + + if ( title ) { + const $modalTitle = $modal.find( obj.selectors.modalTitle ); + $modalTitle.html( title ); + } + + // And replace the content. + const $modalContent = $modal.find( obj.selectors.modalContent ); + const requestData = { + action: 'tribe_tickets_admin_manager', + request: request, + }; + + const contextData = obj.getSettingsContext(); + + const data = { + ...requestData, + ...contextData, + }; + + tribe.tickets.admin.manager.request( data, $modalContent ); + + // Bind the modal events after AJAX success. + $modalContent.on( + 'afterAjaxSuccess.tribeTicketsAdmin', + { container: $modalContent, requestData: data }, + obj.bindModalEvents, + ); + }; + + /** + * Get context to send on the request. + * + * @since 5.5.7 + * @return {object} + */ + obj.getSettingsContext = function() { + const context = {}; + // @todo @juanfra: Get individual email settings and send them as context (once we have the settings per page). + // Get email. + // get colors and image. + // Get alignment. + + // @todo @juanfra: check if the elements are found in the DOM. + const ticketBgColor = $document + .find( 'input[name=' + obj.selectors.formTicketBgColorName + ']' ).val(); + + context.ticketBgColor = ticketBgColor; + + const headerBgColor = $document + .find( 'input[name=' + obj.selectors.formHeaderBgColorName + ']' ).val(); + + context.headerBgColor = headerBgColor; + + return context; + }; + + /** + * Bind handler for when the modal is being "opened". + * + * @since 5.5.7 + * @return {void} + */ + obj.bindModalOpen = function() { + $( tribe.dialogs.events ).on( + 'tribeDialogShowEmailsPreviewModal.tribeTickets', + obj.modalOpen, + ); + }; + + /** + * Handles the initialization of the scripts when Document is ready. + * + * @since 5.5.7 + * @return {void} + */ + obj.ready = function() { + obj.bindModalOpen(); + obj.bindModalClose(); + }; + + // Configure on document ready. + $document.ready( obj.ready ); +} )( jQuery, tribe.tickets.emails ); diff --git a/src/resources/postcss/tickets-admin-settings.pcss b/src/resources/postcss/tickets-admin-settings.pcss index e8fd2b9383..2428d46dca 100644 --- a/src/resources/postcss/tickets-admin-settings.pcss +++ b/src/resources/postcss/tickets-admin-settings.pcss @@ -7,7 +7,3 @@ @import 'tickets-common.pcss'; @import 'tickets-admin/settings/_all.pcss'; -/* @todo: Check this, see if it goes to common or where should we place it. */ -.tribe-settings-form-wrap h3 { - width: 100%; -} diff --git a/src/resources/postcss/tickets-admin/settings/_emails.pcss b/src/resources/postcss/tickets-admin/settings/_emails.pcss index b59539d325..acf86427c9 100644 --- a/src/resources/postcss/tickets-admin/settings/_emails.pcss +++ b/src/resources/postcss/tickets-admin/settings/_emails.pcss @@ -85,3 +85,57 @@ color: var(--tec-color-icon-primary-alt); } } + +.button.tec-tickets__admin-settings-emails-preview-button { + margin-left: var(--tec-spacer-2); +} + +.event-tickets, +.tribe-common { + + body.tickets_page_tec-tickets-settings & { + div.tribe-dialog { + z-index: 99999; /* Fix for the WP admin bar. */ + } + } + + /* + Emails Preview modal specific styles + */ + .tribe-dialog__wrapper.tribe-modal__wrapper--emails-preview { + background-color: var(--tec-color-background); + border-radius: 0; + height: 100%; + max-width: 100vw; + min-height: 350px; + padding: 0; + + @media (--viewport-medium) { + border-radius: var(--tec-border-radius-default); + height: auto; + } + + div[role="document"] { + min-height: 350px; + } + + .tribe-common-c-loader { + padding-top: initial; + } + + .tribe-modal__close-button { + right: var(--tec-spacer-4); + top: var(--tec-spacer-5); + + @media (--viewport-medium) { + top: var(--tec-spacer-4); + } + } + + .tribe-modal__title--emails-preview { + align-self: center; + margin: 0 0 var(--tec-spacer-2); + padding-top: var(--tec-spacer-3); + } + } +} diff --git a/src/template-tags/commerce.php b/src/template-tags/commerce.php index f4650d48fa..05b8d7aacc 100644 --- a/src/template-tags/commerce.php +++ b/src/template-tags/commerce.php @@ -47,3 +47,36 @@ function tec_tickets_commerce_currency_symbol() { function tec_tickets_commerce_currency_position() { return Currency::get_currency_symbol_position( tec_tickets_commerce_currency_code() ); } + +/** + * Returns the Tickets Commerce currency decimal point separator. + * + * @since 5.5.7 + * + * @return string String containing the Tickets Commerce currency decimal point separator. + */ +function tec_tickets_commerce_currency_decimal_separator() : string { + return Currency::get_currency_separator_decimal( tec_tickets_commerce_currency_code() ); +} + +/** + * Returns the Tickets Commerce currency thousands separator. + * + * @since 5.5.7 + * + * @return string String containing the Tickets Commerce currency thousands separator. + */ +function tec_tickets_commerce_currency_thousands_separator() : string { + return Currency::get_currency_separator_thousands( tec_tickets_commerce_currency_code() ); +} + +/** + * Returns the Tickets Commerce currency number of decimals. + * + * @since 5.5.7 + * + * @return int Number of decimals for the Tickets Commerce currency. + */ +function tec_tickets_commerce_currency_number_of_decimals() : int { + return Currency::get_currency_precision( tec_tickets_commerce_currency_code() ); +} diff --git a/src/views/v2/emails/email-template.php b/src/views/v2/emails/email-template.php new file mode 100644 index 0000000000..c3ef2cc347 --- /dev/null +++ b/src/views/v2/emails/email-template.php @@ -0,0 +1,12 @@ +template( 'email-template/preview' ); +$this->template( 'email-template/main' ); + diff --git a/src/views/v2/emails/email-template/body.php b/src/views/v2/emails/email-template/body.php new file mode 100644 index 0000000000..a2e186a0c3 --- /dev/null +++ b/src/views/v2/emails/email-template/body.php @@ -0,0 +1,40 @@ + + + + template( 'email-template/body/top-link' ); ?> + + + + + + + +
+ + template( 'email-template/body/header' ); ?> + + + + template( 'email-template/body/footer' ); ?> +
+ + template( 'email-template/body/greeting' ); ?> + template( 'email-template/body/date' ); ?> + template( 'email-template/body/event-title' ); ?> + template( 'email-template/body/event-image' ); ?> + template( 'email-template/body/ticket-info' ); ?> + template( 'email-template/body/event-location' ); ?> + template( 'email-template/body/add-links' ); ?> +
+
+
 
diff --git a/src/views/v2/emails/email-template/body/add-links.php b/src/views/v2/emails/email-template/body/add-links.php new file mode 100644 index 0000000000..6f3fff91b0 --- /dev/null +++ b/src/views/v2/emails/email-template/body/add-links.php @@ -0,0 +1,27 @@ + + + + + + + + +
+ + + + + + + +
+ + diff --git a/src/views/v2/emails/email-template/body/date.php b/src/views/v2/emails/email-template/body/date.php new file mode 100644 index 0000000000..43de5d13dc --- /dev/null +++ b/src/views/v2/emails/email-template/body/date.php @@ -0,0 +1,20 @@ + + + +

+ +

+ + diff --git a/src/views/v2/emails/email-template/body/event-description.php b/src/views/v2/emails/email-template/body/event-description.php new file mode 100644 index 0000000000..ca74d2cdc8 --- /dev/null +++ b/src/views/v2/emails/email-template/body/event-description.php @@ -0,0 +1,19 @@ + + + + + + diff --git a/src/views/v2/emails/email-template/body/event-image.php b/src/views/v2/emails/email-template/body/event-image.php new file mode 100644 index 0000000000..db3c4fb4bd --- /dev/null +++ b/src/views/v2/emails/email-template/body/event-image.php @@ -0,0 +1,18 @@ + + + + + + diff --git a/src/views/v2/emails/email-template/body/event-location.php b/src/views/v2/emails/email-template/body/event-location.php new file mode 100644 index 0000000000..2814847e7a --- /dev/null +++ b/src/views/v2/emails/email-template/body/event-location.php @@ -0,0 +1,72 @@ + + + +

+ +

+ + + + +

+ +

+ + + + + +
+ + + + + +
+ + +
+
+ +
+
+ + + + + +
+ + + +
+ + + + + +
+ + + + + +
+
+ + diff --git a/src/views/v2/emails/email-template/body/event-title.php b/src/views/v2/emails/email-template/body/event-title.php new file mode 100644 index 0000000000..621dd065a1 --- /dev/null +++ b/src/views/v2/emails/email-template/body/event-title.php @@ -0,0 +1,18 @@ + + + + + + diff --git a/src/views/v2/emails/email-template/body/footer-content.php b/src/views/v2/emails/email-template/body/footer-content.php new file mode 100644 index 0000000000..1fd9d6dee4 --- /dev/null +++ b/src/views/v2/emails/email-template/body/footer-content.php @@ -0,0 +1,20 @@ + + + + + + diff --git a/src/views/v2/emails/email-template/body/footer-credit.php b/src/views/v2/emails/email-template/body/footer-credit.php new file mode 100644 index 0000000000..d570f92be4 --- /dev/null +++ b/src/views/v2/emails/email-template/body/footer-credit.php @@ -0,0 +1,32 @@ +%s', + '#', // @todo Update link to ET. + esc_attr( $header_text_color ), + esc_html__( 'Event Tickets', 'event-tickets' ) +); +$credit_html = sprintf( + // Translators: %s - HTML link to `Event Tickets` website. + __( 'Ticket powered by %s', 'event-tickets' ), + $et_link +); + +?> + + + + + diff --git a/src/views/v2/emails/email-template/body/footer.php b/src/views/v2/emails/email-template/body/footer.php new file mode 100644 index 0000000000..fc42de6892 --- /dev/null +++ b/src/views/v2/emails/email-template/body/footer.php @@ -0,0 +1,25 @@ + + + + + template( 'email-template/body/footer-content' ); ?> + template( 'email-template/body/footer-credit' ); ?> +
+ + diff --git a/src/views/v2/emails/email-template/body/greeting.php b/src/views/v2/emails/email-template/body/greeting.php new file mode 100644 index 0000000000..696ea3e6b3 --- /dev/null +++ b/src/views/v2/emails/email-template/body/greeting.php @@ -0,0 +1,25 @@ + + + +

+ +

+ + diff --git a/src/views/v2/emails/email-template/body/header-image.php b/src/views/v2/emails/email-template/body/header-image.php new file mode 100644 index 0000000000..0730fdf5ee --- /dev/null +++ b/src/views/v2/emails/email-template/body/header-image.php @@ -0,0 +1,14 @@ + + diff --git a/src/views/v2/emails/email-template/body/header.php b/src/views/v2/emails/email-template/body/header.php new file mode 100644 index 0000000000..1050a9fdd3 --- /dev/null +++ b/src/views/v2/emails/email-template/body/header.php @@ -0,0 +1,19 @@ + + + + template( 'email-template/body/header-image' ); ?> + + diff --git a/src/views/v2/emails/email-template/body/recipient-name.php b/src/views/v2/emails/email-template/body/recipient-name.php new file mode 100644 index 0000000000..bf53d90b32 --- /dev/null +++ b/src/views/v2/emails/email-template/body/recipient-name.php @@ -0,0 +1,16 @@ + +

+ + +

diff --git a/src/views/v2/emails/email-template/body/ticket-info.php b/src/views/v2/emails/email-template/body/ticket-info.php new file mode 100644 index 0000000000..593606aaab --- /dev/null +++ b/src/views/v2/emails/email-template/body/ticket-info.php @@ -0,0 +1,24 @@ + + + + template( 'email-template/body/recipient-name' ); ?> +

+ +

+

+ +

+ + diff --git a/src/views/v2/emails/email-template/body/top-link.php b/src/views/v2/emails/email-template/body/top-link.php new file mode 100644 index 0000000000..1a58076122 --- /dev/null +++ b/src/views/v2/emails/email-template/body/top-link.php @@ -0,0 +1,18 @@ + + + %s', + esc_html__( 'Having trouble viewing this email?', 'event-tickets' ), + esc_html__( 'Click here', 'event-tickets' ), + ); + ?> + diff --git a/src/views/v2/emails/email-template/main.php b/src/views/v2/emails/email-template/main.php new file mode 100644 index 0000000000..9bfa5907f9 --- /dev/null +++ b/src/views/v2/emails/email-template/main.php @@ -0,0 +1,37 @@ + + + + + + + + + template( 'email-template/style' ); ?> + + + template( 'email-template/body' ); ?> + + diff --git a/src/views/v2/emails/email-template/preview.php b/src/views/v2/emails/email-template/preview.php new file mode 100644 index 0000000000..2bd8e80d7b --- /dev/null +++ b/src/views/v2/emails/email-template/preview.php @@ -0,0 +1,20 @@ + +
+ template( 'email-template/style' ); ?> + template( 'email-template/body' ); ?> +
diff --git a/src/views/v2/emails/email-template/style.php b/src/views/v2/emails/email-template/style.php new file mode 100644 index 0000000000..04a17ddc54 --- /dev/null +++ b/src/views/v2/emails/email-template/style.php @@ -0,0 +1,12 @@ + + diff --git a/tests/_support/Traits/CT1/CT1_Fixtures.php b/tests/_support/Traits/CT1/CT1_Fixtures.php index 04c3c30cd9..89b1593c3e 100644 --- a/tests/_support/Traits/CT1/CT1_Fixtures.php +++ b/tests/_support/Traits/CT1/CT1_Fixtures.php @@ -9,7 +9,6 @@ use TEC\Events\Custom_Tables\V1\Models\Event; use TEC\Events\Custom_Tables\V1\Models\Event as Event_Model; use TEC\Events\Custom_Tables\V1\Models\Occurrence; -use TEC\Events\Custom_Tables\V1\Models\Occurrence as Occurrence_Model; use TEC\Events\Custom_Tables\V1\Tables\Events as EventsSchema; use TEC\Events\Custom_Tables\V1\Tables\Occurrences as OccurrencesSchema; use Tribe__Date_Utils as Dates; @@ -18,6 +17,48 @@ use TEC\Events\Custom_Tables\V1\Schema_Builder\Schema_Builder; trait CT1_Fixtures { + + /** + * @return int + */ + public function get_provisional_id_base() { + return 100000000; + } + + /** + * Hook callback to normalize provisional IDs. + * + * @param mixed $id + * + * @return mixed + */ + public function faux_provisional_id_filter( $id ) { + $base = $this->get_provisional_id_base(); + if ( is_numeric( $id ) && $id > $base ) { + $occurrence_id = $id - $base; + $occurrence = Occurrence::find( $occurrence_id ); + + return $occurrence instanceof Occurrence ? $occurrence->post_id : $id; + } + + return $id; + } + + /** + * Sets up core hook that mimics what ECP does to normalize provisional ID's to the post ID. + */ + public function enable_provisional_id_normalizer() { + // Faux provisional ID cleaner upper. + add_filter( 'tec_events_custom_tables_v1_normalize_occurrence_id', [ $this, 'faux_provisional_id_filter' ] ); + } + + /** + * Removes hook that was normalizing provisional IDs. + */ + public function disable_provisional_id_normalizer() { + remove_filter( 'tec_events_custom_tables_v1_normalize_occurrence_id', [ $this, 'faux_provisional_id_filter' ] ); + } + /** * Utility to generate reports with various criteria. * @@ -109,15 +150,15 @@ private function given_a_non_migrated_single_event( $override_event_args = [] ): 'post_status' => 'publish', ]; - $post_id = ( new \WP_UnitTest_Factory_For_Post() )->create( array_merge( $event_args, $override_event_args ) ); + $post_id = ( new \WP_UnitTest_Factory_For_Post() )->create( array_merge( $event_args, $override_event_args ) ); // Make sure no models are present in the custom tables for it. - Occurrence_Model::where( 'post_id', '=', $post_id ) - ->delete(); + Occurrence::where( 'post_id', '=', $post_id ) + ->delete(); Event_Model::where( 'post_id', '=', $post_id ) ->delete(); $this->assertNull( Event_Model::find( $post_id, 'post_id' ) ); - $this->assertNull( Occurrence_Model::find( $post_id, 'post_id' ) ); + $this->assertNull( Occurrence::find( $post_id, 'post_id' ) ); // Just in case, remove any recurrence meta there might be. delete_post_meta( $post_id, '_tribe_blocks_recurrence_rules' ); delete_post_meta( $post_id, '_tribe_blocks_recurrence_exclusions' ); @@ -159,7 +200,7 @@ private function assert_custom_tables_exist() { } } - private function assert_custom_tables_not_exist(){ + private function assert_custom_tables_not_exist() { $schema_builder = tribe()->make( Schema_Builder::class ); foreach ( $schema_builder->get_registered_table_schemas() as $table_schema ) { $this->assertFalse( $table_schema->exists() ); @@ -184,7 +225,7 @@ private function given_the_initialization_transient_expired() { delete_transient( Activation::ACTIVATION_TRANSIENT ); } - private function given_a_migrated_single_event(){ + private function given_a_migrated_single_event() { $post = $this->given_a_non_migrated_single_event(); Event::upsert( [ 'post_id' ], Event::data_from_post( $post ) ); $event = Event::find( $post->ID, 'post_id' ); diff --git a/tests/commerce_integration/TEC/Tickets/Attendees_ListTest.php b/tests/commerce_integration/TEC/Tickets/Attendees_ListTest.php new file mode 100644 index 0000000000..fdd138ba23 --- /dev/null +++ b/tests/commerce_integration/TEC/Tickets/Attendees_ListTest.php @@ -0,0 +1,91 @@ +factory()->post->create(); + + $rsvp_ticket_id = $this->create_rsvp_ticket( $post_id ); + $attendees = $this->create_many_attendees_for_ticket( 5, $rsvp_ticket_id, $post_id ); + + /** @var \Tribe\Tickets\Events\Attendees_List $attendees_list */ + $attendees_list = tribe( 'tickets.events.attendees-list' ); + + $this->assertEquals( count($attendees), $attendees_list->get_attendance_counts( $post_id ) ); + } + + /** + * @test + * + * @covers \Tribe\Tickets\Events\Attendees_List::get_attendance_counts + */ + public function test_get_attendance_count_for_tickets_commerce_attendees() { + $post_id = $this->factory()->post->create(); + + $tickets_commerce_ticket_id = $this->create_tc_ticket( $post_id ); + $attendees = $this->create_many_attendees_for_ticket( 5, $tickets_commerce_ticket_id, $post_id ); + + /** @var \Tribe\Tickets\Events\Attendees_List $attendees_list */ + $attendees_list = tribe( 'tickets.events.attendees-list' ); + + $this->assertEquals( count($attendees), $attendees_list->get_attendance_counts( $post_id ) ); + } + + /** + * @test + * + * @covers \Tribe\Tickets\Events\Attendees_List::get_attendance_counts + */ + public function test_get_attendance_count_for_both_rsvp_and_tickets_commerce_attendees() { + $post_id = $this->factory()->post->create(); + + $rsvp_ticket_id = $this->create_rsvp_ticket( $post_id ); + $tickets_commerce_ticket_id = $this->create_tc_ticket( $post_id ); + + $rsvp_attendees = $this->create_many_attendees_for_ticket( 16, $rsvp_ticket_id, $post_id ); + $ticket_attendees = $this->create_many_attendees_for_ticket( 5, $tickets_commerce_ticket_id, $post_id ); + + /** @var \Tribe\Tickets\Events\Attendees_List $attendees_list */ + $attendees_list = tribe( 'tickets.events.attendees-list' ); + + $total_attendees = count( $rsvp_attendees ) + count( $ticket_attendees ); + $this->assertEquals( $total_attendees, $attendees_list->get_attendance_counts( $post_id ) ); + } +} \ No newline at end of file diff --git a/tests/commerce_integration/TEC/Tickets/Commerce/Settings/Payments/Currency/FormatTest.php b/tests/commerce_integration/TEC/Tickets/Commerce/Settings/Payments/Currency/FormatTest.php new file mode 100644 index 0000000000..c871806702 --- /dev/null +++ b/tests/commerce_integration/TEC/Tickets/Commerce/Settings/Payments/Currency/FormatTest.php @@ -0,0 +1,80 @@ +assertEquals( Currency::$currency_code_fallback, $default_currency ); + $this->assertEquals( Currency::$currency_code_fallback_symbol, tec_tickets_commerce_currency_symbol() ); + $this->assertEquals( Currency::$currency_code_thousands_separator, tec_tickets_commerce_currency_thousands_separator() ); + $this->assertEquals( Currency::$currency_code_decimal_separator, tec_tickets_commerce_currency_decimal_separator() ); + $this->assertEquals( Currency::$currency_code_number_of_decimals, tec_tickets_commerce_currency_number_of_decimals() ); + } + + /** + * @test + */ + public function test_default_currency_format_is_correct() { + $formatted_amount = \TEC\Tickets\Commerce\Utils\Value::create( 1000 )->get_currency(); + $this->assertEquals( '$1,000.00', $formatted_amount ); + } + + /** + * @test + */ + public function test_changing_currency_symbol_is_working() { + tribe_update_option( Settings::$option_currency_code, 'EUR' ); + $formatted_amount = \TEC\Tickets\Commerce\Utils\Value::create( 1000 )->get_currency(); + $this->assertEquals( '€1.000,00', $formatted_amount ); + } + + /** + * @test + */ + public function test_changing_currency_decimal_separator_is_working() { + tribe_update_option( Settings::$option_currency_decimal_separator, '--' ); + $formatted_amount = \TEC\Tickets\Commerce\Utils\Value::create( 1000 )->get_currency(); + $this->assertEquals( '€1.000--00', $formatted_amount ); + } + + /** + * @test + */ + public function test_changing_currency_thousands_separator_is_working() { + tribe_update_option( Settings::$option_currency_thousands_separator, '|' ); + $formatted_amount = \TEC\Tickets\Commerce\Utils\Value::create( 1000 )->get_currency(); + $this->assertEquals( '€1|000--00', $formatted_amount ); + } + + /** + * @test + */ + public function test_changing_number_of_decimals_is_working() { + tribe_update_option( Settings::$option_currency_number_of_decimals, 4 ); + $formatted_amount = \TEC\Tickets\Commerce\Utils\Value::create( 1000 )->get_currency(); + $this->assertEquals( '€1|000--0000', $formatted_amount ); + } + + /** + * @test + */ + public function test_changing_currency_symbol_position_is_working() { + tribe_update_option( Settings::$option_currency_position, 'postfix' ); + $formatted_amount = \TEC\Tickets\Commerce\Utils\Value::create( 1000 )->get_currency(); + $this->assertEquals( '1|000--0000€', $formatted_amount ); + } +} \ No newline at end of file diff --git a/tests/ct1_integration.suite.dist.yml b/tests/ct1_integration.suite.dist.yml index 985841dc34..ac096fd2dd 100644 --- a/tests/ct1_integration.suite.dist.yml +++ b/tests/ct1_integration.suite.dist.yml @@ -13,7 +13,7 @@ modules: dbPassword: "%WP_TEST_DB_PASSWORD%" tablePrefix: test_ domain: "%WP_DOMAIN%" - adminEmail: admin@%WP_DOMAIN% + adminEmail: admin@tribe.localhost title: 'Event Tickets Tests' plugins: - the-events-calendar/the-events-calendar.php diff --git a/tests/ct1_integration/Attendees_TableTest.php b/tests/ct1_integration/Attendees_TableTest.php index abe804c20f..3a6bd61efb 100644 --- a/tests/ct1_integration/Attendees_TableTest.php +++ b/tests/ct1_integration/Attendees_TableTest.php @@ -3,25 +3,30 @@ namespace Tribe\Tickets; use TEC\Events\Custom_Tables\V1\Models\Occurrence; -use TEC\Events\Custom_Tables\V1\Models\Occurrence as Occurrence_Model; use TEC\Tickets\Commerce\Cart; use TEC\Tickets\Commerce\Gateways\PayPal\Gateway; use TEC\Tickets\Commerce\Order; use TEC\Tickets\Commerce\Status\Pending; use Tribe\Tickets\Test\Commerce\Attendee_Maker; -use Tribe\Tickets\Test\Commerce\PayPal\Ticket_Maker as PayPal_Ticket_Maker; -use Tribe\Tickets\Test\Commerce\RSVP\Ticket_Maker as RSVP_Ticket_Maker; use Tribe\Tickets\Test\Commerce\TicketsCommerce\Ticket_Maker; use Tribe\Tickets\Test\Traits\CT1\CT1_Fixtures; -use Tribe__Tickets__Attendees; use Tribe__Tickets__Attendees_Table as Attendees_Table; -use Tribe__Tickets__Data_API as Data_API; class Attendees_TableTest extends \Codeception\TestCase\WPTestCase { use CT1_Fixtures; use Attendee_Maker; use Ticket_Maker; + public function _setUp() { + parent::_setUp(); + $this->enable_provisional_id_normalizer(); + } + + public function _tearDown() { + parent::_tearDown(); + $this->disable_provisional_id_normalizer(); + } + /** * @inheritDoc */ @@ -60,26 +65,13 @@ public function create_order_for_ticket( $ticket_id, $quantity = 5 ) { * @test */ public function should_allow_fetching_attendees_by_provisional_id() { - // Faux provisional ID cleaner upper. - $base = 100000000; - $faux_provisional_hook = static function ( $id ) use ( $base ) { - if ( is_numeric( $id ) && $id > $base ) { - $occurrence_id = $id - $base; - $occurrence = Occurrence::find( $occurrence_id ); - - return $occurrence instanceof Occurrence_Model ? $occurrence->post_id : $id; - } - - return $id; - }; - add_filter( 'tec_events_custom_tables_v1_normalize_occurrence_id', $faux_provisional_hook ); $post = $this->given_a_migrated_single_event(); $post_id = $post->ID; $quantity = 4; $occurrence = Occurrence::find_by_post_id( $post_id ); // Create a faux provisional id. - $provisional_id = $occurrence->occurrence_id + $base; + $provisional_id = $occurrence->occurrence_id + $this->get_provisional_id_base(); $ticket_a_id = $this->create_tc_ticket( $post_id, 10 ); $this->create_order_for_ticket( $ticket_a_id, $quantity ); diff --git a/tests/ct1_integration/MetaboxTest.php b/tests/ct1_integration/MetaboxTest.php new file mode 100644 index 0000000000..3227065020 --- /dev/null +++ b/tests/ct1_integration/MetaboxTest.php @@ -0,0 +1,131 @@ +ID ); + $this->enable_provisional_id_normalizer(); + } + + public function _tearDown() { + parent::_tearDown(); + $this->disable_provisional_id_normalizer(); + } + + public function given_an_event_with_ticket_request( $ticket_request, $nonce_action ) { + $post = $this->given_a_migrated_single_event(); + $post_id = $post->ID; + $occurrence = Occurrence::find_by_post_id( $post_id ); + add_filter( 'user_has_cap', function ( $allcaps, $caps ) { + $caps['edit_event_tickets'] = true; + $caps['edit_others_posts'] = true; + + return $caps; + }, 10, 2 ); + // Create a provisional ID. + $provisional_id = $occurrence->occurrence_id + $this->get_provisional_id_base(); + $nonce = wp_create_nonce( $nonce_action ); + $_POST = array_merge( + [ 'post_id' => $provisional_id, 'nonce' => $nonce ], + $ticket_request + ); + + return $post_id; + } + + /** + * It should allow creating ticket on page using provisional ID. + * + * @test + */ + public function should_ajax_ticket_add_with_provisional_id() { + + $this->given_an_event_with_ticket_request( [ + 'is_admin' => 'true', + 'action' => 'tribe-ticket-add', + 'data' => 'ticket_name=test&ticket_description=&ticket_show_description=1&ticket_start_date=&ticket_start_time=&ticket_end_date=&ticket_end_time=&ticket_provider=Tribe__Tickets__RSVP&tribe-ticket%5Bcapacity%5D=&ticket_id=&ticket_menu_order=undefined', + ], 'add_ticket_nonce' ); + + + $metabox = tribe( Tribe__Tickets__Metabox::class ); + $response = $metabox->ajax_ticket_add( true ); + + // Should create ticket with the provisional ID provided. + $this->assertIsArray( $response ); + } + + /** + * Should successfully locate and edit a ticket. + * + * @test + */ + public function should_ajax_ticket_edit_with_provisional_id() { + $post_id = $this->given_an_event_with_ticket_request( [ + 'is_admin' => 'true', + 'action' => 'tribe-ticket-edit', + 'data' => 'ticket_name=test&ticket_description=&ticket_show_description=1&ticket_start_date=&ticket_start_time=&ticket_end_date=&ticket_end_time=&ticket_provider=Tribe__Tickets__RSVP&tribe-ticket%5Bcapacity%5D=12&ticket_id=&ticket_menu_order=undefined', + ], 'edit_ticket_nonce' ); + $ticket_a_id = $this->create_rsvp_ticket( $post_id ); + $_POST['ticket_id'] = $ticket_a_id; + + $metabox = tribe( Tribe__Tickets__Metabox::class ); + $response = $metabox->ajax_ticket_edit( true ); + + // Should create ticket with the provisional ID provided. + $this->assertIsArray( $response ); + } + + /** + * Should successfully locate and remove a ticket. + * + * @test + */ + public function should_ajax_ticket_delete_with_provisional_id() { + $post_id = $this->given_an_event_with_ticket_request( [ + 'is_admin' => 'true', + 'action' => 'tribe-ticket-delete', + 'data' => 'ticket_name=test&ticket_description=&ticket_show_description=1&ticket_start_date=&ticket_start_time=&ticket_end_date=&ticket_end_time=&ticket_provider=Tribe__Tickets__RSVP&tribe-ticket%5Bcapacity%5D=12&ticket_id=&ticket_menu_order=undefined', + ], 'remove_ticket_nonce' ); + $ticket_a_id = $this->create_rsvp_ticket( $post_id ); + $_POST['ticket_id'] = $ticket_a_id; + + $metabox = tribe( Tribe__Tickets__Metabox::class ); + $response = $metabox->ajax_ticket_delete( true ); + + // Should create ticket with the provisional ID provided. + $this->assertIsArray( $response ); + } + + /** + * Should successfully locate and duplicate a ticket. + * + * @test + */ + public function should_ajax_ticket_duplicate_with_provisional_id() { + $post_id = $this->given_an_event_with_ticket_request( [ + 'is_admin' => 'true', + 'action' => 'tribe-ticket-duplicate', + 'data' => 'ticket_name=test&ticket_description=&ticket_show_description=1&ticket_start_date=&ticket_start_time=&ticket_end_date=&ticket_end_time=&ticket_provider=Tribe__Tickets__RSVP&tribe-ticket%5Bcapacity%5D=12&ticket_id=&ticket_menu_order=undefined', + ], 'duplicate_ticket_nonce' ); + $ticket_a_id = $this->create_rsvp_ticket( $post_id ); + $_POST['ticket_id'] = $ticket_a_id; + + $metabox = tribe( Tribe__Tickets__Metabox::class ); + $response = $metabox->ajax_ticket_duplicate( true ); + + // Should create ticket with the provisional ID provided. + $this->assertIsArray( $response ); + } +}