--- a/my-tickets/includes/data-utilities.php
+++ b/my-tickets/includes/data-utilities.php
@@ -369,6 +369,32 @@
}
/**
+ * Set receipt cookie after purchase.
+ *
+ * @param int $post_ID Payment post ID.
+ * @param string $receipt Receipt ID.
+ */
+function mt_set_receipt_cookie( $post_ID, $receipt = false ) {
+ $log_id = mt_get_payment_log_id( $post_ID );
+ $receipt = ( ! $receipt ) ? get_post_meta( $post_ID, '_receipt', true ) : $receipt;
+ $cookie_value = md5( $receipt . $log_id );
+ if ( version_compare( PHP_VERSION, '7.3.0', '>' ) ) {
+ // Fix syntax.
+ $options = array(
+ 'expires' => time() + 600,
+ 'path' => COOKIEPATH,
+ 'domain' => COOKIE_DOMAIN,
+ 'secure' => false,
+ 'httponly' => true,
+ 'samesite' => 'Lax',
+ );
+ setcookie( 'mt_purchase_receipt', $cookie_value, $options );
+ } else {
+ setcookie( 'mt_purchase_receipt', $cookie_value, time() + 600, COOKIEPATH, COOKIE_DOMAIN, false, true );
+ }
+}
+
+/**
* Generate a unique ID to track the current cart process.
*
* @return string
--- a/my-tickets/mt-cart.php
+++ b/my-tickets/mt-cart.php
@@ -769,14 +769,26 @@
$gateway = "<input type='hidden' name='mt_gateway' value='" . esc_attr( $current_gate ) . "' />";
$cart_page = mt_get_cart_url();
if ( is_array( $cart ) && ! empty( $cart ) && $count > 0 ) {
- $output = '
+ $text = ( 'offline' === $current_gate ) ? __( 'Review cart and confirm reservation', 'my-tickets' ) : __( 'Review cart and make payment', 'my-tickets' );
+ /**
+ * Filter the submit button text.
+ *
+ * @hook mt_submit_button_text
+ *
+ * @param {string} $text Submit button text.
+ * @param {string} $current_gate Active gateway.
+ *
+ * @return string
+ */
+ $submit_text = apply_filters( 'mt_submit_button_text', $text, $current_gate );
+ $output = '
<div class="mt_cart">
<div class="mt-response" aria-live="assertive"></div>
<form action="' . esc_url( $cart_page ) . '" method="POST">' . "
- <input class='screen-reader-text' type='submit' name='mt_submit' value='" . apply_filters( 'mt_submit_button_text', __( 'Review cart and make payment', 'my-tickets' ), $current_gate ) . "' />" . '
+ <input class='screen-reader-text' type='submit' name='mt_submit' value='" . esc_attr( $submit_text ) . "' />" . '
' . $nonce . '
' . $gateway;
- $output .= mt_generate_cart_table( $cart );
+ $output .= mt_generate_cart_table( $cart );
if ( $handling_total && 0 !== (int) $handling_total ) {
// Translators: amount of handling fee.
@@ -801,8 +813,20 @@
foreach ( $custom_fields as $key => $field ) {
$custom_output .= $field;
}
- $button = "<p class='mt_submit'><input type='submit' name='mt_submit' value='" . apply_filters( 'mt_submit_button_text', __( 'Review cart and make payment', 'my-tickets' ), $current_gate ) . "' /></p>";
- $output .= "<div class='mt_cart_total' aria-live='assertive'>" . apply_filters( 'mt_cart_total_content', '', $current_gate, $cart ) . apply_filters( 'mt_cart_ticket_total_text', __( 'Ticket Total:', 'my-tickets' ), $current_gate ) . " <span class='mt_total_number'>" . apply_filters( 'mt_money_format', $total ) . "</span></div>n" . mt_invite_login_or_register() . "n" . mt_required_fields( $cart, $custom_output ) . "n" . mt_gateways() . "$buttonn<input type='hidden' name='my-tickets' value='true' />" . apply_filters( 'mt_cart_hidden_fields', '' ) . '</form>' . mt_copy_cart() . '</div>';
+ $text = ( 'offline' === $current_gate ) ? __( 'Review cart and confirm reservation', 'my-tickets' ) : __( 'Review cart and make payment', 'my-tickets' );
+ /**
+ * Filter the submit button text.
+ *
+ * @hook mt_submit_button_text
+ *
+ * @param {string} $text Submit button text.
+ * @param {string} $current_gate Active gateway.
+ *
+ * @return string
+ */
+ $submit_text = apply_filters( 'mt_submit_button_text', $text, $current_gate );
+ $button = "<p class='mt_submit'><input type='submit' name='mt_submit' value='" . esc_attr( $submit_text ) . "' /></p>";
+ $output .= "<div class='mt_cart_total' aria-live='assertive'>" . apply_filters( 'mt_cart_total_content', '', $current_gate, $cart ) . apply_filters( 'mt_cart_ticket_total_text', __( 'Ticket Total:', 'my-tickets' ), $current_gate ) . " <span class='mt_total_number'>" . apply_filters( 'mt_money_format', $total ) . "</span></div>n" . mt_invite_login_or_register() . "n" . mt_required_fields( $cart, $custom_output ) . "n" . mt_gateways() . "$buttonn<input type='hidden' name='my-tickets' value='true' />" . apply_filters( 'mt_cart_hidden_fields', '' ) . '</form>' . mt_copy_cart() . '</div>';
} else {
do_action( 'mt_cart_is_empty' );
$expiration = '';
--- a/my-tickets/mt-cpt.php
+++ b/my-tickets/mt-cpt.php
@@ -45,6 +45,21 @@
}
/**
+ * Get log ID. Serializes the content of the first payment log.
+ *
+ * @param int $post_ID Payment post ID.
+ *
+ * @return string
+ */
+function mt_get_payment_log_id( $post_ID ) {
+ $log = get_post_meta( $post_ID, '_error_log', true );
+ $log_data = serialize( $log );
+ $log_id = md5( $log_data );
+
+ return $log_id;
+}
+
+/**
* Send custom email to ticket purchaser from payment record.
*/
function mt_email_purchaser() {
--- a/my-tickets/mt-notifications.php
+++ b/my-tickets/mt-notifications.php
@@ -460,7 +460,7 @@
$tickets = ( 'true' === $options['mt_html_email'] ) ? '<p>' . $tickets . '</p>' : $tickets;
$ticket_ids = '';
}
- $bulk_tickets = ( 'printable' === $ticketing_method ) ? add_query_arg(
+ $bulk_tickets = ( 'printable' === $ticketing_method || 'eticket' === $ticketing_method ) ? add_query_arg(
array(
'receipt_id' => $hash,
'multiple' => true,
@@ -780,7 +780,7 @@
}
foreach ( $data as $key => $value ) {
if ( is_object( $value ) && ! empty( $value ) ) {
- // null values return false.
+ // non-templatable values are ignored.
} else {
if ( false !== strpos( $template, '{' . $key ) ) {
if ( false !== strpos( $template, '{' . $key . ' ' ) ) { // only do preg_match if appropriate.
--- a/my-tickets/mt-payment.php
+++ b/my-tickets/mt-payment.php
@@ -104,6 +104,7 @@
wp_mail( $options['mt_to'], $mail_subject, $mail_body, $mail_from );
mt_log( $response, $response_code, $data, $post );
}
+ mt_set_receipt_cookie( $payment_id );
}
/**
--- a/my-tickets/mt-receipt.php
+++ b/my-tickets/mt-receipt.php
@@ -18,11 +18,28 @@
$id = ( '' !== $options['mt_receipt_page'] && is_numeric( $options['mt_receipt_page'] ) ) ? absint( $options['mt_receipt_page'] ) : false;
if ( $id && ( is_single( $id ) || is_page( $id ) ) ) {
if ( isset( $_GET['receipt_id'] ) ) {
- $template = locate_template( 'receipt.php' );
- if ( $template ) {
- load_template( $template );
+ $receipt = mt_get_receipt();
+ $receipt_id = md5( sanitize_text_field( $_GET['receipt_id'] ) . mt_get_payment_log_id( $receipt->ID ) );
+ $time = get_post_modified_time( 'U', true, $receipt->ID );
+ $date = ( $receipt ) ? $time : false;
+ $is_verified = false;
+ if ( isset( $_POST['mt-verify-email'] ) ) {
+ $nonce = isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : false;
+ $verify = wp_verify_nonce( $nonce, 'mt-verify-email' );
+ $email = sanitize_text_field( $_POST['mt-verify-email'] );
+ $is_verified = ( $verify && $email === get_post_meta( $receipt->ID, '_email', true ) ) ? true : false;
+ }
+ $cookie_receipt = ( isset( $_COOKIE['mt_purchase_receipt'] ) ) ? $_COOKIE['mt_purchase_receipt'] : false;
+ // Allow conditions: within 10 minutes of purchase & browser has a matching cookie; current user can view reports; user has verified email.
+ if ( ( time() <= $date + 600 && $cookie_receipt === $receipt_id ) || current_user_can( 'mt-view-reports' ) || $is_verified ) {
+ $template = locate_template( 'receipt.php' );
+ if ( $template ) {
+ load_template( $template );
+ } else {
+ load_template( __DIR__ . '/templates/receipt.php' );
+ }
} else {
- load_template( __DIR__ . '/templates/receipt.php' );
+ load_template( __DIR__ . '/mt-verify.php' );
}
exit;
} else {
--- a/my-tickets/mt-shortcodes.php
+++ b/my-tickets/mt-shortcodes.php
@@ -302,9 +302,11 @@
* @return string
*/
function mt_display_payments( $user_id = false, $count = 10, $user_email = '' ) {
- $output = '';
- if ( is_user_logged_in() ) {
- $user = ( ! $user_id ) ? wp_get_current_user()->ID : $user_id;
+ $output = '';
+ $user = wp_get_current_user();
+ $can_view = ( ( $user_id === $user->ID || $user_email === $user->user_email ) || current_user_can( 'mt-view-reports' ) ) ? true : false;
+ if ( is_user_logged_in() && $can_view ) {
+ $user = ( ! $user_id ) ? $user->ID : $user_id;
$count = ( ! $count ) ? 10 : absint( $count );
if ( $user && ! $user_email ) {
$payments = get_posts(
--- a/my-tickets/mt-verify.php
+++ b/my-tickets/mt-verify.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Verification template.
+ *
+ * @category Core
+ * @package My Tickets
+ * @author Joe Dolson
+ * @license GPLv3
+ * @link https://www.joedolson.com/my-tickets/
+ */
+$options = mt_get_settings();
+$post_url = add_query_arg( 'receipt_id', mt_get_receipt_id(), get_permalink( $options['mt_receipt_page'] ) );
+get_header()
+ ?>
+ <style>
+ .mt-entry { width: 100%; max-width: 1080px; padding: 1rem; margin: 0 auto; }
+ .verify-data form { display: flex; align-items: end; }
+ .mt-error { padding: .5rem; outline: 2px solid currentColor; margin-bottom: 1rem; }
+ </style>
+ <article class="mt-entry entry-content">
+ <h1 class='entry-title'><?php esc_html_e( 'Verify your purchase email', 'my-tickets' ); ?></h1>
+ <div class="entry-content">
+ <div class="verify-data">
+ <?php
+ if ( isset( $_POST['mt-verify-email'] ) ) {
+ ?>
+ <div class="mt-error">
+ <p><?php esc_html_e( 'Sorry! That email address does not match our records for this purchase.', 'my-tickets' ); ?></p>
+ </div>
+ <?php
+ }
+ ?>
+ <form action="<?php echo esc_url( $post_url ); ?>" method="post">
+ <?php wp_nonce_field( 'mt-verify-email' ); ?>
+ <p>
+ <label for="mt-verify-email"><?php esc_html_e( 'Your Email', 'my-tickets' ); ?></label><br />
+ <input type="email" id="mt-verify-email" name="mt-verify-email" autocomplete="email" required />
+ </p>
+ <p>
+ <button type="submit"><?php esc_html_e( 'Submit', 'my-tickets' ); ?></button>
+ </p>
+ </form>
+ </div>
+ </div>
+ </article>
+ <?php
+get_footer();
--- a/my-tickets/my-tickets.php
+++ b/my-tickets/my-tickets.php
@@ -17,7 +17,7 @@
* License: GPL-2.0+
* License URI: http://www.gnu.org/license/gpl-2.0.txt
* Domain Path: lang
- * Version: 2.1.0
+ * Version: 2.1.1
*/
/*
@@ -44,7 +44,7 @@
* @return string Current My Tickets version.
*/
function mt_get_current_version() {
- $mt_version = '2.1.0';
+ $mt_version = '2.1.1';
return $mt_version;
}
--- a/my-tickets/templates/receipt.php
+++ b/my-tickets/templates/receipt.php
@@ -95,6 +95,9 @@
grid-template-columns: 1fr 140px;
gap: 16px;
}
+ .payment-details {
+ margin-bottom: 1.5rem;
+ }
code {
font-family:'Courier New', Courier, monospace;