monorepo/native/wordpress/ticket-tailor-wp-max/includes/class-shortcodes.php

304 lines
12 KiB
PHP

<?php
/**
* Ticket Tailor Shortcodes
* Updated with equal-height card support
*/
// Exit if accessed directly
if (!defined('ABSPATH')) {
exit;
}
class Ticket_Tailor_Shortcodes {
private $events;
private $orders;
public function __construct($events, $orders) {
$this->events = $events;
$this->orders = $orders;
$this->register_shortcodes();
}
private function register_shortcodes() {
add_shortcode('tt-event', array($this, 'event_widget_shortcode'));
add_shortcode('tt-events', array($this, 'event_listing_shortcode'));
add_shortcode('tt-single-event', array($this, 'single_event_shortcode'));
}
/**
* Event widget shortcode (original, enhanced)
*/
public function event_widget_shortcode($atts) {
$atts = shortcode_atts(
array(
'url' => '',
'minimal' => 'false',
'bg_fill' => 'true',
'show_logo' => 'true',
'inherit_ref_from_url_param' => '',
'ref' => 'website_widget',
),
$atts,
'tt-event'
);
if (empty($atts['url'])) {
return '<div class="tt-widget-error"><p>' .
esc_html__('Error: No URL set for Ticket Tailor widget', 'ticket-tailor') .
'</p></div>';
}
$url = esc_url($atts['url'], array('http', 'https'));
if (empty($url)) {
return '<div class="tt-widget-error"><p>' .
esc_html__('Error: Invalid URL provided', 'ticket-tailor') .
'</p></div>';
}
$minimal = $this->sanitize_boolean($atts['minimal']);
$bg_fill = $this->sanitize_boolean($atts['bg_fill']);
$show_logo = $this->sanitize_boolean($atts['show_logo']);
$inherit_ref = sanitize_text_field($atts['inherit_ref_from_url_param']);
$ref = sanitize_text_field($atts['ref']);
static $widget_count = 0;
$widget_count++;
$widget_id = 'tt-widget-' . $widget_count;
ob_start();
?>
<div id="<?php echo esc_attr($widget_id); ?>" class="tt-widget-container">
<script>
(function() {
var script = document.createElement('script');
script.src = 'https://cdn.tickettailor.com/js/widgets/min/widget.js';
script.setAttribute('data-url', <?php echo wp_json_encode($url); ?>);
script.setAttribute('data-type', 'inline');
script.setAttribute('data-inline-minimal', <?php echo wp_json_encode($minimal ? 'true' : 'false'); ?>);
script.setAttribute('data-inline-show-logo', <?php echo wp_json_encode($show_logo ? 'true' : 'false'); ?>);
script.setAttribute('data-inline-bg-fill', <?php echo wp_json_encode($bg_fill ? 'true' : 'false'); ?>);
<?php if (!empty($inherit_ref)) : ?>
script.setAttribute('data-inline-inherit-ref-from-url-param', <?php echo wp_json_encode($inherit_ref); ?>);
<?php endif; ?>
script.setAttribute('data-inline-ref', <?php echo wp_json_encode($ref); ?>);
var container = document.getElementById(<?php echo wp_json_encode($widget_id); ?>);
if (container) {
container.appendChild(script);
}
})();
</script>
</div>
<?php
return ob_get_clean();
}
/**
* Event listing shortcode - UPDATED for equal heights and wider cards
*/
public function event_listing_shortcode($atts) {
$atts = shortcode_atts(
array(
'limit' => 10,
'layout' => 'grid',
'columns' => 3,
'show_past' => 'false',
'show_image' => 'true',
),
$atts,
'tt-events'
);
$limit = absint($atts['limit']);
$layout = sanitize_key($atts['layout']);
$columns = absint($atts['columns']);
$show_past = $this->sanitize_boolean($atts['show_past']);
$show_image = $this->sanitize_boolean($atts['show_image']);
$events = $show_past ?
$this->events->get_past_events($limit) :
$this->events->get_upcoming_events($limit);
if (is_wp_error($events)) {
return '<div class="tt-error">' . esc_html($events->get_error_message()) . '</div>';
}
if (empty($events)) {
return '<div class="tt-no-events">' . esc_html__('No events found', 'ticket-tailor') . '</div>';
}
ob_start();
$class = 'tt-event-listing tt-layout-' . esc_attr($layout);
if ($layout === 'grid') {
$class .= ' tt-columns-' . esc_attr($columns);
}
?>
<div class="<?php echo esc_attr($class); ?>">
<?php foreach ($events as $event) : ?>
<div class="tt-event-card">
<?php if ($show_image && !empty($event['images']['header'])) : ?>
<div class="tt-event-image">
<img src="<?php echo esc_url($event['images']['header']); ?>"
alt="<?php echo esc_attr($event['name']); ?>">
</div>
<?php endif; ?>
<div class="tt-event-content">
<h3 class="tt-event-title"><?php echo esc_html($event['name']); ?></h3>
<?php if (!empty($event['start']['iso'])) : ?>
<div class="tt-event-date">
<span class="dashicons dashicons-calendar-alt"></span>
<?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($event['start']['iso']))); ?>
</div>
<?php endif; ?>
<?php if (!empty($event['venue']['name'])) : ?>
<div class="tt-event-venue">
<span class="dashicons dashicons-location"></span>
<?php echo esc_html($event['venue']['name']); ?>
</div>
<?php endif; ?>
<?php
// Only show description in LIST layout, never in GRID
if ($layout === 'list' && !empty($event['description'])) :
?>
<div class="tt-event-excerpt">
<?php echo esc_html(wp_trim_words($event['description'], 20)); ?>
</div>
<?php endif; ?>
<!-- Spacer pushes button to bottom -->
<div class="tt-event-spacer"></div>
<!-- Button container at bottom of card -->
<?php if (!empty($event['url'])) : ?>
<div class="tt-event-button-container">
<a href="<?php echo esc_url($event['url']); ?>"
class="tt-event-button"
target="_blank">
<?php esc_html_e('Get Tickets', 'ticket-tailor'); ?>
</a>
</div>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php
return ob_get_clean();
}
/**
* Single event shortcode
*/
public function single_event_shortcode($atts) {
$atts = shortcode_atts(
array(
'id' => '',
'show_description' => 'true',
'show_tickets' => 'true',
'show_image' => 'true',
),
$atts,
'tt-single-event'
);
$event_id = sanitize_text_field($atts['id']);
if (empty($event_id)) {
return '<div class="tt-error">' . esc_html__('Error: No event ID specified', 'ticket-tailor') . '</div>';
}
$show_description = $this->sanitize_boolean($atts['show_description']);
$show_tickets = $this->sanitize_boolean($atts['show_tickets']);
$show_image = $this->sanitize_boolean($atts['show_image']);
$event = $this->events->get_event($event_id);
if (is_wp_error($event)) {
return '<div class="tt-error">' . esc_html($event->get_error_message()) . '</div>';
}
ob_start();
?>
<div class="tt-single-event">
<?php if ($show_image && !empty($event['images']['header'])) : ?>
<div class="tt-event-header-image">
<img src="<?php echo esc_url($event['images']['header']); ?>"
alt="<?php echo esc_attr($event['name']); ?>">
</div>
<?php endif; ?>
<div class="tt-event-details">
<h2 class="tt-event-title"><?php echo esc_html($event['name']); ?></h2>
<div class="tt-event-meta">
<?php if (!empty($event['start']['iso'])) : ?>
<div class="tt-meta-item">
<span class="dashicons dashicons-calendar-alt"></span>
<strong><?php esc_html_e('Date:', 'ticket-tailor'); ?></strong>
<?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($event['start']['iso']))); ?>
</div>
<?php endif; ?>
<?php if (!empty($event['venue']['name'])) : ?>
<div class="tt-meta-item">
<span class="dashicons dashicons-location"></span>
<strong><?php esc_html_e('Venue:', 'ticket-tailor'); ?></strong>
<?php echo esc_html($event['venue']['name']); ?>
</div>
<?php endif; ?>
<?php if (!empty($event['status'])) : ?>
<div class="tt-meta-item">
<span class="dashicons dashicons-info"></span>
<strong><?php esc_html_e('Status:', 'ticket-tailor'); ?></strong>
<span class="tt-status"><?php echo esc_html($event['status']); ?></span>
</div>
<?php endif; ?>
</div>
<?php if ($show_description && !empty($event['description'])) : ?>
<div class="tt-event-description">
<?php echo wp_kses_post(wpautop($event['description'])); ?>
</div>
<?php endif; ?>
<?php if ($show_tickets && !empty($event['url'])) : ?>
<div class="tt-event-cta">
<a href="<?php echo esc_url($event['url']); ?>"
class="tt-button tt-button-primary"
target="_blank">
<?php esc_html_e('Buy Tickets', 'ticket-tailor'); ?>
</a>
</div>
<?php endif; ?>
</div>
</div>
<?php
return ob_get_clean();
}
/**
* Sanitize boolean values
*/
private function sanitize_boolean($value) {
if (is_bool($value)) {
return $value;
}
if (is_string($value)) {
$value = strtolower(trim($value));
return in_array($value, array('1', 'true', 'yes', 'on'), true);
}
return (bool) $value;
}
}