array( 'type' => 'string', 'default' => '' ), 'roosterBadge' => array( 'type' => 'string', 'default' => '' ), 'roosterAccent' => array( 'type' => 'string', 'default' => '' ), 'roosterSeparator' => array( 'type' => 'string', 'default' => '' ), 'roosterGroup' => array( 'type' => 'string', 'default' => '' ), 'roosterColumn' => array( 'type' => 'integer', 'default' => 0 ), 'roosterPlace' => array( 'type' => 'string', 'default' => '' ), ); if ( 'core/navigation-submenu' === $name ) { $attributes['roosterImage'] = array( 'type' => 'integer', 'default' => 0 ); $attributes['roosterLayout'] = array( 'type' => 'string', 'default' => '' ); $metadata['providesContext'] = array_merge( (array) ( $metadata['providesContext'] ?? array() ), array( self::CONTEXT => 'roosterLayout' ) ); } $metadata['usesContext'] = array_values( array_unique( array_merge( (array) ( $metadata['usesContext'] ?? array() ), array( self::CONTEXT ) ) ) ); $metadata['attributes'] = array_merge( (array) ( $metadata['attributes'] ?? array() ), $attributes ); return $metadata; } public static function placed_entry( $html, $block, $instance = null ) { $html = (string) $html; if ( '' === $html || ! $instance instanceof WP_Block || self::MEGA !== ( $instance->context[ self::CONTEXT ] ?? '' ) ) { return $html; } $block = (array) $block; $place = (string) ( $block['attrs']['roosterPlace'] ?? '' ); if ( 'feature' === $place ) { return ''; } if ( 'foot' !== $place && 'foot-end' !== $place ) { return $html; } if ( '' === self::address( $block ) ) { return ''; } if ( false === strpos( $html, self::TOKEN_FREE_SHIPPING ) ) { return $html; } $amount = self::free_shipping(); return '' === $amount ? '' : str_replace( self::TOKEN_FREE_SHIPPING, esc_html( $amount ), $html ); } public static function version() { return max( 1, (int) get_option( self::OPTION, 1 ) ); } private static function dir() { $uploads = wp_upload_dir( null, false ); return array( 'path' => rtrim( (string) $uploads['basedir'], '/\\' ) . '/' . self::DIR, 'url' => rtrim( (string) $uploads['baseurl'], '/' ) . '/' . self::DIR ); } public static function file_path( $version ) { return self::dir()['path'] . '/menu-' . (int) $version . '.json'; } public static function file_url( $version ) { $version = (int) $version; if ( is_file( self::file_path( $version ) ) ) { return self::dir()['url'] . '/menu-' . $version . '.json'; } return add_query_arg( self::QUERY, $version, home_url( '/' ) ); } public static function on_save( $post_id, $post, $update = true ) { if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) || ! $post instanceof WP_Post || 'auto-draft' === $post->post_status ) { return; } self::regenerate(); } public static function on_delete( $post_id, $post = null ) { if ( $post instanceof WP_Post && 'wp_navigation' === $post->post_type ) { self::regenerate(); } } public static function on_shipping( $old, $new ) { $was = is_array( $old ) ? $old : array(); $now = is_array( $new ) ? $new : array(); if ( (float) ( $was['free_shipping_threshold'] ?? 0 ) === (float) ( $now['free_shipping_threshold'] ?? 0 ) && (string) ( $was['enabled'] ?? '' ) === (string) ( $now['enabled'] ?? '' ) ) { return; } foreach ( get_posts( array( 'post_type' => 'wp_navigation', 'post_status' => 'publish', 'posts_per_page' => 50, 'no_found_rows' => true ) ) as $post ) { if ( false !== strpos( (string) $post->post_content, self::TOKEN_FREE_SHIPPING ) ) { self::regenerate(); return; } } } public static function regenerate() { self::$data = null; $version = self::version() + 1; $data = self::data( $version ); $dir = self::dir()['path']; $written = false; $fs = self::filesystem(); if ( $fs && wp_mkdir_p( $dir ) && wp_is_writable( $dir ) ) { $written = $fs->put_contents( self::file_path( $version ), (string) wp_json_encode( $data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ), FS_CHMOD_FILE ); } update_option( self::OPTION, $version, true ); delete_transient( self::TRANSIENT . ( $version - 1 ) ); if ( $written ) { foreach ( glob( $dir . '/menu-*.json' ) ?: array() as $file ) { if ( preg_match( '/menu-(\d+)\.json$/', $file, $m ) && (int) $m[1] <= $version - self::KEEP ) { wp_delete_file( $file ); } } } do_action( 'rooster/menu/regenerated', $version, $written ); return $version; } public static function serve() { if ( ! isset( $_GET[ self::QUERY ] ) ) { return; } $version = absint( wp_unslash( $_GET[ self::QUERY ] ) ); header( 'X-Robots-Tag: noindex' ); if ( $version !== self::version() ) { nocache_headers(); wp_send_json( array( 'version' => self::version() ), 404 ); } $data = get_transient( self::TRANSIENT . $version ); if ( ! is_array( $data ) || ! isset( $data['panels'] ) ) { $data = self::data( $version ); set_transient( self::TRANSIENT . $version, $data, MONTH_IN_SECONDS ); } header( 'Cache-Control: public, max-age=31536000, immutable' ); wp_send_json( $data, 200, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); } private static function filesystem() { global $wp_filesystem; if ( ! function_exists( 'WP_Filesystem' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } if ( ! $wp_filesystem instanceof WP_Filesystem_Base && ! WP_Filesystem() ) { return null; } return $wp_filesystem instanceof WP_Filesystem_Base ? $wp_filesystem : null; } public static function data( $version = null ) { if ( null === $version ) { $version = self::version(); } if ( is_array( self::$data ) && self::$data['version'] === (int) $version ) { return self::$data; } $panels = array(); $posts = get_posts( array( 'post_type' => 'wp_navigation', 'post_status' => 'publish', 'posts_per_page' => 50, 'orderby' => 'name', 'order' => 'ASC', 'no_found_rows' => true ) ); foreach ( $posts as $post ) { $blocks = self::items( $post ); if ( ! $blocks ) { continue; } $placed = array(); $whole = $blocks; foreach ( $blocks as $i => $block ) { if ( 'core/navigation-submenu' === $block['blockName'] && self::MEGA === (string) ( $block['attrs']['roosterLayout'] ?? '' ) ) { $placed[ $i ] = self::places( $block ); $whole[ $i ]['innerBlocks'] = $placed[ $i ]['phone']; } } $panels[ $post->post_name ] = array( 'label' => (string) $post->post_title, 'html' => self::panel( $post, $whole, self::layout( $post ) ) ) + self::phone( $post, $whole, true ); foreach ( self::submenu_keys( $post, $blocks ) as $i => $key ) { $block = $blocks[ $i ]; $named = (string) ( $block['attrs']['roosterLayout'] ?? '' ); if ( self::MEGA === $named ) { $parts = $placed[ $i ]; $panels[ $key ] = array( 'label' => (string) ( $block['attrs']['label'] ?? '' ), 'html' => self::mega( $post, $block, $parts ), ) + self::phone( $post, array( array( 'innerBlocks' => $parts['phone'] ) + $block ), false ); continue; } $deep = self::deep( $block ); $layout = 'list'; if ( $deep && 'list' !== $named && ( '' !== $named || self::rows( $block ) > self::LIST_ROWS ) ) { $layout = 'columns'; } $nested = $deep && 'columns' === $layout; $panels[ $key ] = array( 'label' => (string) ( $block['attrs']['label'] ?? '' ), 'html' => self::panel( $post, $nested ? self::entries( $block ) : array( $block ), $layout, false, $nested ), ) + self::phone( $post, array( $block ), false ); } } self::$data = array( 'version' => (int) $version, 'panels' => $panels ); return self::$data; } private static function entries( array $block ) { return array_values( array_filter( (array) ( $block['innerBlocks'] ?? array() ), static function ( $b ) { return in_array( (string) ( $b['blockName'] ?? '' ), array( 'core/navigation-link', 'core/navigation-submenu' ), true ); } ) ); } public static function rows( array $block ) { $rows = 0; foreach ( self::entries( $block ) as $entry ) { $rows += 1 + ( 'core/navigation-submenu' === $entry['blockName'] ? count( self::entries( $entry ) ) : 0 ); } return $rows; } public static function deep( array $block ) { foreach ( self::entries( $block ) as $entry ) { if ( 'core/navigation-submenu' === $entry['blockName'] && self::entries( $entry ) ) { return true; } } return false; } public static function submenu_keys( WP_Post $post, array $items ) { $keys = array(); $used = array(); foreach ( array_values( $items ) as $i => $block ) { if ( 'core/navigation-submenu' !== $block['blockName'] || empty( $block['innerBlocks'] ) ) { continue; } $key = $post->post_name . '#' . sanitize_title( (string) ( $block['attrs']['label'] ?? '' ) ); if ( in_array( $key, $used, true ) || '#' === substr( $key, -1 ) ) { $key .= '-' . $i; } $used[] = $key; $keys[ $i ] = $key; } return $keys; } public static function items( WP_Post $post ) { return array_values( array_filter( parse_blocks( (string) $post->post_content ), static function ( $b ) { return in_array( (string) ( $b['blockName'] ?? '' ), array( 'core/navigation-link', 'core/navigation-submenu' ), true ); } ) ); } public static function layout( WP_Post $post ) { $layout = (string) get_post_meta( $post->ID, self::META_LAYOUT, true ); if ( '' === $layout && (int) get_post_meta( $post->ID, self::META_IMAGE, true ) > 0 ) { $layout = 'featured'; } return in_array( $layout, self::LAYOUTS, true ) ? $layout : 'columns'; } public static function family( WP_Post $post ) { return sanitize_key( (string) get_post_meta( $post->ID, self::META_FAMILY, true ) ); } public static function panel( WP_Post $post, array $blocks, $layout, $head = true, $linked = false ) { $layout = in_array( (string) $layout, self::LAYOUTS, true ) ? (string) $layout : 'columns'; $family = self::family( $post ); $html = $head ? self::card( $post, $blocks, $family ) : ''; $columns = ''; $loose = ''; $count = 0; if ( $linked ) { foreach ( self::stacks( $blocks ) as $stack ) { ++$count; $column = ''; foreach ( $stack as $block ) { $column .= self::group( $block ); } $columns .= '
' . $column . '
'; } $blocks = array(); } foreach ( $blocks as $block ) { if ( 'core/navigation-submenu' === $block['blockName'] && 'list' !== $layout ) { ++$count; $items = ''; foreach ( (array) $block['innerBlocks'] as $child ) { $items .= self::item( $child ); } $columns .= '

' . esc_html( (string) ( $block['attrs']['label'] ?? '' ) ) . '

' . '
'; continue; } if ( 'core/navigation-submenu' === $block['blockName'] ) { foreach ( (array) $block['innerBlocks'] as $child ) { $loose .= self::item( $child, true ); } continue; } $loose .= self::item( $block ); } if ( '' !== $loose ) { ++$count; $columns .= '
'; } $compact = $linked && $count <= self::COMPACT_COLUMNS ? ' is-compact is-cols-' . max( 1, $count ) : ''; $html .= '
' . $columns . '
'; $html = (string) apply_filters( 'rooster/menu/panel', $html, $post, $layout ); return '
' . $html . '
'; } public static function stacks( array $blocks ) { $named = false; foreach ( $blocks as $block ) { $named = $named || (int) ( $block['attrs']['roosterColumn'] ?? 0 ) > 0; } $stacks = array(); $at = 0; foreach ( $blocks as $block ) { $column = (int) ( $block['attrs']['roosterColumn'] ?? 0 ); if ( $named ) { $at = $column > 0 ? $column : max( 1, $at ); } elseif ( 0 === $at || ( 'core/navigation-submenu' === $block['blockName'] && self::entries( $block ) ) ) { $at = count( $stacks ) + 1; } $stacks[ $at ][] = $block; } ksort( $stacks ); return array_values( $stacks ); } private static function group( array $block ) { $name = trim( (string) ( $block['attrs']['label'] ?? '' ) ); if ( '' === $name ) { return ''; } $address = (string) ( $block['attrs']['url'] ?? '' ); $items = ''; if ( 'core/navigation-submenu' === $block['blockName'] ) { foreach ( self::entries( $block ) as $child ) { $items .= self::item( $child ); } } return '

' . ( '' !== $address ? '' . esc_html( $name ) . '' : esc_html( $name ) ) . '

' . ( '' !== $items ? '' : '' ); } private static function places( array $block ) { $parts = array( 'columns' => array(), 'feature' => null, 'foot' => array(), 'foot-end' => array(), 'phone' => array() ); foreach ( self::entries( $block ) as $entry ) { $place = (string) ( $entry['attrs']['roosterPlace'] ?? '' ); if ( 'feature' === $place && null === $parts['feature'] ) { $parts['feature'] = $entry; continue; } if ( 'foot' === $place || 'foot-end' === $place ) { $entry['attrs']['label'] = self::tokens( (string) ( $entry['attrs']['label'] ?? '' ) ); if ( '' === trim( $entry['attrs']['label'] ) ) { continue; } $parts[ $place ][] = $entry; if ( '' !== self::address( $entry ) ) { $parts['phone'][] = $entry; } continue; } $parts['columns'][] = $entry; $entry['attrs']['url'] = self::address( $entry ); $parts['phone'][] = $entry; } return $parts; } public static function mega( WP_Post $post, array $block, ?array $parts = null ) { $parts = $parts ?? self::places( $block ); $family = self::family( $post ); $deep = false; foreach ( $parts['columns'] as $entry ) { $deep = $deep || ( 'core/navigation-submenu' === $entry['blockName'] && self::entries( $entry ) ); } $columns = ''; foreach ( self::stacks( $parts['columns'] ) as $stack ) { $column = ''; foreach ( $stack as $entry ) { $entry['attrs']['url'] = self::address( $entry ); $column .= $deep ? self::group( $entry ) : self::item( $entry ); } if ( '' !== $column ) { $columns .= '
' . ( $deep ? $column : '' ) . '
'; } } $card = self::feature( $block, $parts['feature'] ); $body = ( '' !== $columns ? '
' . $columns . '
' : '' ) . $card; $foot = ''; foreach ( array( 'foot' => '', 'foot-end' => ' is-end' ) as $place => $class ) { $items = ''; foreach ( $parts[ $place ] as $entry ) { $items .= self::foot_item( $entry ); } if ( '' !== $items ) { $foot .= ''; } } $html = ( '' !== $body ? '
' . $body . '
' : '' ) . ( '' !== $foot ? '
' . $foot . '
' : '' ); $html = (string) apply_filters( 'rooster/menu/panel', $html, $post, self::MEGA ); return '
' . $html . '
'; } private static function feature( array $block, ?array $entry ) { $image = (int) ( $block['attrs']['roosterImage'] ?? 0 ); if ( $image <= 0 && $entry ) { $image = self::picture( $entry ); } if ( $image <= 0 ) { $image = self::picture( $block ); } $art = ''; if ( $image > 0 ) { $img = wp_get_attachment_image( $image, 'medium_large', false, array( 'class' => 'rooster-mega__feature-img', 'alt' => '', 'loading' => 'lazy', 'decoding' => 'async', 'sizes' => '(min-width: 64rem) 24rem, 80vw' ) ); $art = '' !== $img ? '' . $img . '' : ''; } $from = $entry ?? $block; $title = trim( (string) ( $from['attrs']['label'] ?? '' ) ); $line = $entry ? trim( (string) ( $entry['attrs']['description'] ?? '' ) ) : ''; if ( ( '' === $art && ! $entry ) || ( '' === $art && '' === $title ) ) { return ''; } $linked = '' !== $title && '' !== self::address( $from ); $words = ( '' !== $title ? '' . ( $linked ? '' . esc_html( $title ) . '' : esc_html( $title ) ) . '' : '' ) . ( '' !== $line ? '' . esc_html( $line ) . '' : '' ); if ( $linked ) { return '' . $art . $words . ''; } return '
' . $art . $words . '
'; } public static function picture( array $block ) { $id = (int) ( $block['attrs']['id'] ?? 0 ); $kind = (string) ( $block['attrs']['kind'] ?? '' ); $image = 0; if ( $id > 0 && 'taxonomy' === $kind ) { $image = (int) get_term_meta( $id, 'thumbnail_id', true ); } elseif ( $id > 0 && 'post-type' === $kind ) { $image = (int) get_post_thumbnail_id( $id ); } return max( 0, (int) apply_filters( 'rooster/menu/picture', $image, $block ) ); } private static function foot_item( array $block ) { $label = trim( (string) ( $block['attrs']['label'] ?? '' ) ); if ( '' === $label ) { return ''; } $icon = sanitize_key( (string) ( $block['attrs']['roosterIcon'] ?? '' ) ); $glyph = '' !== $icon && function_exists( 'rooster_has_icon' ) && rooster_has_icon( $icon ) ? rooster_icon( $icon, array( 'class' => 'rooster-mega__icon', 'width' => 16, 'height' => 16 ) ) : ''; return '
  • ' . ( '' !== self::address( $block ) ? '' . $glyph . '' . esc_html( $label ) . '' : '' . $glyph . esc_html( $label ) . '' ) . '
  • '; } private static function address( array $block ) { $url = trim( (string) ( $block['attrs']['url'] ?? '' ) ); return '#' === $url ? '' : $url; } private static function link_attributes( array $block ) { $attrs = ' href="' . esc_url( (string) ( $block['attrs']['url'] ?? '' ) ) . '"'; if ( ! empty( $block['attrs']['opensInNewTab'] ) ) { $attrs .= ' target="_blank" rel="noreferrer noopener"'; } if ( ! empty( $block['attrs']['rel'] ) && empty( $block['attrs']['opensInNewTab'] ) ) { $attrs .= ' rel="' . esc_attr( (string) $block['attrs']['rel'] ) . '"'; } if ( ! empty( $block['attrs']['title'] ) ) { $attrs .= ' title="' . esc_attr( (string) $block['attrs']['title'] ) . '"'; } return $attrs; } private static function tokens( $label ) { $label = (string) $label; if ( false === strpos( $label, self::TOKEN_FREE_SHIPPING ) ) { return $label; } $amount = self::free_shipping(); return '' === $amount ? '' : str_replace( self::TOKEN_FREE_SHIPPING, $amount, $label ); } public static function free_shipping() { if ( ! function_exists( 'wc_price' ) ) { return ''; } $amount = 0.0; if ( class_exists( 'AIEO_DMM_Free_Shipping' ) ) { $state = AIEO_DMM_Free_Shipping::is_audience_eligible(); $amount = ! empty( $state['eligible'] ) ? (float) ( $state['payload']['threshold'] ?? 0 ) : 0.0; } $amount = (float) apply_filters( 'rooster/menu/free_shipping', $amount ); if ( $amount <= 0 ) { return ''; } $whole = abs( $amount - round( $amount ) ) < 0.005; return trim( html_entity_decode( wp_strip_all_tags( wc_price( $amount, array( 'decimals' => $whole ? 0 : wc_get_price_decimals() ) ) ), ENT_QUOTES, 'UTF-8' ) ); } private static function card( WP_Post $post, array $blocks, $family ) { $tagline = trim( (string) get_post_meta( $post->ID, self::META_TAGLINE, true ) ); $cta = get_post_meta( $post->ID, self::META_CTA, true ); $html = '
    ' . self::art( $post, $blocks, $family ) . '

    ' . esc_html( (string) $post->post_title ) . '

    ' . ( '' !== $tagline ? '

    ' . esc_html( $tagline ) . '

    ' : '' ); if ( is_array( $cta ) && ! empty( $cta['url'] ) && ! empty( $cta['label'] ) ) { $html .= '' . esc_html( (string) $cta['label'] ) . ''; } return $html . '
    '; } private static function art( WP_Post $post, array $blocks, $family, $tag = 'div' ) { $image_id = (int) get_post_meta( $post->ID, self::META_IMAGE, true ); foreach ( $blocks as $block ) { if ( ! $image_id && ! empty( $block['attrs']['roosterImage'] ) ) { $image_id = (int) $block['attrs']['roosterImage']; } } if ( $image_id > 0 ) { $image = wp_get_attachment_image( $image_id, 'medium', false, array( 'class' => 'rooster-mega__art', 'alt' => '', 'loading' => 'lazy', 'decoding' => 'async', 'sizes' => '(min-width: 64rem) 18rem, 80vw' ) ); if ( '' !== $image ) { return $image; } } if ( '' === $family || ! class_exists( 'WP_Block_Patterns_Registry' ) ) { return ''; } $name = (string) apply_filters( 'rooster/menu/motif_pattern', 'rooster-site/motif-' . $family, $family, $post ); $pattern = '' !== $name ? WP_Block_Patterns_Registry::get_instance()->get_registered( $name ) : null; if ( empty( $pattern['content'] ) ) { return ''; } $art = trim( (string) do_blocks( (string) $pattern['content'] ) ); return '' !== $art ? '<' . $tag . ' class="rooster-mega__art" aria-hidden="true">' . $art . '' : ''; } private static function item( array $block, $tree = false ) { $label = trim( (string) ( $block['attrs']['label'] ?? '' ) ); $url = (string) ( $block['attrs']['url'] ?? '' ); if ( '' === $label || '' === $url ) { return ''; } $icon = sanitize_key( (string) ( $block['attrs']['roosterIcon'] ?? '' ) ); $badge = trim( (string) ( $block['attrs']['roosterBadge'] ?? '' ) ); $desc = trim( (string) ( $block['attrs']['description'] ?? '' ) ); $attrs = self::link_attributes( $block ); $glyph = '' !== $icon && function_exists( 'rooster_has_icon' ) && rooster_has_icon( $icon ) ? rooster_icon( $icon, array( 'class' => 'rooster-mega__icon', 'width' => 16, 'height' => 16 ) ) : ''; $under = ''; if ( $tree && 'core/navigation-submenu' === ( $block['blockName'] ?? '' ) ) { foreach ( self::entries( $block ) as $child ) { $under .= self::item( $child ); } if ( '' !== $under ) { $under = ''; } } $html = '
  • ' . '' . $glyph . '' . esc_html( $label ) . '' . ( '' !== $badge ? ' ' . esc_html( $badge ) . '' : '' ) . ''; if ( '' !== $desc ) { $html .= '' . esc_html( $desc ) . ''; } return $html . '' . $under . '
  • '; } public static function phone( WP_Post $post, array $blocks, $head = true ) { $thumb = $head ? self::art( $post, $blocks, self::family( $post ), 'span' ) : ''; $summary = '' !== $thumb ? '' : ''; if ( $head ) { $tagline = trim( (string) get_post_meta( $post->ID, self::META_TAGLINE, true ) ); $summary .= '' . esc_html( (string) $post->post_title ) . '' . ( '' !== $tagline ? '' . esc_html( wp_trim_words( $tagline, 9 ) ) . '' : '' ) . ''; } else { $label = (string) ( $blocks[0]['attrs']['label'] ?? '' ); $summary .= '' . esc_html( $label ) . ''; } $summary .= ''; $columns = array(); $loose = array(); foreach ( $blocks as $block ) { if ( 'core/navigation-submenu' === $block['blockName'] && $head ) { $columns[] = $block; } elseif ( 'core/navigation-submenu' === $block['blockName'] ) { foreach ( (array) $block['innerBlocks'] as $inner ) { $under = '' === trim( (string) ( $inner['attrs']['url'] ?? '' ) ) ? self::entries( (array) $inner ) : array(); $loose = array_merge( $loose, $under ? $under : array( $inner ) ); } } else { $loose[] = $block; } } $rows = static function ( array $items ) { $out = ''; foreach ( $items as $item ) { $out .= self::drawer_link( $item, 'rooster-mega__drawer-row', true ); } return '' !== $out ? '' : ''; }; $body = ''; foreach ( $columns as $n => $column ) { $items = (array) $column['innerBlocks']; if ( 0 === $n ) { $body .= $rows( $items ); continue; } $first = $items[0] ?? array(); if ( $n === count( $columns ) - 1 && $n > 0 && '' !== (string) ( $first['attrs']['roosterIcon'] ?? '' ) && ! empty( $first['attrs']['url'] ) ) { $text = sprintf( __( '%s documentation', 'ai-eshop-optimizer' ), (string) $post->post_title ); $body .= self::drawer_link( array( 'attrs' => array( 'label' => $text ) + (array) $first['attrs'] ), 'rooster-mega__drawer-docs', false ); continue; } $head = '

    ' . esc_html( (string) ( $column['attrs']['label'] ?? '' ) ) . '

    '; if ( $items && ! array_filter( $items, static fn ( $item ) => '' === trim( (string) ( $item['attrs']['description'] ?? '' ) ) ) ) { $links = ''; foreach ( $items as $item ) { $links .= self::drawer_link( $item, 'rooster-mega__drawer-row has-note', true, false, true ); } $body .= $head . ''; continue; } $links = ''; foreach ( $items as $item ) { $links .= self::drawer_link( $item, 'rooster-mega__drawer-link', false, false ); } $body .= $head . ''; } $body .= $rows( $loose ); return array( 'summary' => $summary, 'drawer' => '
    ' . $body . '
    ', 'levels' => self::levels( $head ? $blocks : self::entries( (array) ( $blocks[0] ?? array() ) ) ), ); } public static function levels( array $items ) { $rows = ''; foreach ( $items as $item ) { $name = (string) ( $item['blockName'] ?? '' ); if ( ! in_array( $name, array( 'core/navigation-link', 'core/navigation-submenu' ), true ) ) { continue; } $label = trim( (string) ( $item['attrs']['label'] ?? '' ) ); if ( '' === $label ) { continue; } $next = 'core/navigation-submenu' === $name ? self::levels( self::entries( $item ) ) : ''; $link = self::drawer_link( $item, 'rooster-mega__drawer-row', true, true, false, true ); if ( '' === $link ) { if ( '' === $next ) { continue; } $link = '' . esc_html( $label ) . ''; } if ( '' === $next ) { $rows .= '
  • ' . $link . '
  • '; continue; } $show = sprintf( __( 'Show %s', 'ai-eshop-optimizer' ), $label ); $rows .= '
  • ' . $link . '' . '
    ' . $next . '
  • '; } return '' !== $rows ? '' : ''; } private static function drawer_link( array $block, $class, $badge, $icon = true, $note = false, $bare = false ) { $label = trim( (string) ( $block['attrs']['label'] ?? '' ) ); $url = (string) ( $block['attrs']['url'] ?? '' ); if ( '' === $label || '' === $url ) { return ''; } $attrs = ' href="' . esc_url( $url ) . '"' . ( ! empty( $block['attrs']['opensInNewTab'] ) ? ' target="_blank" rel="noreferrer noopener"' : '' ); $slug = sanitize_key( (string) ( $block['attrs']['roosterIcon'] ?? '' ) ); $glyph = $icon && '' !== $slug && function_exists( 'rooster_has_icon' ) && rooster_has_icon( $slug ) ? rooster_icon( $slug, array( 'class' => 'rooster-mega__icon', 'width' => 16, 'height' => 16 ) ) : ''; $text = trim( (string) ( $block['attrs']['roosterBadge'] ?? '' ) ); $name = esc_html( $label ) . ( $badge && '' !== $text ? ' ' . esc_html( $text ) . '' : '' ); $desc = $note ? trim( (string) ( $block['attrs']['description'] ?? '' ) ) : ''; if ( '' !== $desc ) { $name = '' . $name . '' . esc_html( $desc ) . ''; } $html = '' . $glyph . $name . ''; return $bare || 'rooster-mega__drawer-docs' === $class ? $html : '
  • ' . $html . '
  • '; } public static function post( $slug ) { $slug = sanitize_title( (string) $slug ); if ( '' === $slug ) { return null; } $posts = get_posts( array( 'post_type' => 'wp_navigation', 'post_status' => 'publish', 'name' => $slug, 'posts_per_page' => 1, 'no_found_rows' => true ) ); return $posts ? $posts[0] : null; } public static function families( array $slugs ) { $out = array(); foreach ( $slugs as $slug ) { $post = self::post( $slug ); if ( $post ) { $family = self::family( $post ); $out[ '' !== $family ? $family : $post->post_name ] = $post; } } return $out; } }