$attrs Shortcode attributes. * @return string */ public static function render( $attrs = array() ): string { $options = Fontdelbosc_Transit_Plugin::get_options(); $attrs = shortcode_atts( array( 'view' => Fontdelbosc_Transit_Payload::str( $options['default_view'] ?? null ) ?? 'c15', 'max' => (string) ( Fontdelbosc_Transit_Payload::int( $options['max_incidents'] ?? null ) ?? 20 ), 'comarca' => '', ), (array) $attrs, 'fontdelbosc_transit' ); $view = sanitize_key( Fontdelbosc_Transit_Payload::str( $attrs['view'] ) ?? '' ); $max = min( 50, max( 1, Fontdelbosc_Transit_Payload::int( $attrs['max'] ) ?? 20 ) ); $comarcas = Fontdelbosc_Transit_Comarques::keys_from_attr( Fontdelbosc_Transit_Payload::str( $attrs['comarca'] ) ?? '' ); $comarca_labels = array_map( static fn( string $key ): string => Fontdelbosc_Transit_Comarques::label( $key ), $comarcas ); $comarca_label = implode( ', ', $comarca_labels ); if ( 'zbe' === $view ) { return self::render_view( 'zbe-list', array( 'zones' => Fontdelbosc_Transit_Data_Manager::get_zbes() ) ); } $data = Fontdelbosc_Transit_Data_Manager::get_incidents(); if ( null === $data ) { return self::render_view( 'c15' === $view ? 'incidents-c15' : 'incidents-all', array( 'incidents' => array(), 'meta' => array(), 'unavailable' => true, ) ); } $incidents = $data['incidents']; if ( array() !== $comarcas ) { $incidents = array_values( array_filter( $incidents, static fn( array $incident ): bool => in_array( Fontdelbosc_Transit_Comarques::comarca_of( $incident ), $comarcas, true ) ) ); } if ( 'c15' === $view ) { $incidents = array_values( array_filter( $incidents, static fn( array $incident ): bool => Fontdelbosc_Transit_Maps::is_c15( $incident ) ) ); } else { usort( $incidents, static function ( array $a, array $b ): int { $a_c15 = Fontdelbosc_Transit_Maps::is_c15( $a ) ? 0 : 1; $b_c15 = Fontdelbosc_Transit_Maps::is_c15( $b ) ? 0 : 1; if ( $a_c15 !== $b_c15 ) { return $a_c15 <=> $b_c15; } return strcmp( Fontdelbosc_Transit_Payload::str( $b['start_time'] ?? null ) ?? '', Fontdelbosc_Transit_Payload::str( $a['start_time'] ?? null ) ?? '' ); } ); } return self::render_view( 'c15' === $view ? 'incidents-c15' : 'incidents-all', array( 'incidents' => array_slice( $incidents, 0, $max ), 'meta' => array( 'source' => $data['source'], 'publication_time' => $data['publication_time'], ), 'comarca_label' => $comarca_label, ) ); } /** * Render a template by name. * * @param string $name Template name (file name without .php). * @param array $fontdelbosc_data Template data. * @return string */ public static function render_view( string $name, array $fontdelbosc_data ): string { $file = FONTDELBOSC_TRANSIT_DIR . 'templates/' . $name . '.php'; if ( ! is_file( $file ) ) { return ''; } ob_start(); include $file; return (string) ob_get_clean(); } /** * Return the inline SVG markup for an icon key. * * @param string $key Icon key (see templates/icon.php). * @return string Trusted static SVG markup. */ public static function icon( string $key ): string { $fontdelbosc_icon = $key; ob_start(); include FONTDELBOSC_TRANSIT_DIR . 'templates/icon.php'; return (string) ob_get_clean(); } }