This commit is contained in:
Javier Casares 2026-10-12 15:30:04 +00:00
commit 1ef08bd731
27 changed files with 4854 additions and 0 deletions

42
templates/icon.php Normal file
View file

@ -0,0 +1,42 @@
<?php
/**
* Inline SVG icons, stroke-based, inherit currentColor.
*
* @package Fontdelbosc_Transit
*
* @var string $fontdelbosc_icon Icon key.
*/
defined( 'ABSPATH' ) || exit;
$fontdelbosc_icon = isset( $fontdelbosc_icon ) ? $fontdelbosc_icon : 'incident';
?>
<?php if ( 'works' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><path d="M12 3 5 20h14L12 3z"/><path d="M8.7 13.5h6.6"/><path d="M10.4 9h1.1"/></svg>
<?php elseif ( 'accident' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><path d="M7.86 2h8.28L22 7.86v8.28L16.14 22H7.86L2 16.14V7.86L7.86 2z"/><path d="M12 8v4"/><path d="M12 16h.01"/></svg>
<?php elseif ( 'congestion' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><path d="M4 6h16"/><path d="M4 11h11"/><path d="M4 16h6"/></svg>
<?php elseif ( 'obstruction' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><path d="M5 21V9"/><path d="M19 21V9"/><rect x="3" y="4" width="18" height="5" rx="1"/><path d="M7 4 5 9"/><path d="M12 4l-2 5"/><path d="M17 4l-2 5"/></svg>
<?php elseif ( 'weather' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><path d="M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z"/><path d="M8 20v1.5"/><path d="M12 19v2.5"/><path d="M16 20v1.5"/></svg>
<?php elseif ( 'assistance' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
<?php elseif ( 'management' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><rect x="8" y="3" width="8" height="18" rx="3.5"/><path d="M12 6.5v.01"/><path d="M12 11v.01"/><path d="M12 15.5v.01"/></svg>
<?php elseif ( 'restriction' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M5.64 5.64 18.36 18.36"/></svg>
<?php elseif ( 'zbe' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><path d="M20 4c0 9-5 13-11 13H5c0-8 6-12 15-13z"/><path d="M4 21c2.5-6.5 6.5-10 12-12.5"/></svg>
<?php elseif ( 'clock' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="14" height="14" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>
<?php elseif ( 'check' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="26" height="26" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="m8.5 12.5 2.5 2.5 5-6"/></svg>
<?php elseif ( 'info' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="26" height="26" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M12 11v5"/><path d="M12 8h.01"/></svg>
<?php elseif ( 'external' === $fontdelbosc_icon ) : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="12" height="12" aria-hidden="true" focusable="false"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><path d="M15 3h6v6"/><path d="M10 14 21 3"/></svg>
<?php else : ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" width="22" height="22" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M12 8v4"/><path d="M12 16h.01"/></svg>
<?php endif; ?>

119
templates/incident-card.php Normal file
View file

@ -0,0 +1,119 @@
<?php
/**
* Incident card partial.
*
* @package Fontdelbosc_Transit
*
* @var array<string, mixed> $fontdelbosc_incident Normalized incident.
*/
defined( 'ABSPATH' ) || exit;
$fontdelbosc_incident = isset( $fontdelbosc_incident ) ? $fontdelbosc_incident : array();
$fontdelbosc_is_c15 = Fontdelbosc_Transit_Maps::is_c15( $fontdelbosc_incident );
$fontdelbosc_type = (string) ( $fontdelbosc_incident['type'] ?? '' );
$fontdelbosc_key = Fontdelbosc_Transit_Maps::type_key( $fontdelbosc_type );
$fontdelbosc_title = (string) ( $fontdelbosc_incident['title'] ?? '' );
if ( '' === $fontdelbosc_title ) {
$fontdelbosc_title = Fontdelbosc_Transit_Maps::type_label( $fontdelbosc_type );
}
// The RSS title ends with the incident type in parentheses; redundant here.
$fontdelbosc_title = trim( (string) preg_replace( '/\s*\([^)]*\)$/', '', $fontdelbosc_title ) );
$fontdelbosc_meta_items = array();
if ( '' !== (string) ( $fontdelbosc_incident['direction'] ?? '' ) ) {
$fontdelbosc_meta_items[] = array(
'label' => Fontdelbosc_Transit_Maps::direction_label( (string) $fontdelbosc_incident['direction'] ),
'icon' => '',
);
}
if ( '' !== (string) ( $fontdelbosc_incident['start_time'] ?? '' ) ) {
$fontdelbosc_time = sprintf(
/* translators: %s: start date and time. */
__( 'Start: %s', 'fontdelbosc-transit' ),
Fontdelbosc_Transit_Maps::format_time( (string) $fontdelbosc_incident['start_time'] )
);
if ( '' !== (string) ( $fontdelbosc_incident['end_time'] ?? '' ) ) {
$fontdelbosc_time .= sprintf(
/* translators: %s: end date and time. */
' — ' . __( 'End: %s', 'fontdelbosc-transit' ),
Fontdelbosc_Transit_Maps::format_time( (string) $fontdelbosc_incident['end_time'] )
);
}
$fontdelbosc_meta_items[] = array(
'label' => $fontdelbosc_time,
'icon' => 'clock',
);
}
if ( '' !== (string) ( $fontdelbosc_incident['impact'] ?? '' ) ) {
$fontdelbosc_meta_items[] = array(
'label' => Fontdelbosc_Transit_Maps::impact_label( (string) $fontdelbosc_incident['impact'] ),
'icon' => '',
'impact' => true,
);
}
?>
<article class="fdbt-card fdbt-card--<?php echo esc_attr( $fontdelbosc_key ); ?><?php echo $fontdelbosc_is_c15 ? ' fdbt-card--c15' : ''; ?>">
<header class="fdbt-card__head">
<span class="fdbt-card__type fdbt-type--<?php echo esc_attr( $fontdelbosc_key ); ?>">
<span class="fdbt-icon fdbt-icon--<?php echo esc_attr( $fontdelbosc_key ); ?>" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( $fontdelbosc_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<?php echo esc_html( Fontdelbosc_Transit_Maps::type_label( $fontdelbosc_type ) ); ?>
</span>
<?php if ( '' !== (string) ( $fontdelbosc_incident['status'] ?? '' ) ) : ?>
<span class="fdbt-card__status"><span class="fdbt-dot" aria-hidden="true"></span><?php echo esc_html( Fontdelbosc_Transit_Maps::status_label( (string) $fontdelbosc_incident['status'] ) ); ?></span>
<?php endif; ?>
</header>
<p class="fdbt-card__title"><?php echo esc_html( $fontdelbosc_title ); ?></p>
<?php if ( '' !== (string) ( $fontdelbosc_incident['road_name'] ?? '' ) || '' !== (string) ( $fontdelbosc_incident['town'] ?? '' ) || '' !== (string) ( $fontdelbosc_incident['km'] ?? '' ) ) : ?>
<p class="fdbt-card__place">
<?php
$fontdelbosc_place = array();
if ( '' !== (string) $fontdelbosc_incident['road_name'] ) {
$fontdelbosc_place[] = '<strong>' . esc_html( (string) $fontdelbosc_incident['road_name'] ) . '</strong>';
}
if ( '' !== (string) $fontdelbosc_incident['town'] ) {
$fontdelbosc_place[] = esc_html( (string) $fontdelbosc_incident['town'] );
}
if ( '' !== (string) $fontdelbosc_incident['km'] ) {
$fontdelbosc_place[] = esc_html( sprintf( /* translators: %s: kilometre point. */ __( 'km %s', 'fontdelbosc-transit' ), (string) $fontdelbosc_incident['km'] ) );
}
echo implode( ' · ', $fontdelbosc_place ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- parts escaped above.
?>
</p>
<?php endif; ?>
<?php if ( array() !== $fontdelbosc_meta_items ) : ?>
<ul class="fdbt-card__meta">
<?php foreach ( $fontdelbosc_meta_items as $fontdelbosc_meta_item ) : ?>
<li class="fdbt-card__meta-item<?php echo ! empty( $fontdelbosc_meta_item['impact'] ) ? ' fdbt-card__meta-item--impact' : ''; ?>">
<?php if ( 'clock' === $fontdelbosc_meta_item['icon'] ) : ?>
<span class="fdbt-meta__icon" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'clock' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<?php endif; ?>
<?php echo esc_html( $fontdelbosc_meta_item['label'] ); ?>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if ( '' !== (string) ( $fontdelbosc_incident['link'] ?? '' ) ) : ?>
<p class="fdbt-card__link">
<a href="<?php echo esc_url( (string) $fontdelbosc_incident['link'] ); ?>" target="_blank" rel="nofollow noopener">
<?php esc_html_e( 'View at the SCT information centre', 'fontdelbosc-transit' ); ?>
<span class="fdbt-link__icon" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'external' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
</a>
</p>
<?php endif; ?>
</article>

View file

@ -0,0 +1,54 @@
<?php
/**
* All Catalunya incidents view (C-15 first).
*
* @package Fontdelbosc_Transit
*
* @var array<string, mixed> $fontdelbosc_data Template data.
*/
defined( 'ABSPATH' ) || exit;
$fontdelbosc_incidents = $fontdelbosc_data['incidents'] ?? array();
$fontdelbosc_meta = $fontdelbosc_data['meta'] ?? array();
$fontdelbosc_unavailable = ! empty( $fontdelbosc_data['unavailable'] );
$fontdelbosc_scope = Fontdelbosc_Transit_Payload::str( $fontdelbosc_data['comarca_label'] ?? null ) ?? '';
?>
<section class="fdbt fdbt--all">
<h2 class="fdbt__title">
<?php esc_html_e( 'All Catalunya traffic', 'fontdelbosc-transit' ); ?>
<?php if ( '' !== $fontdelbosc_scope ) : ?>
<span class="fdbt__scope">— <?php echo esc_html( $fontdelbosc_scope ); ?></span>
<?php endif; ?>
<?php if ( ! $fontdelbosc_unavailable && array() !== $fontdelbosc_incidents ) : ?>
<span class="fdbt-count">
<?php
/* translators: %s: number of incidents. */
echo esc_html( '(' . sprintf( _n( '%s incident', '%s incidents', count( $fontdelbosc_incidents ), 'fontdelbosc-transit' ), number_format_i18n( count( $fontdelbosc_incidents ) ) ) ) . ')';
?>
</span>
<?php endif; ?>
</h2>
<?php if ( $fontdelbosc_unavailable ) : ?>
<p class="fdbt__empty fdbt__empty--unavailable">
<span class="fdbt-empty__icon fdbt-empty__icon--muted" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'info' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<?php esc_html_e( 'Data unavailable.', 'fontdelbosc-transit' ); ?>
</p>
<?php elseif ( array() === $fontdelbosc_incidents ) : ?>
<p class="fdbt__empty">
<span class="fdbt-empty__icon fdbt-empty__icon--ok" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'check' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<?php esc_html_e( 'No incidents reported.', 'fontdelbosc-transit' ); ?>
</p>
<?php else : ?>
<div class="fdbt-grid">
<?php
foreach ( $fontdelbosc_incidents as $fontdelbosc_incident ) {
include FONTDELBOSC_TRANSIT_DIR . 'templates/incident-card.php';
}
?>
</div>
<?php endif; ?>
<?php include FONTDELBOSC_TRANSIT_DIR . 'templates/source-footer.php'; ?>
</section>

View file

@ -0,0 +1,54 @@
<?php
/**
* C-15 incidents view (highlighted).
*
* @package Fontdelbosc_Transit
*
* @var array<string, mixed> $fontdelbosc_data Template data.
*/
defined( 'ABSPATH' ) || exit;
$fontdelbosc_incidents = $fontdelbosc_data['incidents'] ?? array();
$fontdelbosc_meta = $fontdelbosc_data['meta'] ?? array();
$fontdelbosc_unavailable = ! empty( $fontdelbosc_data['unavailable'] );
$fontdelbosc_scope = Fontdelbosc_Transit_Payload::str( $fontdelbosc_data['comarca_label'] ?? null ) ?? '';
?>
<section class="fdbt fdbt--c15">
<h2 class="fdbt__title">
<?php esc_html_e( 'Traffic on C-15', 'fontdelbosc-transit' ); ?>
<?php if ( '' !== $fontdelbosc_scope ) : ?>
<span class="fdbt__scope">— <?php echo esc_html( $fontdelbosc_scope ); ?></span>
<?php endif; ?>
<?php if ( ! $fontdelbosc_unavailable && array() !== $fontdelbosc_incidents ) : ?>
<span class="fdbt-count">
<?php
/* translators: %s: number of incidents. */
echo esc_html( '(' . sprintf( _n( '%s incident', '%s incidents', count( $fontdelbosc_incidents ), 'fontdelbosc-transit' ), number_format_i18n( count( $fontdelbosc_incidents ) ) ) ) . ')';
?>
</span>
<?php endif; ?>
</h2>
<?php if ( $fontdelbosc_unavailable ) : ?>
<p class="fdbt__empty fdbt__empty--unavailable">
<span class="fdbt-empty__icon fdbt-empty__icon--muted" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'info' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<?php esc_html_e( 'Data unavailable.', 'fontdelbosc-transit' ); ?>
</p>
<?php elseif ( array() === $fontdelbosc_incidents ) : ?>
<p class="fdbt__empty">
<span class="fdbt-empty__icon fdbt-empty__icon--ok" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'check' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<?php esc_html_e( 'No incidents on C-15.', 'fontdelbosc-transit' ); ?>
</p>
<?php else : ?>
<div class="fdbt-grid">
<?php
foreach ( $fontdelbosc_incidents as $fontdelbosc_incident ) {
include FONTDELBOSC_TRANSIT_DIR . 'templates/incident-card.php';
}
?>
</div>
<?php endif; ?>
<?php include FONTDELBOSC_TRANSIT_DIR . 'templates/source-footer.php'; ?>
</section>

View file

@ -0,0 +1,33 @@
<?php
/**
* Source footer: last updated + mandatory attribution.
*
* @package Fontdelbosc_Transit
*
* @var array<string, mixed> $fontdelbosc_meta Source metadata.
*/
defined( 'ABSPATH' ) || exit;
$fontdelbosc_meta = $fontdelbosc_data['meta'] ?? array();
?>
<footer class="fdbt-footer">
<?php
$fontdelbosc_updated = isset( $fontdelbosc_meta['publication_time'] )
? Fontdelbosc_Transit_Maps::last_updated( (string) $fontdelbosc_meta['publication_time'] )
: '';
if ( '' !== $fontdelbosc_updated ) :
?>
<p class="fdbt-footer__updated"><?php echo esc_html( $fontdelbosc_updated ); ?></p>
<?php endif; ?>
<p class="fdbt-footer__source">
<?php
printf(
/* translators: %s: source name. */
esc_html__( 'Source: %s', 'fontdelbosc-transit' ),
'<a href="https://cit.transit.gencat.cat" target="_blank" rel="nofollow noopener">' . esc_html__( 'Servei Català de Trànsit (SCT) / DGT', 'fontdelbosc-transit' ) . '</a>'
);
?>
</p>
</footer>

112
templates/zbe-list.php Normal file
View file

@ -0,0 +1,112 @@
<?php
/**
* ZBE cards view.
*
* @package Fontdelbosc_Transit
*
* @var array<string, mixed> $fontdelbosc_data Template data.
*/
defined( 'ABSPATH' ) || exit;
$fontdelbosc_zones = $fontdelbosc_data['zones'] ?? array();
$fontdelbosc_options = Fontdelbosc_Transit_Plugin::get_options();
?>
<section class="fdbt fdbt--zbe">
<h2 class="fdbt__title">
<?php esc_html_e( 'Low Emission Zones (ZBE)', 'fontdelbosc-transit' ); ?>
<?php if ( array() !== $fontdelbosc_zones ) : ?>
<span class="fdbt-count">
<?php
/* translators: %s: number of zones. */
echo esc_html( '(' . sprintf( _n( '%s zone', '%s zones', count( $fontdelbosc_zones ), 'fontdelbosc-transit' ), number_format_i18n( count( $fontdelbosc_zones ) ) ) . ')' );
?>
</span>
<?php endif; ?>
</h2>
<?php if ( ! empty( $fontdelbosc_options['show_zbe_2026_notice'] ) ) : ?>
<div class="fdbt-notice">
<span class="fdbt-notice__icon" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'info' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<p><?php esc_html_e( 'From 1 January 2026, label B vehicles are banned in Catalan ZBEs when high-pollution protocols are activated.', 'fontdelbosc-transit' ); ?></p>
</div>
<?php endif; ?>
<?php if ( array() === $fontdelbosc_zones ) : ?>
<p class="fdbt__empty fdbt__empty--unavailable">
<span class="fdbt-empty__icon fdbt-empty__icon--muted" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'info' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<?php esc_html_e( 'Data unavailable.', 'fontdelbosc-transit' ); ?>
</p>
<?php else : ?>
<div class="fdbt-grid">
<?php foreach ( $fontdelbosc_zones as $fontdelbosc_zone ) : ?>
<?php $fontdelbosc_stickers = Fontdelbosc_Transit_Payload::arr( $fontdelbosc_zone['stickers'] ?? null ); ?>
<article class="fdbt-card fdbt-card--zbe">
<header class="fdbt-card__head">
<span class="fdbt-card__type fdbt-type--zbe">
<span class="fdbt-icon fdbt-icon--zbe" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'zbe' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<?php esc_html_e( 'Low Emission Zone', 'fontdelbosc-transit' ); ?>
</span>
<?php if ( 'active' === (string) ( $fontdelbosc_zone['status'] ?? '' ) ) : ?>
<span class="fdbt-card__status"><span class="fdbt-dot" aria-hidden="true"></span><?php esc_html_e( 'Active', 'fontdelbosc-transit' ); ?></span>
<?php endif; ?>
</header>
<p class="fdbt-card__title"><?php echo esc_html( (string) $fontdelbosc_zone['name'] ); ?></p>
<?php if ( array() !== $fontdelbosc_stickers ) : ?>
<p class="fdbt-card__chips">
<?php
/* translators: %s: list of restricted vehicle labels. */
esc_html_e( 'Restricted vehicle types:', 'fontdelbosc-transit' );
?>
<?php foreach ( $fontdelbosc_stickers as $fontdelbosc_sticker ) : ?>
<span class="fdbt-chip fdbt-chip--<?php echo esc_attr( Fontdelbosc_Transit_Maps::sticker_class( (string) $fontdelbosc_sticker ) ); ?>"><?php echo esc_html( Fontdelbosc_Transit_Maps::sticker_label( (string) $fontdelbosc_sticker ) ); ?></span>
<?php endforeach; ?>
</p>
<?php endif; ?>
<?php foreach ( Fontdelbosc_Transit_Payload::arr( $fontdelbosc_zone['periods'] ?? null ) as $fontdelbosc_period ) : ?>
<?php
if ( ! is_array( $fontdelbosc_period ) ) {
continue; }
?>
<p class="fdbt-card__meta-item fdbt-card__meta-item--hours">
<span class="fdbt-meta__icon" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'clock' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
<?php
printf(
/* translators: 1: days, 2: start time, 3: end time. */
esc_html__( 'Operating hours: %1$s %2$s–%3$s', 'fontdelbosc-transit' ),
esc_html( (string) $fontdelbosc_period['days'] ),
esc_html( (string) $fontdelbosc_period['start'] ),
esc_html( (string) $fontdelbosc_period['end'] )
);
?>
</p>
<?php endforeach; ?>
<?php if ( '' !== (string) ( $fontdelbosc_zone['url'] ?? '' ) ) : ?>
<p class="fdbt-card__link">
<a href="<?php echo esc_url( (string) $fontdelbosc_zone['url'] ); ?>" target="_blank" rel="nofollow noopener">
<?php esc_html_e( 'Municipal regulations', 'fontdelbosc-transit' ); ?>
<span class="fdbt-link__icon" aria-hidden="true"><?php echo Fontdelbosc_Transit_Shortcode::icon( 'external' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG markup. ?></span>
</a>
</p>
<?php endif; ?>
</article>
<?php endforeach; ?>
</div>
<?php endif; ?>
<footer class="fdbt-footer">
<p class="fdbt-footer__source">
<?php
printf(
/* translators: %s: source name. */
esc_html__( 'Source: %s', 'fontdelbosc-transit' ),
'<a href="https://nap.dgt.es/dataset/zonas-de-bajas-emisiones" target="_blank" rel="nofollow noopener">' . esc_html__( 'DGT / Punt d\'Accés Nacional', 'fontdelbosc-transit' ) . '</a>'
);
?>
</p>
</footer>
</section>