upskill-event-manager/includes/class-hvac-breadcrumbs.php
bengizmo 70b78a069f feat: Add navigation menu system and breadcrumb functionality
- Implemented comprehensive trainer navigation system:
  * Horizontal and vertical navigation layouts
  * Multi-level menu with dropdowns for Events, Venues, Organizers, Profile
  * Responsive mobile navigation with hamburger menu
  * Keyboard navigation support (Arrow keys, Enter, Escape)
  * Active page highlighting
  * Master trainer menu items for users with appropriate role

- Created breadcrumb system:
  * Automatic breadcrumb generation based on URL structure
  * Shortcode support [hvac_breadcrumbs]
  * SEO-friendly with structured data (Schema.org)
  * Multiple style options (default, pills, arrows)
  * Responsive design

- Technical implementation:
  * HVAC_Trainer_Navigation class for menu management
  * HVAC_Breadcrumbs class for breadcrumb generation
  * CSS for both navigation and breadcrumbs
  * JavaScript for interactive menu behaviors
  * Template part for easy inclusion

Navigation provides easy access to all trainer features and improves UX.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 16:45:58 -03:00

267 lines
No EOL
9.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* HVAC Breadcrumbs System
*
* @package HVAC_Community_Events
* @since 2.0.0
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* HVAC_Breadcrumbs class
*/
class HVAC_Breadcrumbs {
/**
* Constructor
*/
public function __construct() {
// Register shortcode
add_shortcode('hvac_breadcrumbs', array($this, 'render_breadcrumbs'));
// Auto-add breadcrumbs to trainer pages
add_action('hvac_after_page_header', array($this, 'display_breadcrumbs'));
// Enqueue styles
add_action('wp_enqueue_scripts', array($this, 'enqueue_styles'));
}
/**
* Enqueue breadcrumb styles
*/
public function enqueue_styles() {
if ($this->should_show_breadcrumbs()) {
wp_enqueue_style(
'hvac-breadcrumbs',
HVAC_PLUGIN_URL . 'assets/css/hvac-breadcrumbs.css',
array(),
HVAC_PLUGIN_VERSION
);
}
}
/**
* Get breadcrumb trail
*/
private function get_breadcrumb_trail() {
$trail = array();
$current_url = home_url(add_query_arg(array(), $GLOBALS['wp']->request));
// Always start with home
$trail[] = array(
'label' => 'Home',
'url' => home_url('/')
);
// Check if we're on a trainer page
if (strpos($current_url, '/trainer/') !== false) {
$trail[] = array(
'label' => 'Trainer',
'url' => '/trainer/dashboard/'
);
// Parse the current path
$path = parse_url($current_url, PHP_URL_PATH);
$path = trim($path, '/');
$segments = explode('/', $path);
// Remove 'trainer' from segments as we've already added it
array_shift($segments);
// Build breadcrumb based on URL segments
if (!empty($segments)) {
$breadcrumb_map = $this->get_breadcrumb_map();
$current_path = '/trainer';
foreach ($segments as $index => $segment) {
$current_path .= '/' . $segment;
// Check if we have a mapping for this path
if (isset($breadcrumb_map[$current_path])) {
$is_last = ($index === count($segments) - 1);
$trail[] = array(
'label' => $breadcrumb_map[$current_path]['label'],
'url' => $is_last ? null : $current_path . '/',
'current' => $is_last
);
}
}
}
} elseif (strpos($current_url, '/master-trainer/') !== false) {
$trail[] = array(
'label' => 'Master Trainer',
'url' => '/master-trainer/master-dashboard/'
);
// Similar logic for master trainer pages
$path = parse_url($current_url, PHP_URL_PATH);
$path = trim($path, '/');
$segments = explode('/', $path);
array_shift($segments); // Remove 'master-trainer'
if (!empty($segments)) {
$breadcrumb_map = $this->get_breadcrumb_map();
$current_path = '/master-trainer';
foreach ($segments as $index => $segment) {
$current_path .= '/' . $segment;
if (isset($breadcrumb_map[$current_path])) {
$is_last = ($index === count($segments) - 1);
$trail[] = array(
'label' => $breadcrumb_map[$current_path]['label'],
'url' => $is_last ? null : $current_path . '/',
'current' => $is_last
);
}
}
}
} elseif (strpos($current_url, '/trainer-registration/') !== false) {
$trail[] = array(
'label' => 'Registration',
'url' => null,
'current' => true
);
}
// Allow filtering of breadcrumb trail
return apply_filters('hvac_breadcrumb_trail', $trail, $current_url);
}
/**
* Get breadcrumb mapping
*/
private function get_breadcrumb_map() {
return array(
// Trainer pages
'/trainer/dashboard' => array('label' => 'Dashboard'),
'/trainer/event' => array('label' => 'Events'),
'/trainer/event/manage' => array('label' => 'Manage Event'),
'/trainer/event-summary' => array('label' => 'Event Summary'),
'/trainer/generate-certificates' => array('label' => 'Generate Certificates'),
'/trainer/certificate-reports' => array('label' => 'Certificate Reports'),
'/trainer/venue' => array('label' => 'Venues'),
'/trainer/venue/list' => array('label' => 'List'),
'/trainer/venue/manage' => array('label' => 'Manage'),
'/trainer/organizer' => array('label' => 'Organizers'),
'/trainer/organizer/list' => array('label' => 'List'),
'/trainer/organizer/manage' => array('label' => 'Manage'),
'/trainer/profile' => array('label' => 'Profile'),
'/trainer/profile/edit' => array('label' => 'Edit'),
// Master trainer pages
'/master-trainer/master-dashboard' => array('label' => 'Master Dashboard'),
'/master-trainer/trainers' => array('label' => 'All Trainers'),
'/master-trainer/reports' => array('label' => 'Global Reports')
);
}
/**
* Render breadcrumbs shortcode
*/
public function render_breadcrumbs($atts = array()) {
$atts = shortcode_atts(array(
'separator' => '',
'show_home' => 'yes',
'home_label' => 'Home',
'class' => 'hvac-breadcrumb'
), $atts);
$trail = $this->get_breadcrumb_trail();
if (empty($trail)) {
return '';
}
// Remove home if requested
if ($atts['show_home'] === 'no' && !empty($trail)) {
array_shift($trail);
} else if (!empty($trail) && $atts['home_label'] !== 'Home') {
$trail[0]['label'] = $atts['home_label'];
}
ob_start();
?>
<nav class="<?php echo esc_attr($atts['class']); ?>" aria-label="Breadcrumb">
<ol class="hvac-breadcrumb-list">
<?php foreach ($trail as $index => $item): ?>
<li class="hvac-breadcrumb-item<?php echo isset($item['current']) && $item['current'] ? ' hvac-breadcrumb-current' : ''; ?>">
<?php if (!empty($item['url']) && (!isset($item['current']) || !$item['current'])): ?>
<a href="<?php echo esc_url($item['url']); ?>" class="hvac-breadcrumb-link">
<?php echo esc_html($item['label']); ?>
</a>
<?php else: ?>
<span class="hvac-breadcrumb-text" aria-current="page">
<?php echo esc_html($item['label']); ?>
</span>
<?php endif; ?>
<?php if ($index < count($trail) - 1): ?>
<span class="hvac-breadcrumb-separator" aria-hidden="true">
<?php echo esc_html($atts['separator']); ?>
</span>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ol>
</nav>
<?php
return ob_get_clean();
}
/**
* Display breadcrumbs automatically
*/
public function display_breadcrumbs() {
if ($this->should_show_breadcrumbs()) {
echo do_shortcode('[hvac_breadcrumbs]');
}
}
/**
* Check if breadcrumbs should be shown
*/
private function should_show_breadcrumbs() {
// Show on all trainer and master trainer pages
$current_url = home_url(add_query_arg(array(), $GLOBALS['wp']->request));
return strpos($current_url, '/trainer/') !== false ||
strpos($current_url, '/master-trainer/') !== false ||
strpos($current_url, '/trainer-registration/') !== false;
}
/**
* Get structured data for breadcrumbs (SEO)
*/
public function get_structured_data() {
$trail = $this->get_breadcrumb_trail();
if (empty($trail)) {
return '';
}
$items = array();
foreach ($trail as $index => $item) {
$items[] = array(
'@type' => 'ListItem',
'position' => $index + 1,
'name' => $item['label'],
'item' => !empty($item['url']) ? home_url($item['url']) : null
);
}
$structured_data = array(
'@context' => 'https://schema.org',
'@type' => 'BreadcrumbList',
'itemListElement' => $items
);
return '<script type="application/ld+json">' . json_encode($structured_data, JSON_UNESCAPED_SLASHES) . '</script>';
}
}