547 lines
24 KiB
PHP
547 lines
24 KiB
PHP
<?php
|
|
/**
|
|
* Ticket Tailor Blocks
|
|
* Enhanced with full-width support and responsive columns
|
|
* FIXED: Removed spacers that were making cards too tall
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class Ticket_Tailor_Blocks {
|
|
|
|
/**
|
|
* Event Manager
|
|
*/
|
|
private $events;
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct($events) {
|
|
$this->events = $events;
|
|
|
|
add_action('init', array($this, 'register_blocks'));
|
|
add_action('enqueue_block_editor_assets', array($this, 'enqueue_editor_assets'));
|
|
}
|
|
|
|
/**
|
|
* Register blocks
|
|
*/
|
|
public function register_blocks() {
|
|
// Event Widget Block (Original)
|
|
register_block_type('ticket-tailor/event-widget', array(
|
|
'render_callback' => array($this, 'render_event_widget_block'),
|
|
'attributes' => array(
|
|
'url' => array('type' => 'string', 'default' => ''),
|
|
'minimal' => array('type' => 'boolean', 'default' => false),
|
|
'bgFill' => array('type' => 'boolean', 'default' => true),
|
|
'showLogo' => array('type' => 'boolean', 'default' => true),
|
|
'ref' => array('type' => 'string', 'default' => 'website_widget'),
|
|
'align' => array('type' => 'string', 'default' => ''),
|
|
),
|
|
));
|
|
|
|
// Event Listing Block - ENHANCED
|
|
register_block_type('ticket-tailor/event-listing', array(
|
|
'render_callback' => array($this, 'render_event_listing_block'),
|
|
'attributes' => array(
|
|
'limit' => array('type' => 'number', 'default' => 10),
|
|
'layout' => array('type' => 'string', 'default' => 'grid'),
|
|
'columns' => array('type' => 'number', 'default' => 3),
|
|
'columnsMode' => array('type' => 'string', 'default' => 'fixed'),
|
|
'showPast' => array('type' => 'boolean', 'default' => false),
|
|
'showImage' => array('type' => 'boolean', 'default' => true),
|
|
'imageType' => array('type' => 'string', 'default' => 'thumbnail'),
|
|
'fullWidth' => array('type' => 'boolean', 'default' => true),
|
|
'maxCardWidth' => array('type' => 'string', 'default' => 'none'),
|
|
'align' => array('type' => 'string', 'default' => ''),
|
|
'className' => array('type' => 'string', 'default' => ''),
|
|
),
|
|
));
|
|
|
|
// Single Event Block - ENHANCED
|
|
register_block_type('ticket-tailor/single-event', array(
|
|
'render_callback' => array($this, 'render_single_event_block'),
|
|
'attributes' => array(
|
|
'eventId' => array('type' => 'string', 'default' => ''),
|
|
'showDescription' => array('type' => 'boolean', 'default' => true),
|
|
'showTickets' => array('type' => 'boolean', 'default' => true),
|
|
'showImage' => array('type' => 'boolean', 'default' => true),
|
|
'imageType' => array('type' => 'string', 'default' => 'header'),
|
|
'fullWidth' => array('type' => 'boolean', 'default' => false),
|
|
'maxWidth' => array('type' => 'string', 'default' => '800px'),
|
|
'align' => array('type' => 'string', 'default' => ''),
|
|
),
|
|
));
|
|
|
|
// Category Events Block - ENHANCED
|
|
register_block_type('ticket-tailor/category-events', array(
|
|
'render_callback' => array($this, 'render_category_events_block'),
|
|
'attributes' => array(
|
|
'category' => array('type' => 'string', 'default' => ''),
|
|
'limit' => array('type' => 'number', 'default' => 10),
|
|
'layout' => array('type' => 'string', 'default' => 'grid'),
|
|
'columns' => array('type' => 'number', 'default' => 3),
|
|
'columnsMode' => array('type' => 'string', 'default' => 'fixed'),
|
|
'showImage' => array('type' => 'boolean', 'default' => true),
|
|
'imageType' => array('type' => 'string', 'default' => 'thumbnail'),
|
|
'fullWidth' => array('type' => 'boolean', 'default' => true),
|
|
'align' => array('type' => 'string', 'default' => ''),
|
|
),
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Enqueue editor assets
|
|
*/
|
|
public function enqueue_editor_assets() {
|
|
wp_enqueue_script(
|
|
'ticket-tailor-blocks',
|
|
TICKET_TAILOR_PLUGIN_URL . 'assets/js/blocks.js',
|
|
array('wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-data'),
|
|
TICKET_TAILOR_VERSION,
|
|
true
|
|
);
|
|
|
|
// Pass events data to editor
|
|
$events = $this->events->get_events();
|
|
if (!is_wp_error($events)) {
|
|
$event_options = array();
|
|
foreach ($events as $event) {
|
|
$event_options[] = array(
|
|
'value' => $event['id'],
|
|
'label' => $event['name'],
|
|
);
|
|
}
|
|
|
|
wp_localize_script('ticket-tailor-blocks', 'ticketTailorData', array(
|
|
'events' => $event_options,
|
|
));
|
|
}
|
|
|
|
wp_enqueue_style(
|
|
'ticket-tailor-blocks-editor',
|
|
TICKET_TAILOR_PLUGIN_URL . 'assets/css/blocks-editor.css',
|
|
array('wp-edit-blocks'),
|
|
TICKET_TAILOR_VERSION
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Render event widget block
|
|
*/
|
|
public function render_event_widget_block($attributes) {
|
|
$url = $attributes['url'] ?? '';
|
|
$align = $attributes['align'] ?? '';
|
|
|
|
if (empty($url)) {
|
|
return '<div class="tt-block-placeholder">' . esc_html__('Please enter an event URL', 'ticket-tailor') . '</div>';
|
|
}
|
|
|
|
$minimal = $attributes['minimal'] ?? false;
|
|
$bg_fill = $attributes['bgFill'] ?? true;
|
|
$show_logo = $attributes['showLogo'] ?? true;
|
|
$ref = $attributes['ref'] ?? 'website_widget';
|
|
|
|
// Add alignment class
|
|
$wrapper_class = 'tt-widget-block';
|
|
if (!empty($align)) {
|
|
$wrapper_class .= ' align' . esc_attr($align);
|
|
}
|
|
|
|
// Use shortcode renderer
|
|
$shortcode = new Ticket_Tailor_Shortcodes($this->events, null);
|
|
$widget_html = $shortcode->event_widget_shortcode(array(
|
|
'url' => $url,
|
|
'minimal' => $minimal ? 'true' : 'false',
|
|
'bg_fill' => $bg_fill ? 'true' : 'false',
|
|
'show_logo' => $show_logo ? 'true' : 'false',
|
|
'ref' => $ref,
|
|
));
|
|
|
|
return '<div class="' . esc_attr($wrapper_class) . '">' . $widget_html . '</div>';
|
|
}
|
|
|
|
/**
|
|
* Render event listing block - ENHANCED
|
|
*/
|
|
public function render_event_listing_block($attributes) {
|
|
$limit = $attributes['limit'] ?? 10;
|
|
$layout = $attributes['layout'] ?? 'grid';
|
|
$columns = $attributes['columns'] ?? 3;
|
|
$columns_mode = $attributes['columnsMode'] ?? 'fixed';
|
|
$show_past = $attributes['showPast'] ?? false;
|
|
$show_image = $attributes['showImage'] ?? true;
|
|
$image_type = $attributes['imageType'] ?? 'thumbnail';
|
|
$full_width = $attributes['fullWidth'] ?? true;
|
|
$max_card_width = $attributes['maxCardWidth'] ?? 'none';
|
|
$align = $attributes['align'] ?? '';
|
|
$className = $attributes['className'] ?? '';
|
|
|
|
// Sanitize image type
|
|
if (!in_array($image_type, array('thumbnail', 'header'))) {
|
|
$image_type = 'thumbnail';
|
|
}
|
|
|
|
$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();
|
|
|
|
// Build wrapper classes
|
|
$wrapper_classes = array('tt-event-listing-wrapper');
|
|
if ($full_width) {
|
|
$wrapper_classes[] = 'tt-full-width';
|
|
}
|
|
if (!empty($align)) {
|
|
$wrapper_classes[] = 'align' . esc_attr($align);
|
|
}
|
|
if (!empty($className)) {
|
|
$wrapper_classes[] = esc_attr($className);
|
|
}
|
|
|
|
// Build listing classes
|
|
$class = 'tt-event-listing tt-layout-' . esc_attr($layout);
|
|
if ($layout === 'grid') {
|
|
if ($columns_mode === 'responsive') {
|
|
$class .= ' tt-columns-responsive tt-max-columns-' . esc_attr($columns);
|
|
} else {
|
|
$class .= ' tt-columns-' . esc_attr($columns);
|
|
}
|
|
}
|
|
|
|
// Add inline styles ONLY for responsive mode, not for fixed mode
|
|
$style = '';
|
|
if ($layout === 'grid' && $columns_mode === 'responsive') {
|
|
$min_width = $max_card_width === 'small' ? '280px' :
|
|
($max_card_width === 'medium' ? '350px' :
|
|
($max_card_width === 'large' ? '450px' : '320px'));
|
|
$style = 'style="grid-template-columns: repeat(auto-fit, minmax(' . esc_attr($min_width) . ', 1fr));"';
|
|
}
|
|
// No inline styles for fixed mode - let CSS classes handle it
|
|
?>
|
|
<div class="<?php echo esc_attr(implode(' ', $wrapper_classes)); ?>">
|
|
<div class="<?php echo esc_attr($class); ?>" <?php echo $style; ?>>
|
|
<?php foreach ($events as $event) : ?>
|
|
<div class="tt-event-card">
|
|
<?php if ($show_image && !empty($event['images'][$image_type])) : ?>
|
|
<div class="tt-event-image tt-image-<?php echo esc_attr($image_type); ?>">
|
|
<img src="<?php echo esc_url($event['images'][$image_type]); ?>"
|
|
alt="<?php echo esc_attr($event['name']); ?>"
|
|
loading="lazy">
|
|
</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 if ($layout === 'list' && !empty($event['description'])) : ?>
|
|
<div class="tt-event-excerpt">
|
|
<?php echo esc_html(wp_trim_words($event['description'], 20)); ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php /* REMOVED SPACER - was making cards too tall
|
|
<!-- Spacer pushes button to bottom -->
|
|
<div class="tt-event-spacer"></div>
|
|
*/ ?>
|
|
|
|
<!-- Button container -->
|
|
<?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"
|
|
rel="noopener noreferrer">
|
|
<?php esc_html_e('Get Tickets', 'ticket-tailor'); ?>
|
|
</a>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
|
|
return ob_get_clean();
|
|
}
|
|
|
|
/**
|
|
* Render single event block - ENHANCED
|
|
*/
|
|
public function render_single_event_block($attributes) {
|
|
$event_id = $attributes['eventId'] ?? '';
|
|
$show_description = $attributes['showDescription'] ?? true;
|
|
$show_tickets = $attributes['showTickets'] ?? true;
|
|
$show_image = $attributes['showImage'] ?? true;
|
|
$image_type = $attributes['imageType'] ?? 'header';
|
|
$full_width = $attributes['fullWidth'] ?? false;
|
|
$max_width = $attributes['maxWidth'] ?? '800px';
|
|
$align = $attributes['align'] ?? '';
|
|
|
|
if (empty($event_id)) {
|
|
return '<div class="tt-block-placeholder">' . esc_html__('Please select an event', 'ticket-tailor') . '</div>';
|
|
}
|
|
|
|
// Sanitize image type
|
|
if (!in_array($image_type, array('thumbnail', 'header'))) {
|
|
$image_type = 'thumbnail';
|
|
}
|
|
|
|
$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();
|
|
|
|
// Build wrapper classes
|
|
$wrapper_classes = array('tt-single-event-wrapper');
|
|
if (!empty($align)) {
|
|
$wrapper_classes[] = 'align' . esc_attr($align);
|
|
}
|
|
|
|
// Build inline styles
|
|
$style = '';
|
|
if (!$full_width && !empty($max_width)) {
|
|
$style = 'style="max-width: ' . esc_attr($max_width) . ';"';
|
|
}
|
|
?>
|
|
<div class="<?php echo esc_attr(implode(' ', $wrapper_classes)); ?>">
|
|
<div class="tt-single-event" <?php echo $style; ?>>
|
|
<?php if ($show_image && !empty($event['images'][$image_type])) : ?>
|
|
<div class="tt-event-header-image">
|
|
<img src="<?php echo esc_url($event['images'][$image_type]); ?>"
|
|
alt="<?php echo esc_attr($event['name']); ?>"
|
|
loading="lazy">
|
|
</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']); ?>
|
|
<?php if (!empty($event['venue']['address'])) : ?>
|
|
<br><small style="margin-left: 28px;"><?php echo esc_html($event['venue']['address']); ?></small>
|
|
<?php endif; ?>
|
|
</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 tt-status-<?php echo esc_attr($event['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"
|
|
rel="noopener noreferrer">
|
|
<?php esc_html_e('Buy Tickets', 'ticket-tailor'); ?>
|
|
</a>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
|
|
return ob_get_clean();
|
|
}
|
|
|
|
/**
|
|
* Render category events block - ENHANCED
|
|
*/
|
|
public function render_category_events_block($attributes) {
|
|
$category = $attributes['category'] ?? '';
|
|
$limit = $attributes['limit'] ?? 10;
|
|
$layout = $attributes['layout'] ?? 'grid';
|
|
$columns = $attributes['columns'] ?? 3;
|
|
$columns_mode = $attributes['columnsMode'] ?? 'fixed';
|
|
$show_image = $attributes['showImage'] ?? true;
|
|
$image_type = $attributes['imageType'] ?? 'thumbnail';
|
|
$full_width = $attributes['fullWidth'] ?? true;
|
|
$align = $attributes['align'] ?? '';
|
|
|
|
if (empty($category)) {
|
|
return '<div class="tt-block-placeholder">' . esc_html__('Please select a category', 'ticket-tailor') . '</div>';
|
|
}
|
|
|
|
// Sanitize image type
|
|
if (!in_array($image_type, array('thumbnail', 'header'))) {
|
|
$image_type = 'thumbnail';
|
|
}
|
|
|
|
// Get events by category
|
|
$events = $this->events->get_events_by_category($category);
|
|
|
|
if (is_wp_error($events)) {
|
|
return '<div class="tt-error">' . esc_html($events->get_error_message()) . '</div>';
|
|
}
|
|
|
|
// Limit results
|
|
$events = array_slice($events, 0, $limit);
|
|
|
|
if (empty($events)) {
|
|
return '<div class="tt-no-events">' .
|
|
sprintf(
|
|
/* translators: %s: category name */
|
|
esc_html__('No events found in category: %s', 'ticket-tailor'),
|
|
esc_html($category)
|
|
) .
|
|
'</div>';
|
|
}
|
|
|
|
ob_start();
|
|
|
|
// Build wrapper classes
|
|
$wrapper_classes = array('tt-category-events-wrapper');
|
|
if ($full_width) {
|
|
$wrapper_classes[] = 'tt-full-width';
|
|
}
|
|
if (!empty($align)) {
|
|
$wrapper_classes[] = 'align' . esc_attr($align);
|
|
}
|
|
|
|
// Build listing classes
|
|
$class = 'tt-event-listing tt-category-listing tt-layout-' . esc_attr($layout);
|
|
if ($layout === 'grid') {
|
|
if ($columns_mode === 'responsive') {
|
|
$class .= ' tt-columns-responsive tt-max-columns-' . esc_attr($columns);
|
|
} else {
|
|
$class .= ' tt-columns-' . esc_attr($columns);
|
|
}
|
|
}
|
|
|
|
// Add inline styles ONLY for responsive mode, not for fixed mode
|
|
$style = '';
|
|
if ($layout === 'grid' && $columns_mode === 'responsive') {
|
|
$style = 'style="grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));"';
|
|
}
|
|
// No inline styles for fixed mode - let CSS classes handle it
|
|
?>
|
|
<div class="<?php echo esc_attr(implode(' ', $wrapper_classes)); ?>" data-category="<?php echo esc_attr($category); ?>">
|
|
<div class="tt-category-header">
|
|
<h2 class="tt-category-title">
|
|
<?php
|
|
printf(
|
|
/* translators: %s: category name */
|
|
esc_html__('%s Events', 'ticket-tailor'),
|
|
esc_html(ucfirst($category))
|
|
);
|
|
?>
|
|
</h2>
|
|
</div>
|
|
|
|
<div class="<?php echo esc_attr($class); ?>" <?php echo $style; ?>>
|
|
<?php foreach ($events as $event) : ?>
|
|
<div class="tt-event-card">
|
|
<?php if ($show_image && !empty($event['images'][$image_type])) : ?>
|
|
<div class="tt-event-image tt-image-<?php echo esc_attr($image_type); ?>">
|
|
<img src="<?php echo esc_url($event['images'][$image_type]); ?>"
|
|
alt="<?php echo esc_attr($event['name']); ?>"
|
|
loading="lazy">
|
|
</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 if ($layout === 'list' && !empty($event['description'])) : ?>
|
|
<div class="tt-event-excerpt">
|
|
<?php echo esc_html(wp_trim_words($event['description'], 20)); ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php /* REMOVED SPACER - was making cards too tall
|
|
<!-- Spacer pushes button to bottom -->
|
|
<div class="tt-event-spacer"></div>
|
|
*/ ?>
|
|
|
|
<!-- Button container -->
|
|
<?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"
|
|
rel="noopener noreferrer">
|
|
<?php esc_html_e('Get Tickets', 'ticket-tailor'); ?>
|
|
</a>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
|
|
return ob_get_clean();
|
|
}
|
|
}
|