'fi-FI', 'sv' => 'sv-FI', 'en' => 'en-FI', ); return $map[ $lang ] ?? 'en-FI'; } /** * Format cents as money for the visitor language ("18,50 €", "€18.50"). * * @param int|null $cents Cents. * @param string $currency ISO code. * @param string $lang fi|sv|en. * @return string */ function bayle_menu_widget_format_money( $cents, string $currency, string $lang ): string { if ( null === $cents ) { return ''; } $amount = $cents / 100; if ( class_exists( 'NumberFormatter' ) ) { $fmt = new NumberFormatter( str_replace( '-', '_', bayle_menu_widget_number_locale( $lang ) ), NumberFormatter::CURRENCY ); $out = $fmt->formatCurrency( $amount, $currency ); if ( is_string( $out ) && '' !== $out ) { return $out; } } $symbols = array( 'EUR' => '€', 'SEK' => 'kr', 'NOK' => 'kr', 'DKK' => 'kr', 'GBP' => '£', 'USD' => '$', ); $symbol = $symbols[ $currency ] ?? $currency; if ( 'en' === $lang ) { return $symbol . number_format( $amount, 2, '.', ',' ); } return number_format( $amount, 2, ',', "\u{00a0}" ) . "\u{00a0}" . $symbol; } /** * Weekday name (ISO 1 = Monday). * * @param int $day 1–7. * @return string */ function bayle_menu_widget_weekday_name( int $day ): string { $names = array( 1 => _x( 'Monday', 'weekday', 'bayle-menu-widget' ), 2 => _x( 'Tuesday', 'weekday', 'bayle-menu-widget' ), 3 => _x( 'Wednesday', 'weekday', 'bayle-menu-widget' ), 4 => _x( 'Thursday', 'weekday', 'bayle-menu-widget' ), 5 => _x( 'Friday', 'weekday', 'bayle-menu-widget' ), 6 => _x( 'Saturday', 'weekday', 'bayle-menu-widget' ), 7 => _x( 'Sunday', 'weekday', 'bayle-menu-widget' ), ); return $names[ $day ] ?? ''; } /** * Format an ISO time in the restaurant's time zone ("16:00", or "Wed 11:00" * when it is not today). * * @param string $iso ISO 8601. * @param array $menu Normalized menu. * @return string */ function bayle_menu_widget_menu_clock( string $iso, array $menu ): string { if ( '' === $iso ) { return ''; } try { $tz = new DateTimeZone( $menu['timezone'] ); $when = ( new DateTimeImmutable( $iso ) )->setTimezone( $tz ); $now = new DateTimeImmutable( 'now', $tz ); } catch ( Exception $e ) { return ''; } // Finnish writes the clock with a dot (18.00). $fi = 0 === strpos( (string) determine_locale(), 'fi' ); $clock = $when->format( 'h12' === $menu['hourCycle'] ? 'g:i A' : ( $fi ? 'H.i' : 'H:i' ) ); if ( $when->format( 'Y-m-d' ) !== $now->format( 'Y-m-d' ) ) { $clock = bayle_menu_widget_weekday_name( (int) $when->format( 'N' ) ) . ' ' . $clock; } return $clock; } /** * Open / closed line, or ''. * * @param array $menu Normalized menu. * @return string */ function bayle_menu_widget_menu_status_text( array $menu ): string { if ( null === $menu['openNow'] ) { return ''; } $next = bayle_menu_widget_menu_clock( $menu['nextChange'], $menu ); if ( $menu['openNow'] ) { /* translators: %s: closing time, e.g. "16:00". */ return '' !== $next ? sprintf( __( 'Open now · closes %s', 'bayle-menu-widget' ), $next ) : __( 'Open now', 'bayle-menu-widget' ); } /* translators: %s: opening time, e.g. "Wednesday 11:00". */ return '' !== $next ? sprintf( __( 'Closed now · opens %s', 'bayle-menu-widget' ), $next ) : __( 'Closed now', 'bayle-menu-widget' ); } /** * Online-ordering line from Bayle's order hours (not opening hours), or ''. * * @param array $menu Normalized menu. * @return string */ function bayle_menu_widget_menu_order_status_text( array $menu ): string { if ( null === ( $menu['orderOpen'] ?? null ) ) { return ''; } $next = bayle_menu_widget_menu_clock( (string) ( $menu['orderNext'] ?? '' ), $menu ); if ( $menu['orderOpen'] ) { /* translators: %s: time online ordering closes, e.g. "21:00". */ return '' !== $next ? sprintf( __( 'Ordering until %s', 'bayle-menu-widget' ), $next ) : __( 'Ordering open now', 'bayle-menu-widget' ); } /* translators: %s: time online ordering opens, e.g. "Saturday 10:00". */ return '' !== $next ? sprintf( __( 'Ordering opens %s', 'bayle-menu-widget' ), $next ) : __( 'Online ordering is closed right now', 'bayle-menu-widget' ); } /** * Bayle's standard diet / allergen codes (food-service DEFAULT_DIETARIES): * code => array( English label, label in the current language ). * * @return array */ function bayle_menu_widget_diet_catalog(): array { return array( 'L' => array( 'Lactose-free', _x( 'Lactose-free', 'diet label', 'bayle-menu-widget' ) ), 'VL' => array( 'Low-lactose', _x( 'Low-lactose', 'diet label', 'bayle-menu-widget' ) ), 'G' => array( 'Gluten-free', _x( 'Gluten-free', 'diet label', 'bayle-menu-widget' ) ), 'M' => array( 'Milk-free', _x( 'Milk-free', 'diet label', 'bayle-menu-widget' ) ), 'V' => array( 'Vegan', _x( 'Vegan', 'diet label', 'bayle-menu-widget' ) ), 'VEG' => array( 'Vegetarian', _x( 'Vegetarian', 'diet label', 'bayle-menu-widget' ) ), 'NV' => array( 'Non-vegetarian', _x( 'Non-vegetarian', 'diet label', 'bayle-menu-widget' ) ), 'P' => array( 'Nut-free', _x( 'Nut-free', 'diet label', 'bayle-menu-widget' ) ), 'EF' => array( 'Egg-free', _x( 'Egg-free', 'diet label', 'bayle-menu-widget' ) ), 'SOYF' => array( 'Soy-free', _x( 'Soy-free', 'diet label', 'bayle-menu-widget' ) ), 'SESF' => array( 'Sesame-free', _x( 'Sesame-free', 'diet label', 'bayle-menu-widget' ) ), 'PORKF' => array( 'Pork-free', _x( 'Pork-free', 'diet label', 'bayle-menu-widget' ) ), 'SUGF' => array( 'Sugar-free', _x( 'Sugar-free', 'diet label', 'bayle-menu-widget' ) ), 'HALAL' => array( 'Halal', _x( 'Halal', 'diet label', 'bayle-menu-widget' ) ), 'KOSHER' => array( 'Kosher', _x( 'Kosher', 'diet label', 'bayle-menu-widget' ) ), 'ORG' => array( 'Organic', _x( 'Organic', 'diet label', 'bayle-menu-widget' ) ), 'S' => array( 'Mildly spicy', _x( 'Mildly spicy', 'diet label', 'bayle-menu-widget' ) ), 'MS' => array( 'Medium spicy', _x( 'Medium spicy', 'diet label', 'bayle-menu-widget' ) ), 'ES' => array( 'Extra spicy', _x( 'Extra spicy', 'diet label', 'bayle-menu-widget' ) ), 'CHILI' => array( 'Contains chili', _x( 'Contains chili', 'diet label', 'bayle-menu-widget' ) ), 'NUT' => array( 'Contains nuts', _x( 'Contains nuts', 'diet label', 'bayle-menu-widget' ) ), 'PNUT' => array( 'Contains peanuts', _x( 'Contains peanuts', 'diet label', 'bayle-menu-widget' ) ), 'GARLIC' => array( 'Contains garlic', _x( 'Contains garlic', 'diet label', 'bayle-menu-widget' ) ), 'ONION' => array( 'Contains onion', _x( 'Contains onion', 'diet label', 'bayle-menu-widget' ) ), 'EGG' => array( 'Contains egg', _x( 'Contains egg', 'diet label', 'bayle-menu-widget' ) ), 'FISH' => array( 'Contains fish', _x( 'Contains fish', 'diet label', 'bayle-menu-widget' ) ), 'SEA' => array( 'Contains seafood', _x( 'Contains seafood', 'diet label', 'bayle-menu-widget' ) ), 'SOY' => array( 'Contains soy', _x( 'Contains soy', 'diet label', 'bayle-menu-widget' ) ), 'SES' => array( 'Contains sesame', _x( 'Contains sesame', 'diet label', 'bayle-menu-widget' ) ), 'CEL' => array( 'Contains celery', _x( 'Contains celery', 'diet label', 'bayle-menu-widget' ) ), 'MUS' => array( 'Contains mustard', _x( 'Contains mustard', 'diet label', 'bayle-menu-widget' ) ), 'SUL' => array( 'Contains sulphites', _x( 'Contains sulphites', 'diet label', 'bayle-menu-widget' ) ), 'LUPIN' => array( 'Contains lupin', _x( 'Contains lupin', 'diet label', 'bayle-menu-widget' ) ), 'GLUTEN' => array( 'Contains gluten', _x( 'Contains gluten', 'diet label', 'bayle-menu-widget' ) ), 'WHEAT' => array( 'Contains wheat', _x( 'Contains wheat', 'diet label', 'bayle-menu-widget' ) ), 'ALCO' => array( 'Contains alcohol', _x( 'Contains alcohol', 'diet label', 'bayle-menu-widget' ) ), 'CAFF' => array( 'Contains caffeine', _x( 'Contains caffeine', 'diet label', 'bayle-menu-widget' ) ), ); } /** * Diet / allergen label in the menu language. * * Bayle's standard codes always use the plugin's own translation, so labels are * consistent and correctly spelled in fi/sv/en. Restaurant-custom codes keep * the label Bayle sent. * * @param string $code Code, e.g. "L". * @param string $api_label Label from Bayle. * @param string $lang fi|sv|en (unused; the menu renders in its own locale). * @return string */ function bayle_menu_widget_diet_label( string $code, string $api_label, string $lang ): string { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed $catalog = bayle_menu_widget_diet_catalog(); return isset( $catalog[ strtoupper( $code ) ] ) ? $catalog[ strtoupper( $code ) ][1] : $api_label; } /** * Where the cart is handed over to Bayle's hosted checkout. * * @param string $order_url Restaurant storefront (links.checkout from Bayle; '' when it has none). * @return string */ function bayle_menu_widget_menu_checkout_url( string $order_url ): string { $url = '' !== $order_url ? trailingslashit( $order_url ) . 'order/' : ''; /** * Filters the Bayle checkout URL the cart is handed over to. * * @param string $url Checkout URL. * @param string $order_url Storefront URL from Bayle. */ return (string) apply_filters( 'bayle_menu_widget_menu_checkout_url', $url, $order_url ); } /** * Render the native menu. * * @param string $slug Slug. * @param string $lang fi|sv|en. * @param array $opts images, categories (bool), layout list|grid, ordering (bool), heading 2–4. * @return string */ function bayle_menu_widget_render_native_menu( string $slug, string $lang, array $opts ): string { $result = bayle_menu_widget_get_menu( $slug, $lang ); bayle_menu_widget_enqueue_menu_assets( false ); if ( null === $result['data'] ) { $msg = 'unavailable' === $result['status'] ? __( 'The menu is not available right now.', 'bayle-menu-widget' ) : __( 'The menu could not be loaded. Please try again in a moment.', 'bayle-menu-widget' ); $out = '

' . esc_html( $msg ) . '

'; if ( 'unavailable' === $result['status'] && current_user_can( 'manage_options' ) ) { $out .= '

' . esc_html__( 'Admins only: check the restaurant slug in Settings → Bayle Menu and that the menu module is on in Bayle.', 'bayle-menu-widget' ) . '

'; } return $out . '
'; } $menu = $result['data']; $menu = bayle_menu_widget_localize_menu_diets( $menu, $lang ); $heading = max( 2, min( 4, (int) ( $opts['heading'] ?? 2 ) ) ); $images = ! empty( $opts['images'] ); $layout = 'grid' === ( $opts['layout'] ?? '' ) ? 'grid' : 'list'; static $instance = 0; ++$instance; $prefix = 'bayle-menu-' . $instance; // Ordering: on only when Bayle says so (links.order), the owner has not // switched it off, and this block allows it. $order_url = (string) ( $menu['orderUrl'] ?? '' ); $checkout = bayle_menu_widget_menu_checkout_url( (string) ( $menu['checkoutBase'] ?? $order_url ) ); // One checkout path: the in-site dialog, or Bayle's hosted page when the owner // chose it and the restaurant has a storefront to hand the cart to. $in_frame = bayle_menu_widget_checkout_in_site() || '' === $checkout; $ordering = '' !== $order_url && ! empty( $opts['ordering'] ) && bayle_menu_widget_menu_ordering_setting(); $ctx = array( 'menu' => $menu, 'lang' => $lang, 'images' => $images, 'ordering' => $ordering, 'prefix' => $prefix, 'seq' => 0, 'dishes' => array(), 'link' => $order_url, 'inFrame' => $in_frame, ); $sections = array(); $nav = array(); // Lunch: today first, the rest of the week folded away (no script needed). if ( null !== $menu['lunch'] ) { $lunch_id = $prefix . '-lunch'; $nav[] = array( $lunch_id, __( 'Lunch', 'bayle-menu-widget' ) ); $html = '
'; $html .= '' . esc_html__( 'Lunch', 'bayle-menu-widget' ) . ''; $lunch = $menu['lunch']; if ( '' !== $lunch['weekday'] && '' !== $lunch['weekend'] ) { /* translators: 1: weekday lunch hours, 2: weekend lunch hours, e.g. "11:00–15:00". */ $html .= '

' . esc_html( sprintf( __( 'Lunch on weekdays %1$s, weekends %2$s', 'bayle-menu-widget' ), $lunch['weekday'], $lunch['weekend'] ) ) . '

'; } elseif ( '' !== $lunch['weekday'] ) { /* translators: %s: lunch hours, e.g. "11:00–15:00". */ $html .= '

' . esc_html( sprintf( __( 'Lunch on weekdays %s', 'bayle-menu-widget' ), $lunch['weekday'] ) ) . '

'; } $today = $lunch['today'] ? $lunch['today'] : (int) ( new DateTimeImmutable( 'now', new DateTimeZone( $menu['timezone'] ) ) )->format( 'N' ); $order = array(); for ( $i = 0; $i < 7; $i++ ) { $order[] = ( ( $today - 1 + $i ) % 7 ) + 1; } $rest = ''; foreach ( $order as $day ) { if ( empty( $lunch['days'][ $day ] ) ) { continue; } $label = bayle_menu_widget_weekday_name( $day ); if ( $day === $today ) { /* translators: %s: weekday name. */ $label = sprintf( __( 'Today · %s', 'bayle-menu-widget' ), $label ); } $h = $heading + 1; $part = '
' . esc_html( $label ) . '' . bayle_menu_widget_render_menu_items( $lunch['days'][ $day ], $h + 1, $ctx ) . '
'; if ( $day === $today ) { $html .= $part; } else { $rest .= $part; } } if ( '' !== $rest ) { $html .= '
' . esc_html__( 'Lunch for the rest of the week', 'bayle-menu-widget' ) . '' . $rest . '
'; } foreach ( $menu['notes'] as $note ) { if ( 'lunch' === $note['scope'] ) { $html .= '

' . esc_html( $note['text'] ) . '

'; } } $sections[] = $html . '
'; } // À la carte by category, in Bayle's order; unknown categories last. if ( $menu['items'] ) { $by_cat = array(); $known = array(); foreach ( $menu['categories'] as $cat ) { $known[ $cat['key'] ] = true; } foreach ( $menu['items'] as $item ) { $key = isset( $known[ $item['category'] ] ) ? $item['category'] : '_other'; $by_cat[ $key ][] = $item; } $cats = $menu['categories']; if ( ! empty( $by_cat['_other'] ) ) { $cats[] = array( 'key' => '_other', 'name' => __( 'À la carte', 'bayle-menu-widget' ), 'description' => '', ); } foreach ( $cats as $cat ) { if ( empty( $by_cat[ $cat['key'] ] ) ) { continue; } $id = $prefix . '-' . sanitize_html_class( $cat['key'] ); $name = '' !== $cat['name'] ? $cat['name'] : __( 'À la carte', 'bayle-menu-widget' ); $nav[] = array( $id, $name ); $html = '
'; $html .= '' . esc_html( $name ) . ''; if ( '' !== $cat['description'] ) { $html .= '

' . esc_html( $cat['description'] ) . '

'; } $html .= bayle_menu_widget_render_menu_items( $by_cat[ $cat['key'] ], $heading + 1, $ctx ); $sections[] = $html . '
'; } } $classes = array( 'bayle-menu-widget', 'bayle-restaurant--menu', 'bayle-menu', 'bayle-menu--' . $layout, 'is-loaded' ); $orderable = ! empty( $ctx['dishes'] ); if ( $orderable ) { $classes[] = 'bayle-menu--ordering'; } $out = '
'; if ( $result['stale'] ) { $out .= '

' . esc_html__( 'Showing a saved copy of the menu because the latest one could not be loaded right now.', 'bayle-menu-widget' ) . '

'; } $status = bayle_menu_widget_menu_status_text( $menu ); $order_status = $orderable ? bayle_menu_widget_menu_order_status_text( $menu ) : ''; if ( '' !== $status || '' !== $order_status || ( $ordering && ! $orderable ) ) { $out .= '
'; if ( '' !== $status ) { $out .= '

' . esc_html( $status ) . '

'; } if ( '' !== $order_status ) { $out .= '

' . esc_html( $order_status ) . '

'; } if ( $ordering && ! $orderable ) { // Bayle has ordering on but does not expose orderable dishes to // this site yet: the only order path is the restaurant's Bayle // ordering page (its own storefront or its Bayle marketplace page). $out .= ''; } $out .= '
'; } if ( ! empty( $opts['categories'] ) && count( $nav ) > 1 ) { $out .= ''; } $out .= implode( '', $sections ); $notes = array(); foreach ( $menu['notes'] as $note ) { if ( 'lunch' !== $note['scope'] ) { $notes[] = '

' . esc_html( $note['text'] ) . '

'; } } $out .= implode( '', $notes ); if ( '' !== $menu['updatedAt'] ) { $ts = strtotime( $menu['updatedAt'] ); if ( $ts ) { /* translators: %s: date the menu was last updated. */ $out .= '

' . esc_html( sprintf( __( 'Menu updated %s', 'bayle-menu-widget' ), wp_date( get_option( 'date_format' ), $ts, new DateTimeZone( $menu['timezone'] ) ) ) ) . '

'; } } if ( $orderable ) { $out .= bayle_menu_widget_menu_order_data( $ctx, $checkout ); bayle_menu_widget_enqueue_menu_assets( true, $ctx['inFrame'] ); } return $out . '
'; } /** * Dish list. * * @param array $items Normalized items. * @param int $level Heading level for dish names. * @param array $ctx Render context (by reference: collects orderable dishes). * @return string */ function bayle_menu_widget_render_menu_items( array $items, int $level, array &$ctx ): string { $level = min( 6, $level ); $menu = $ctx['menu']; $lang = $ctx['lang']; $out = ''; } /** * Data for the cart script (JSON, not executable). * * @param array $ctx Render context. * @param string $checkout Bayle checkout URL. * @return string */ function bayle_menu_widget_menu_order_data( array $ctx, string $checkout ): string { $menu = $ctx['menu']; $data = array( 'slug' => $menu['slug'], 'currency' => $menu['currency'], 'locale' => bayle_menu_widget_number_locale( $ctx['lang'] ), 'lang' => $ctx['lang'], 'checkout' => esc_url_raw( $checkout ), // In-site checkout: Bayle's menu page in checkout-only mode, framed in a dialog. 'frame' => ! empty( $ctx['inFrame'] ) ? esc_url_raw( bayle_menu_widget_build_src( (string) $menu['slug'], bayle_menu_widget_resolve_base_url(), $ctx['lang'], true ) ) : '', 'checkoutT' => bayle_menu_widget_checkout_i18n(), 'back' => esc_url_raw( get_permalink() ? get_permalink() : home_url( '/' ) ), 'address' => $menu['address'], 'status' => bayle_menu_widget_menu_status_text( $menu ), 'open' => (bool) $menu['openNow'], // The cart shows ordering hours; opening hours ('status') only if Bayle sent none. 'orderStatus' => bayle_menu_widget_menu_order_status_text( $menu ), 'dishes' => $ctx['dishes'], 'i18n' => array( 'add' => __( 'Add to order', 'bayle-menu-widget' ), /* translators: %s: total price. */ 'addFor' => __( 'Add to order · %s', 'bayle-menu-widget' ), 'close' => __( 'Close', 'bayle-menu-widget' ), 'qty' => __( 'Quantity', 'bayle-menu-widget' ), 'less' => __( 'One less', 'bayle-menu-widget' ), 'more' => __( 'One more', 'bayle-menu-widget' ), 'size' => __( 'Size', 'bayle-menu-widget' ), 'allergens' => __( 'Allergens and diets', 'bayle-menu-widget' ), 'askStaff' => __( 'Ask the restaurant about allergens before ordering.', 'bayle-menu-widget' ), /* translators: %s: dish name. */ 'added' => __( 'Added to your order: %s', 'bayle-menu-widget' ), 'yourOrder' => __( 'Your order', 'bayle-menu-widget' ), 'view' => __( 'View order', 'bayle-menu-widget' ), /* translators: %d: number of items. */ 'items1' => __( '%d item', 'bayle-menu-widget' ), /* translators: %d: number of items. */ 'itemsN' => __( '%d items', 'bayle-menu-widget' ), 'remove' => __( 'Remove', 'bayle-menu-widget' ), 'empty' => __( 'Your order is empty.', 'bayle-menu-widget' ), 'subtotal' => __( 'Subtotal', 'bayle-menu-widget' ), 'pickupOnly' => __( 'Pickup only', 'bayle-menu-widget' ), /* translators: %s: restaurant address. */ 'pickupAt' => __( 'Pick up at %s', 'bayle-menu-widget' ), 'nextStep' => __( 'On the next step you choose a pickup time and pay on Bayle’s secure checkout. Prices are confirmed there.', 'bayle-menu-widget' ), 'checkout' => __( 'Continue to checkout', 'bayle-menu-widget' ), 'leaving' => __( 'Opens Bayle checkout', 'bayle-menu-widget' ), 'nextHere' => __( 'On the next step you choose a pickup time and pay securely with Bayle, without leaving this page. Prices are confirmed there.', 'bayle-menu-widget' ), 'paid' => __( 'Thank you! Your order is in. You can close the checkout.', 'bayle-menu-widget' ), 'clear' => __( 'Empty order', 'bayle-menu-widget' ), 'extras' => __( 'Extras', 'bayle-menu-widget' ), /* translators: %d: how many extras the guest may pick at most. */ 'upTo' => __( 'Optional, choose up to %d', 'bayle-menu-widget' ), /* translators: %d: how many extras the guest must pick. */ 'exactly' => __( 'Required, choose %d', 'bayle-menu-widget' ), /* translators: 1: fewest extras to pick, 2: most extras to pick. */ 'between' => __( 'Required, choose %1$d to %2$d', 'bayle-menu-widget' ), /* translators: %d: most extras the guest may pick. */ 'maxReached' => __( 'You have chosen the maximum of %d.', 'bayle-menu-widget' ), /* translators: %s: name of the group of extras, e.g. "Sauce". */ 'needChoice' => __( 'Please make a choice: %s', 'bayle-menu-widget' ), /* translators: %s: price an extra adds, e.g. "1,00 €". */ 'plusPrice' => __( '+%s', 'bayle-menu-widget' ), 'with' => __( 'With', 'bayle-menu-widget' ), 'tooBig' => __( 'This order is too large to send in one go. Remove a dish or some extras and try again.', 'bayle-menu-widget' ), ), ); return ''; } /** * Enqueue menu CSS (and the cart script when dishes can be ordered). * * @param bool $with_script Also enqueue the ordering script. * @param bool|null $in_frame Checkout opens in the in-site dialog (null: the Checkout setting). */ function bayle_menu_widget_enqueue_menu_assets( bool $with_script, ?bool $in_frame = null ): void { wp_enqueue_style( 'bayle-menu-widget-menu' ); if ( $with_script ) { if ( null === $in_frame ? bayle_menu_widget_checkout_in_site() : $in_frame ) { bayle_menu_widget_enqueue_checkout_assets(); } wp_enqueue_script( 'bayle-menu-widget-menu-order' ); } } /** * Register menu assets (enqueued only where a native menu renders). */ function bayle_menu_widget_register_menu_assets(): void { wp_register_style( 'bayle-menu-widget-menu', plugins_url( 'assets/menu.css', BAYLE_MENU_WIDGET_FILE ), array(), BAYLE_MENU_WIDGET_VERSION ); wp_register_script( 'bayle-menu-widget-menu-order', plugins_url( 'assets/menu-order.js', BAYLE_MENU_WIDGET_FILE ), array(), BAYLE_MENU_WIDGET_VERSION, array( 'in_footer' => true, 'strategy' => 'defer', ) ); } /** * Replace diet labels with labels in the menu language. * * @param array $menu Normalized menu. * @param string $lang fi|sv|en. * @return array */ function bayle_menu_widget_localize_menu_diets( array $menu, string $lang ): array { $fix = static function ( array $items ) use ( $lang ): array { foreach ( $items as $i => $item ) { foreach ( $item['diets'] as $j => $diet ) { $items[ $i ]['diets'][ $j ]['label'] = bayle_menu_widget_diet_label( $diet['code'], $diet['label'], $lang ); } } return $items; }; $menu['items'] = $fix( $menu['items'] ); if ( null !== $menu['lunch'] ) { foreach ( $menu['lunch']['days'] as $day => $items ) { $menu['lunch']['days'][ $day ] = $fix( $items ); } } return $menu; } /** * WordPress locale for a menu language. * * @param string $lang fi|sv|en. * @return string */ function bayle_menu_widget_lang_locale( string $lang ): string { $map = array( 'fi' => 'fi', 'sv' => 'sv_SE', 'en' => 'en_US', ); return $map[ $lang ] ?? 'en_US'; }