Skip to content

Commit

Permalink
Add ticket model switcher
Browse files Browse the repository at this point in the history
  • Loading branch information
joedolson committed Dec 28, 2023
1 parent 32ab19a commit b59519e
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 104 deletions.
135 changes: 80 additions & 55 deletions src/js/pricing-table.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,87 @@
jQuery(document).ready(function ($) {
$('.add-price').on('click', function () {
var context = $( this ).attr( 'data-context' );
var num = $('.clonedPrice.' + context).length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#price' + context + num).clone().attr('id', 'price' + context + newNum);
// manipulate the name/id values of the input inside the new element
// insert the new element after the last "duplicatable" input field
$('#price' + context + num).after(newElem);
// enable the "remove" button
$('.del-price.' + context).removeAttr('disabled');
// business rule: you can only add 20 variations
if (newNum == 20) {
$( this ).attr('disabled', 'disabled');
}
});
(function ($) {
$(function () {
mt_pricing_table();
function mt_pricing_table() {
$('.add-price').on('click', function () {
var context = $( this ).attr( 'data-context' );
var num = $('.clonedPrice.' + context).length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#price' + context + num).clone().attr('id', 'price' + context + newNum);
// manipulate the name/id values of the input inside the new element
// insert the new element after the last "duplicatable" input field
$('#price' + context + num).after(newElem);
// enable the "remove" button
$('.del-price.' + context).removeAttr('disabled');
// business rule: you can only add 20 variations
if (newNum == 20) {
$( this ).attr('disabled', 'disabled');
}
});

$('.del-price').on('click', function () {
var context = $( this ).attr( 'data-context' );
var num = $('.clonedPrice.' + context).length; // how many "duplicatable" input fields we currently have
$('#price' + context + num).remove(); // remove the last element
// enable the "add" button
$( this ).removeAttr('disabled');
// if only one element remains, disable the "remove" button
if (num - 1 == 1) {
$( this ).attr('disabled', 'disabled');
}
});
$('.del-price').attr('disabled', 'disabled');

$("button.up,button.down").on( 'click', function(e){
e.preventDefault();
$('.mt-pricing table tr').removeClass('fade');
var row = $(this).parents("tr:first");
if ($(this).is(".up")) {
row.insertBefore(row.prev()).addClass('fade');
} else {
row.insertAfter(row.next()).addClass('fade');
}
});

$('.del-price').on('click', function () {
var context = $( this ).attr( 'data-context' );
var num = $('.clonedPrice.' + context).length; // how many "duplicatable" input fields we currently have
$('#price' + context + num).remove(); // remove the last element
// enable the "add" button
$( this ).removeAttr('disabled');
// if only one element remains, disable the "remove" button
if (num - 1 == 1) {
$( this ).attr('disabled', 'disabled');
$('.deletable .mt-controls').append( '<button type="button" class="button delete"><span class="dashicons dashicons-no"></span><span class="screen-reader-text">' + mt.delete + '</span></button>' );
$('.deletable .mt-controls .delete').on( 'click', function() {
var is_undo = $( this ).hasClass( 'undo' );
var parent = $(this).parents('.deletable');
if ( is_undo ) {
parent.find('input,button.up,button.down').removeAttr('disabled');
parent.find('button.delete').removeClass('undo');
parent.find('button.delete .dashicons').removeClass( 'dashicons-undo').addClass('dashicons-no');
parent.find('button.delete .screen-reader-text').text(mt.delete);
} else {
parent.find('input,button.up,button.down').attr('disabled', 'disabled');
parent.find('button.delete').addClass('undo');
parent.find('button.delete .dashicons').removeClass( 'dashicons-no').addClass('dashicons-undo');
parent.find('button.delete .screen-reader-text').text(mt.undo);
}
});
}
});
$('.del-price').attr('disabled', 'disabled');
$( '.mt-load-model button' ).on( 'click', function() {
var event_id = $(this).attr( 'id' );
var model = $(this).attr( 'class' );
var event = $( '.mt-ticket-data-json' ).html();
var data = {
'action': mt.action,
'event_id': event_id,
'model': model,
'event': event,
'security': mt.security
};

$("button.up,button.down").on( 'click', function(e){
e.preventDefault();
$('.mt-pricing table tr').removeClass('fade');
var row = $(this).parents("tr:first");
if ($(this).is(".up")) {
row.insertBefore(row.prev()).addClass('fade');
} else {
row.insertAfter(row.next()).addClass('fade');
}
});
$.post( ajaxurl, data, function (response) {
var container = $( '.mt-ticket-wrapper-form' );
var form = response.form;

$('.deletable .mt-controls').append( '<button type="button" class="button delete"><span class="dashicons dashicons-no"></span><span class="screen-reader-text">' + mt.delete + '</span></button>' );
$('.deletable .mt-controls .delete').on( 'click', function(e) {
var is_undo = $( this ).hasClass( 'undo' );
var parent = $(this).parents('.deletable');
if ( is_undo ) {
parent.find('input,button.up,button.down').removeAttr('disabled');
parent.find('button.delete').removeClass('undo');
parent.find('button.delete .dashicons').removeClass( 'dashicons-undo').addClass('dashicons-no');
parent.find('button.delete .screen-reader-text').text(mt.delete);
} else {
parent.find('input,button.up,button.down').attr('disabled', 'disabled');
parent.find('button.delete').addClass('undo');
parent.find('button.delete .dashicons').removeClass( 'dashicons-no').addClass('dashicons-undo');
parent.find('button.delete .screen-reader-text').text(mt.undo);
}
});
});
container.html( form );
mt_pricing_table();
}, "json" );
});
});
}(jQuery));

window.customElements.whenDefined( 'duet-date-picker' ).then(() => {
elem = document.querySelectorAll('.duet-fallback');
Expand Down
36 changes: 30 additions & 6 deletions src/mt-ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
exit;
} // Exit if accessed directly.

add_action( 'wp_ajax_mt_ajax_cart', 'mt_ajax_cart' );
add_action( 'wp_ajax_nopriv_mt_ajax_cart', 'mt_ajax_cart' );

/**
* Submits a cart update request from AJAX when cart is modified from Cart page.
*
Expand Down Expand Up @@ -55,9 +52,8 @@ function mt_ajax_cart() {
die;
}
}

add_action( 'wp_ajax_mt_ajax_handler', 'mt_ajax_handler' );
add_action( 'wp_ajax_nopriv_mt_ajax_handler', 'mt_ajax_handler' );
add_action( 'wp_ajax_mt_ajax_cart', 'mt_ajax_cart' );
add_action( 'wp_ajax_nopriv_mt_ajax_cart', 'mt_ajax_cart' );

/**
* Submit a cart update request from AJAX when add_to_cart button used from event
Expand Down Expand Up @@ -139,3 +135,31 @@ function mt_ajax_handler() {
wp_send_json( $response );
}
}
add_action( 'wp_ajax_mt_ajax_handler', 'mt_ajax_handler' );
add_action( 'wp_ajax_nopriv_mt_ajax_handler', 'mt_ajax_handler' );

/**
* AJAX load a ticket model set.
*/
function mt_ajax_load_model() {
// verify nonce.
if ( ! check_ajax_referer( 'mt-load-model', 'security', false ) ) {
wp_send_json(
array(
'response' => __( 'Invalid security response.', 'my-tickets' ),
'form' => '',
)
);
}
$model = ( in_array( $_REQUEST['model'], array( 'continuous', 'discrete', 'event' ) ) ) ? sanitize_key( $_REQUEST['model'] ) : false;
$event_id = absint( $_REQUEST['event_id'] );
$data = map_deep( json_decode( $_REQUEST['event'] ), 'sanitize_text_field' );
$form = mt_get_registration_fields( '', $event_id, $data, 'admin', $model );
wp_send_json(
array(
'form' => $form,
)
);
}
add_action( 'wp_ajax_mt_ajax_load_model', 'mt_ajax_load_model' );
add_action( 'wp_ajax_nopriv_mt_ajax_load_model', 'mt_ajax_load_model' );
103 changes: 62 additions & 41 deletions src/mt-processing.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,33 +257,77 @@ function mt_calculate_discount( $price, $event_id, $payment_id = false ) {
*
* @return string
*/
function mt_registration_fields( $form, $has_data, $data, $public = 'admin' ) {
$original_form = $form;
$options = mt_get_settings();
$registration = array();
$event_id = false;
$description = false;
$hide = false;
$checked = '';
$notes = '';
function mt_registration_fields( $form, $has_data, $data, $public = 'admin', $model = '' ) {
$event_id = 0;
$notes = '';
$hide = false;
$checked = '';
$registration = array();
if ( true === $has_data && property_exists( $data, 'event_post' ) ) {
$event_id = (int) $data->event_post;
$registration = get_post_meta( $event_id, '_mt_registration_options', true );
$notes = get_post_meta( $event_id, '_mt_event_notes', true );
$hide = get_post_meta( $event_id, '_mt_hide_registration_form', true );
$description = stripslashes( esc_attr( $data->event_registration ) );
$registration = get_post_meta( $event_id, '_mt_registration_options', true );
$checked = ( 'true' === get_post_meta( $event_id, '_mt_sell_tickets', true ) ) ? ' checked="checked"' : '';
$notes = get_post_meta( $event_id, '_mt_event_notes', true );
}
if ( is_int( $has_data ) && $has_data ) {
$event_id = $has_data;
$registration = get_post_meta( $event_id, '_mt_registration_options', true );
$notes = get_post_meta( $event_id, '_mt_event_notes', true );
$hide = get_post_meta( $event_id, '_mt_hide_registration_form', true );
$description = false;
$registration = get_post_meta( $event_id, '_mt_registration_options', true );
$checked = ( 'true' === get_post_meta( $event_id, '_mt_sell_tickets', true ) ) ? ' checked="checked"' : '';
$notes = get_post_meta( $event_id, '_mt_event_notes', true );
}
$is_hidden = ( 'true' === $hide ) ? ' checked="checked"' : '';
$data = '<div class="hidden mt-ticket-data-json">' . json_encode( $data ) . '</div>';
$model_selector = '
<div class="mt-load-model">
' . $data . '
<button type="button" class="continuous" id="' . $event_id . '">Continuous</button>
<button type="button" class="discrete" id="' . $event_id . '">Discrete</button>
<button type="button" class="event" id="' . $event_id . '">Event</button>
</div>';
$shortcode = ( $registration ) ? "<label for='shortcode'>" . __( 'Add to Cart Form Shortcode', 'my-tickets' ) . "</label><br /><textarea id='shortcode' readonly='readonly' class='large-text readonly'>[ticket event='$event_id']</textarea>" : '';

// Appear on My Calendar events to toggle ticket sales.
$format = ( isset( $_GET['page'] ) && 'my-calendar' === $_GET['page'] ) ? "<p><input type='checkbox' class='mt-trigger' name='mt-trigger' id='mt-trigger'$checked /> <label for='mt-trigger'>" . __( 'Sell tickets on this event.', 'my-tickets' ) . '</label></p>' : '';
$reports = ( $event_id && ! empty( get_post_meta( $event_id, '_ticket' ) ) ) ? "<p class='get-report'><span class='dashicons dashicons-chart-bar' aria-hidden='true'></span> <a href='" . admin_url( "admin.php?page=mt-reports&amp;event_id=$event_id" ) . "'>" . __( 'View Tickets Purchased for this event', 'my-tickets' ) . '</a></p>' : '';
$form = $reports . $format . $shortcode . $model_selector . '<div class="mt-ticket-wrapper-form">' . mt_get_registration_fields( $form, $has_data, $data, $public, $model ) . '</div>';

$form .= "<p>
<label for='mt_event_notes'>" . __( 'Event-specific notes for email notifications', 'my-tickets' ) . "</label><br />
<textarea id='mt_event_notes' name='mt_event_notes' cols='60' rows='4' class='widefat' aria-describedby='template_tag'>" . stripslashes( esc_textarea( $notes ) ) . "</textarea><br />
<span id='template_tag'>" . __( 'Template tag for email notifications:', 'my-tickets' ) . ' <code>{event_notes}</code></span>
</p>';
$form .= "<p><input type='checkbox' name='mt_hide_registration_form' id='mt_hide' $is_hidden /> <label for='mt_hide'>" . __( 'Don\'t display form on event', 'my-tickets' ) . '</label></p>';


return $form;
}

/**
* Add registration fields for My Calendar events & posts.
*
* @param string $form Form html.
* @param bool $has_data Does this form contain data.
* @param object $data object Data contained.
* @param string $public Admin or public context.
* @param string $model Whether to fetch a specific ticket model format.
*
* @return string
*/
function mt_get_registration_fields( $form, $has_data, $data, $public = 'admin', $model = '' ) {
$original_form = $form;
$options = mt_get_settings();
$registration = array();
$description = false;
if ( true === $has_data && property_exists( $data, 'event_post' ) ) {
$description = stripslashes( esc_attr( $data->event_registration ) );
}
if ( is_int( $has_data ) && $has_data ) {
$description = false;
}
if ( empty( $registration ) ) {
$default_model = $options['default_model'];
$default_model = ( '' !== $model ) ? $model : $options['default_model'];
$registration = $options['defaults'][ $default_model ];
}
$expiration = ( isset( $registration['reg_expires'] ) ) ? $registration['reg_expires'] : $options['defaults']['reg_expires'];
Expand All @@ -297,25 +341,9 @@ function mt_registration_fields( $form, $has_data, $data, $public = 'admin' ) {
$is_tickets = '';
$is_registration = ' checked="checked"';
}
$method = ( isset( $registration['counting_method'] ) ) ? $registration['counting_method'] : $options['defaults']['counting_method'];
if ( 'true' === $hide ) {
$is_hidden = ' checked="checked"';
} else {
$is_hidden = '';
}
if ( $registration ) {
$shortcode = "<label for='shortcode'>" . __( 'Add to Cart Form Shortcode', 'my-tickets' ) . "</label><br /><textarea id='shortcode' readonly='readonly' class='large-text readonly'>[ticket event='$event_id']</textarea>";
} else {
$shortcode = '';
}
// Appear on My Calendar events to toggle ticket sales.
$format = ( isset( $_GET['page'] ) && 'my-calendar' === $_GET['page'] ) ? "<p><input type='checkbox' class='mt-trigger' name='mt-trigger' id='mt-trigger'$checked /> <label for='mt-trigger'>" . __( 'Sell tickets on this event.', 'my-tickets' ) . '</label></p>' : '';
$before = "<div class='mt-ticket-form'>";
$after = '</div>';
$reports = ( $event_id && ! empty( get_post_meta( $event_id, '_ticket' ) ) ) ? "<p class='get-report'><span class='dashicons dashicons-chart-bar' aria-hidden='true'></span> <a href='" . admin_url( "admin.php?page=mt-reports&amp;event_id=$event_id" ) . "'>" . __( 'View Tickets Purchased for this event', 'my-tickets' ) . '</a></p>' : '';
$method = ( isset( $registration['counting_method'] ) ) ? $registration['counting_method'] : $default_model;

$form = $reports . $format . $before . $shortcode;
$form .= mt_prices_table( $registration );
$form = mt_prices_table( $registration, $method );
$form .= "
<p>
<label for='reg_expires'>" . __( 'Allow sales until', 'my-tickets' ) . "</label> <input type='number' name='reg_expires' id='reg_expires' value='$expiration' aria-labelledby='reg_expires reg_expires_label' size='3' /> <span class='label' id='reg_expires_label'>" . __( 'hours before the event', 'my-tickets' ) . "</span>
Expand All @@ -340,12 +368,6 @@ function mt_registration_fields( $form, $has_data, $data, $public = 'admin' ) {
if ( false !== $description ) {
$form .= "<p><label for='event_registration'>" . __( 'Registration Information', 'my-tickets' ) . "</label> <textarea name='event_registration' id='event_registration' cols='40' rows='4'/>$description</textarea></p>";
}
$form .= "<p>
<label for='mt_event_notes'>" . __( 'Event-specific notes for email notifications', 'my-tickets' ) . "</label><br />
<textarea id='mt_event_notes' name='mt_event_notes' cols='60' rows='4' class='widefat' aria-describedby='template_tag'>" . stripslashes( esc_textarea( $notes ) ) . "</textarea><br />
<span id='template_tag'><strong>" . __( 'Template tag:', 'my-tickets' ) . ' </strong><code>{event_notes}</code></span>
</p>';
$form .= "<p><input type='checkbox' name='mt_hide_registration_form' id='mt_hide' $is_hidden /> <label for='mt_hide'>" . __( 'Don\'t display form on event', 'my-tickets' ) . '</label></p>';
/**
* Show custom fields/content in event creation inside My Calendar. Inserted at the end of the form.
*
Expand All @@ -358,7 +380,6 @@ function mt_registration_fields( $form, $has_data, $data, $public = 'admin' ) {
* @return {string}
*/
$form .= apply_filters( 'mt_custom_data_fields', '', $registration, $data );
$form .= $after;

/**
* Filter generated form for event creation inside My Calendar.
Expand Down
6 changes: 4 additions & 2 deletions src/mt-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -474,8 +474,10 @@ function mt_wp_enqueue_scripts() {
'mt.add',
'mt',
array(
'delete' => __( 'Delete', 'my-tickets' ),
'undo' => __( 'Undo Deletion', 'my-tickets' ),
'delete' => __( 'Delete', 'my-tickets' ),
'undo' => __( 'Undo Deletion', 'my-tickets' ),
'action' => 'mt_ajax_load_model',
'security' => wp_create_nonce( 'mt-load-model' ),
)
);
wp_localize_script(
Expand Down
1 change: 1 addition & 0 deletions src/my-tickets.php
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,7 @@ function mt_kses_elements() {
'data-event' => array(),
'data-ticket' => array(),
'data-payment' => array(),
'id' => array(),
),
'ul' => array(
'class' => array(),
Expand Down

0 comments on commit b59519e

Please sign in to comment.