| 1 |
<?php |
| 2 |
if (!defined('ABSPATH')) { |
| 3 |
exit; |
| 4 |
} |
| 5 |
|
| 6 |
// Trip Attributes Section for Single Trip Page |
| 7 |
// Expected variables: $trip |
| 8 |
?> |
| 9 |
<div class="yatra-trip-attributes"> |
| 10 |
<div class="yatra-section-header"> |
| 11 |
<h2 class="yatra-section-title"><?php echo esc_html__('Trip Attributes', 'yatra'); ?></h2> |
| 12 |
<p class="yatra-section-description"><?php echo esc_html__('Key features and characteristics', 'yatra'); ?></p> |
| 13 |
</div> |
| 14 |
|
| 15 |
<div class="yatra-spec-sheet yatra-spec-sheet--attributes-grid"> |
| 16 |
<div class="yatra-attributes-grid"> |
| 17 |
<?php foreach ($trip->getAttributes() as $attribute): ?> |
| 18 |
<div class="yatra-attribute-item"> |
| 19 |
<div class="yatra-attribute-icon"> |
| 20 |
<?php if ($attribute['icon']): ?> |
| 21 |
<?php if ($attribute['icon']['type'] === 'image'): ?> |
| 22 |
<img src="<?php echo esc_url($attribute['icon']['value']); ?>" alt="<?php echo esc_attr($attribute['name']); ?>" class="yatra-attribute-icon-img"> |
| 23 |
<?php else: ?> |
| 24 |
<?php |
| 25 |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 26 |
echo yatra_stored_picker_icon_markup($attribute['icon'], 'info', 'yatra-icon'); |
| 27 |
?> |
| 28 |
<?php endif; ?> |
| 29 |
<?php else: ?> |
| 30 |
<?php echo yatra_svg_icon('tag', 'yatra-icon'); ?> |
| 31 |
<?php endif; ?> |
| 32 |
</div> |
| 33 |
|
| 34 |
<div class="yatra-attribute-content"> |
| 35 |
<div class="yatra-attribute-name"><?php echo esc_html($attribute['name']); ?></div> |
| 36 |
<div class="yatra-attribute-value"> |
| 37 |
<?php |
| 38 |
// Display value based on field type |
| 39 |
switch ($attribute['field_type']) { |
| 40 |
case 'checkbox': |
| 41 |
$cb_val = $attribute['value'] ?? null; |
| 42 |
$cb_options = json_decode($attribute['field_options'] ?? '[]', true); |
| 43 |
if (!is_array($cb_options)) { |
| 44 |
$cb_options = []; |
| 45 |
} |
| 46 |
if (is_array($cb_val)) { |
| 47 |
$labels = []; |
| 48 |
foreach ($cb_options as $opt) { |
| 49 |
if (!isset($opt['value'], $opt['label'])) { |
| 50 |
continue; |
| 51 |
} |
| 52 |
foreach ($cb_val as $v) { |
| 53 |
if ((string) $v === (string) $opt['value']) { |
| 54 |
$labels[] = $opt['label']; |
| 55 |
break; |
| 56 |
} |
| 57 |
} |
| 58 |
} |
| 59 |
echo esc_html($labels !== [] ? implode(', ', $labels) : '—'); |
| 60 |
} else { |
| 61 |
echo $cb_val ? esc_html__('Yes', 'yatra') : esc_html__('No', 'yatra'); |
| 62 |
} |
| 63 |
break; |
| 64 |
case 'select': |
| 65 |
case 'radio': |
| 66 |
$options = json_decode($attribute['field_options'] ?? '[]', true); |
| 67 |
if (!is_array($options)) { |
| 68 |
$options = []; |
| 69 |
} |
| 70 |
$selected_value = is_array($attribute['value']) ? ($attribute['value'][0] ?? null) : ($attribute['value'] ?? null); |
| 71 |
$matched_label = null; |
| 72 |
foreach ($options as $option) { |
| 73 |
if (!is_array($option) || !isset($option['value'], $option['label'])) { |
| 74 |
continue; |
| 75 |
} |
| 76 |
if ((string) $option['value'] === (string) $selected_value) { |
| 77 |
$matched_label = (string) $option['label']; |
| 78 |
break; |
| 79 |
} |
| 80 |
} |
| 81 |
if ($matched_label !== null) { |
| 82 |
echo esc_html($matched_label); |
| 83 |
} elseif ($selected_value !== null && $selected_value !== '') { |
| 84 |
echo esc_html((string) $selected_value); |
| 85 |
} else { |
| 86 |
echo esc_html('—'); |
| 87 |
} |
| 88 |
break; |
| 89 |
case 'date': |
| 90 |
echo esc_html(date_i18n(get_option('date_format'), strtotime($attribute['value']))); |
| 91 |
break; |
| 92 |
case 'time': |
| 93 |
echo esc_html(date_i18n(get_option('time_format'), strtotime($attribute['value']))); |
| 94 |
break; |
| 95 |
case 'color': |
| 96 |
echo '<span class="yatra-color-swatch" style="background-color: ' . esc_attr($attribute['value']) . ';" title="' . esc_attr($attribute['value']) . '"></span>' . esc_html($attribute['value']); |
| 97 |
break; |
| 98 |
case 'url': |
| 99 |
case 'file': |
| 100 |
$link = (string) ($attribute['value'] ?? ''); |
| 101 |
if ($link !== '' && filter_var($link, FILTER_VALIDATE_URL)) { |
| 102 |
echo '<a href="' . esc_url($link) . '" target="_blank" rel="noopener noreferrer">' . esc_html($link) . '</a>'; |
| 103 |
} else { |
| 104 |
echo esc_html($link !== '' ? $link : '—'); |
| 105 |
} |
| 106 |
break; |
| 107 |
case 'email': |
| 108 |
echo '<a href="mailto:' . esc_attr($attribute['value']) . '">' . esc_html($attribute['value']) . '</a>'; |
| 109 |
break; |
| 110 |
case 'textarea': |
| 111 |
// Truncate long textareas for compact display |
| 112 |
$text = wp_strip_all_tags((string) ($attribute['value'] ?? '')); |
| 113 |
$snippet = function_exists('mb_substr') ? mb_substr($text, 0, 50) : substr($text, 0, 50); |
| 114 |
$long = function_exists('mb_strlen') ? mb_strlen($text) : strlen($text); |
| 115 |
echo esc_html($snippet . ($long > 50 ? '...' : '')); |
| 116 |
break; |
| 117 |
case 'number': |
| 118 |
$nv = $attribute['value'] ?? null; |
| 119 |
echo esc_html(is_numeric($nv) ? (string) (0 + $nv) : (string) $nv); |
| 120 |
break; |
| 121 |
case 'text_field': |
| 122 |
default: |
| 123 |
$raw = $attribute['value'] ?? ''; |
| 124 |
if (is_array($raw)) { |
| 125 |
$flat = []; |
| 126 |
foreach ($raw as $piece) { |
| 127 |
$flat[] = is_scalar($piece) ? (string) $piece : ''; |
| 128 |
} |
| 129 |
echo esc_html(implode(', ', array_filter($flat, static fn ($s) => $s !== ''))); |
| 130 |
} else { |
| 131 |
$text = wp_strip_all_tags((string) $raw); |
| 132 |
$snippet = function_exists('mb_substr') ? mb_substr($text, 0, 30) : substr($text, 0, 30); |
| 133 |
$long = function_exists('mb_strlen') ? mb_strlen($text) : strlen($text); |
| 134 |
echo esc_html($snippet . ($long > 30 ? '...' : '')); |
| 135 |
} |
| 136 |
break; |
| 137 |
} |
| 138 |
?> |
| 139 |
</div> |
| 140 |
<?php if (!empty($attribute['description'])): ?> |
| 141 |
<div class="yatra-attribute-description"><?php echo esc_html(substr($attribute['description'], 0, 40) . (strlen($attribute['description']) > 40 ? '...' : '')); ?></div> |
| 142 |
<?php endif; ?> |
| 143 |
</div> |
| 144 |
</div> |
| 145 |
<?php endforeach; ?> |
| 146 |
</div> |
| 147 |
</div> |
| 148 |
</div> |