$incident Normalized incident. * @return bool */ public static function is_c15( array $incident ): bool { $road = self::normalize_road( Fontdelbosc_Transit_Payload::str( $incident['road_name'] ?? null ) ?? '' ); if ( 'C15' === $road || 'EIXGARRAF' === substr( $road, 0, 9 ) ) { return true; } $title = Fontdelbosc_Transit_Payload::str( $incident['title'] ?? null ) ?? ''; $description = Fontdelbosc_Transit_Payload::str( $incident['description'] ?? null ) ?? ''; $haystack = $title . ' ' . $description; // Word boundary required: C-153 and C-155 are different roads. return 1 === preg_match( '/C-?15\b/i', $haystack ) || false !== stripos( $haystack, 'eix garraf' ); } /** * Normalize a road name for comparison (uppercase, no spaces or hyphens). * * @param string $road Raw road name. * @return string */ private static function normalize_road( string $road ): string { return strtoupper( preg_replace( '/[\s\-]+/u', '', $road ) ?? '' ); } /** * Format an ISO or RSS timestamp as a local date-time string. * * @param string $time Raw timestamp. * @return string Empty when unparseable. */ public static function format_time( string $time ): string { if ( '' === $time ) { return ''; } $ts = strtotime( $time ); if ( false === $ts ) { return ''; } $formatted = wp_date( 'j M Y H:i', $ts ); return is_string( $formatted ) ? $formatted : ''; } /** * Human "last updated" line from a raw timestamp. * * @param string $time Raw timestamp. * @return string Empty when unparseable. */ public static function last_updated( string $time ): string { if ( '' === $time ) { return ''; } $ts = strtotime( $time ); return false === $ts ? '' : sprintf( /* translators: %s: human-readable time difference. */ __( 'Last updated: %s ago', 'fontdelbosc-transit' ), human_time_diff( $ts, time() ) ); } }