Skip to content

Instantly share code, notes, and snippets.

@jesseeproductions
Last active February 1, 2016 16:14
Show Gist options
  • Save jesseeproductions/6f5bc1f7d2e7fa8df6c7 to your computer and use it in GitHub Desktop.
Save jesseeproductions/6f5bc1f7d2e7fa8df6c7 to your computer and use it in GitHub Desktop.
QR Prevent Multiple Checkins 4.0
<?php
/**
* Class Tribe__Tickets_Plus__QR
*/
class Tribe__Tickets_Plus__QR {
public function __construct() {
add_filter( 'init', array( $this, 'handle_redirects' ), 10 );
add_filter( 'admin_notices', array( $this, 'admin_notice' ), 10 );
add_action( 'tribe_tickets_ticket_email_ticket_bottom', array( $this, 'inject_qr' ) );
add_action( 'rsvp_uncheckin', array( $this, 'admin_undo_checkin' ), 10 );
add_action( 'wootickets_uncheckin', array( $this, 'admin_undo_checkin' ), 10 );
add_action( 'eddtickets_uncheckin', array( $this, 'admin_undo_checkin' ), 10 );
add_action( 'shopptickets_uncheckin', array( $this, 'admin_undo_checkin' ), 10 );
add_action( 'wpectickets_uncheckin', array( $this, 'admin_undo_checkin' ), 10 );
}
/**
* Procesess the links coming from QR codes and decides what to do:
* - If the user is logged in and has proper permissions, it will redirect
* to the attendees screen for the event, and will automatically check in the user.
*
* - If the user is not logged in and/or not have proper permissions, it'll redirect
* to the homepage of the event (front end)
*/
public function handle_redirects() {
// Check if it's our time to shine.
// Not as fancy as a custom permalink handler, but way less likely to fail depending on setup and settings
if ( ! isset( $_GET['event_qr_code'] ) ) {
return;
}
// Check all the data we need is there
if ( empty( $_GET['ticket_id'] ) || empty( $_GET['event_id'] ) ) {
return;
}
// Make sure we don't fail too hard
if ( ! class_exists( 'Tribe__Tickets__Tickets_Handler' ) ) {
return;
}
// If the user is the site owner (or similar), Check in the user to the event
if ( is_user_logged_in() && current_user_can( 'edit_posts' ) ) {
$this->_check_in( $_GET['ticket_id'] );
$post = get_post( $_GET['event_id'] );
if ( empty( $post ) ) {
return;
}
$url = add_query_arg( array(
'post_type' => $post->post_type,
'page' => Tribe__Tickets__Tickets_Handler::$attendees_slug,
'event_id' => $_GET['event_id'],
'qr_checked_in' => $_GET['ticket_id'],
), admin_url( 'edit.php' ) );
} else { // Probably just the ticket holder, redirect to the event front end single
$url = get_permalink( $_GET['event_id'] );
}
wp_redirect( $url );
exit;
}
/**
* Show a notice so the user knows the ticket was checked in
*/
public function admin_notice() {
if ( empty( $_GET['qr_checked_in'] ) ) {
return;
}
$checked_status = get_post_meta( $_GET['qr_checked_in'], '_tribe_checkedin_status', true );
if ( ! $checked_status ) {
echo '<div class="updated"><p>';
printf( esc_html__( 'The ticket with ID %d was checked in.', 'event-tickets-plus' ), absint( $_GET['qr_checked_in'] ) );
echo '</p></div>';
update_post_meta( $_GET['qr_checked_in'], '_tribe_checkedin_status', 'checked' );
} else {
echo '<div class="error"><p>';
printf( esc_html__( 'The ticket with ID %d has already been checked in.', 'event-tickets-plus' ), absint( $_GET['qr_checked_in'] ) );
echo '</p></div>';
}
}
/**
* Delete Checked Status on Undo Check In Click from Admin
*/
public function admin_undo_checkin( $attendee_id ) {
delete_post_meta( $attendee_id, '_tribe_checkedin_status' );
}
/**
* Generates the QR image, stores is locally and injects it into the tickets email
*
* @param $ticket array
*
* @return string
*/
public function inject_qr( $ticket ) {
$link = $this->_get_link( $ticket['ticket_id'], $ticket['event_id'] );
$qr = $this->_get_image( $link );
if ( ! $qr ) {
return;
}
?>
<table class="content" align="center" width="620" cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" style="margin:15px auto 0; padding:0;">
<tr>
<td align="center" valign="top" class="wrapper" width="620">
<table class="inner-wrapper" border="0" cellpadding="0" cellspacing="0" width="620" bgcolor="#f7f7f7" style="margin:0 auto !important; width:620px; padding:0;">
<tr>
<td valign="top" class="ticket-content" align="left" width="140" border="0" cellpadding="20" cellspacing="0" style="padding:20px; background:#f7f7f7;">
<img src="<?php echo esc_url( $qr ); ?>" width="140" height="140" alt="QR Code Image" style="border:0; outline:none; height:auto; max-width:100%; display:block;"/>
</td>
<td valign="top" class="ticket-content" align="left" border="0" cellpadding="20" cellspacing="0" style="padding:20px; background:#f7f7f7;">
<h3 style="color:#0a0a0e; margin:0 0 10px 0 !important; font-family: 'Helvetica Neue', Helvetica, sans-serif; font-style:normal; font-weight:700; font-size:28px; letter-spacing:normal; text-align:left;line-height: 100%;">
<span style="color:#0a0a0e !important"><?php esc_html_e( 'Check in for this event', 'event-tickets-plus' ); ?></span>
</h3>
<p>
Scan this QR code at the event to check in.
</p>
</td>
</tr>
</td>
</tr>
</table>
<?php
}
/**
* Generates the link for the QR image
*
* @param $ticket_id
* @param $event_id
*
* @return string
*/
private function _get_link( $ticket_id, $event_id ) {
$url = add_query_arg( 'event_qr_code', 1, home_url() );
$url = add_query_arg( 'ticket_id', $ticket_id, $url );
$url = add_query_arg( 'event_id', $event_id, $url );
return $url;
}
/**
* Generates the QR image for a given link and stores it in /wp-content/uploads.
* Returns the link to the new image.
*
* @param $link
*
* @return string
*/
private function _get_image( $link ) {
if ( ! class_exists( 'QRencode' ) ) {
include_once( EVENT_TICKETS_PLUS_DIR . '/vendor/phpqrcode/qrlib.php' );
}
$uploads = wp_upload_dir();
$file_name = 'qr_' . md5( $link ) . '.png';
$path = trailingslashit( $uploads['path'] ) . $file_name;
$url = trailingslashit( $uploads['url'] ) . $file_name;
if ( ! file_exists( $path ) ) {
QRcode::png( $link, $path, QR_ECLEVEL_L, 3 );
}
return $url;
}
/**
* Checks the user in, for all the *Tickets modules running.
*
* @param $ticket_id
*/
private function _check_in( $ticket_id ) {
$modules = Tribe__Tickets__Tickets::modules();
foreach ( $modules as $class => $module ) {
if ( ! is_callable( array( $class, 'get_instance' ) ) ) {
continue;
}
$obj = call_user_func( array( $class, 'get_instance' ) );
$obj->checkin( $ticket_id );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment