Группируйте загрузки WooCommerce по продуктам в раскрывающемся меню

Я продаю онлайн-курсы на своем веб-сайте с помощью WooCommerce. Каждый курс (продукт) имеет количество загружаемых файлов. К сожалению, WooCommerce не группирует загрузки каждого продукта и не составляет длинный список доступных загрузок. Если кто-то купит несколько курсов, список загрузок будет очень длинным и запутанным, что неудобно для пользователя.

Я ищу несколько кодов (PHP, Java, CSS) для группировки всех загрузок продуктов в раскрывающемся меню. Таким образом, если кто-то купит 7 курсов, то на странице загрузки будет семь раскрывающихся списков, и при нажатии на каждый из них просто появятся загрузки этого конкретного продукта.

Я использовал код PHP ниже. Он группирует загрузки вместе, но раскрывающегося меню нет.

/**
 * Group Downloadable products by product ID
 *
 * @param array $downloads
 * @return array
 */
function prefix_group_downloadable_products( array $downloads ) {
    $unique_downloads = [];

    foreach ( $downloads as $download ) {
        $list = [
            'download_url' => $download['download_url'],
            'file_name'    => $download['file']['name']
        ];

        if ( array_key_exists( $download['product_id'], $unique_downloads ) ) {
            $unique_downloads[ $download['product_id'] ]['list'][] = $list;
            continue;
        }

        $data = $download;
        $data['list'] = [ $list ];
        $unique_downloads[ $download['product_id'] ] = $data;
    }

    return $unique_downloads;
}

add_filter( 'woocommerce_customer_get_downloadable_products', 
'prefix_group_downloadable_products' );


/**
 * Show number list of downloadable files for group product
 * 
 * @param array $download
 * @return void
 */ 
function prefix_downloads_column_download_file( array $download ) {
    $lists = $download['list'];

    if ( empty( $lists ) ) {
        _e( 'No Download Files', 'storefront' );
        return;
    }

    echo '<ol>';

    foreach ( $lists as $list ) {
        echo '<li>';
        echo '<a href = "' . esc_url( $list['download_url'] ) . '" class = "woocommerce-MyAccount-downloads-file">';
        echo esc_html( $list['file_name'] );
        echo '</a></li>';
    }

    echo '</ol>';
}

add_action( 'woocommerce_account_downloads_column_download-file', 'prefix_downloads_column_download_file' );

Кроме того, этот код приводит к появлению ошибок на страницах «Мои заказы» и «Отчет о заказах», что не позволяет отображать там загрузки. Ошибка заключается в следующем:

Предупреждение: неопределенный «список» ключей массива в /home/beatop/domains/sdrecords.ir/public_html/wp-content/themes/hello-theme-child-master/functions.php в строке 156. Нет файлов для скачивания

Строка 156 связана с этим: $lists = $download['list'];

Как исправить эту ошибку и добавить выпадающее меню?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы избежать этой проблемы, вам нужно сначала проверить наличие $download['list'].

Чтобы получить раскрывающийся список загрузок, сгруппированных по продуктам, необходимы некоторые изменения и дополнения (требуется JavaScript/jQuery).

Примечание (обновление). В уведомлениях по электронной почте мы сохраняем таблицу «Загрузки» в том виде, в каком она есть по умолчанию, поскольку раскрывающийся список не работает.

Следующий код будет обрабатывать это раскрывающееся меню везде, во внешнем интерфейсе:

// Group downloads data by product
add_filter( 'woocommerce_customer_get_downloadable_products', 'prefix_group_downloadable_products', 10, 2 );
add_filter( 'woocommerce_order_get_downloadable_items', 'prefix_group_downloadable_products', 10, 2 );
function prefix_group_downloadable_products( $downloads = array(), $order = null ) {
    // Only on front-end
    if ( is_admin() || ! is_wc_endpoint_url() ) { 
        return $downloads;
    }

    $unique_downloads = []; // Initializing

    foreach ( $downloads as $download ) {
        $list = [
            'download_url' => $download['download_url'],
            'file_name'    => $download['file']['name']
        ];

        if ( array_key_exists( $download['product_id'], $unique_downloads ) ) {
            $unique_downloads[ $download['product_id'] ]['list'][] = $list;
            continue;
        }

        $data = $download;
        $data['list'] = [ $list ];
        $unique_downloads[ $download['product_id'] ] = $data;
    }
    return $unique_downloads;
}

// Display a dropdown of the downloads by product
add_action( 'woocommerce_account_downloads_column_download-file', 'customize_downloads_columns' );
function customize_downloads_columns( $download = array() ) {
    $lists = isset($download['list']) ? $download['list'] : array();

    if ( empty( $lists ) ) {
        _e( 'No Download Files', 'storefront' );
        return;
    }

    echo '<select class = "downloads-dropdown">
    <option value = "">'. __(' Select download', 'storefront' ) .'</option>';

    foreach ( $lists as $list ) {
        printf( '<option value = "%s">%s</option>', 
        esc_url($list['download_url']), esc_html($list['file_name']) );

    }
    echo '</select>';
}

// Javascript: Trigger the download when selecting a file in the dropdown
add_action( 'wp_head', 'trigger_download_from_selected_file_js' );
function trigger_download_from_selected_file_js() {
    if ( is_wc_endpoint_url('downloads') || is_wc_endpoint_url('view-order') || is_wc_endpoint_url('order-received') ) {
        wc_enqueue_js("$(document.body).on('change', 'select.downloads-dropdown', function(){
        if ( $(this).val() != '' ) {
            window.location.href = $(this).val();
        }
        });");
    }
}

Вы получите что-то вроде (в разделе «Моя учетная запись» > «Страница загрузок»):

В разделе «Моя учетная запись» > «Просмотреть заказ» и на страницах «Заказ полученных» (спасибо):

Таблица загрузок в уведомлениях по электронной почте остается неизменной (поведение WooCommerce по умолчанию):


Дополнение для уведомлений по электронной почте (необязательно)

Замените таблицу загрузок текстом, связанным с разделом «Загрузки» в моей учетной записи:

// Remove the downloads table
add_action( 'woocommerce_init', function(){
    remove_action( 'woocommerce_email_order_details', array( WC()->mailer(), 'order_downloads' ), 10 );
});

// Email notifications: Display a text linked to My Account downloads
add_action( 'woocommerce_email_order_details', 'display_linked_text_to_my_account_downloads', 9, 4 );
function display_linked_text_to_my_account_downloads( $order, $sent_to_admin = false, $plain_text = false, $email = '' ) {
    $show_downloads = $order->has_downloadable_item() && $order->is_download_permitted() && ! $sent_to_admin && ! is_a( $email, 'WC_Email_Customer_Refunded_Order' );
    
    if ( ! $show_downloads ) {
        return;
    }

    $text_align    = is_rtl() ? 'right' : 'left';
    $downloads_url = wc_get_endpoint_url('downloads', '', get_permalink( get_option('woocommerce_myaccount_page_id') ) );
    ?>
    <h2 class = "woocommerce-order-downloads__title"><?php esc_html_e( 'Downloads', 'woocommerce' ); ?></h2>
    <table class = "td" cellspacing = "0" cellpadding = "6" style = "width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; margin-bottom: 40px;" border = "1">
        <tr>
            <td class = "td" style = "text-align:<?php echo esc_attr( $text_align ); ?>;">
                <?php printf( __('Downloads are available in your Account %s.', 'storefront'),
                '<a href = "' . $downloads_url . '" class = "button">'. __('"Downloads" section', 'storefront') .'</a>'); ?>
            </td>
        </tr>
    </table>
    <?php 
}

Я обновил свой ответ по коду: уведомления по электронной почте не изменились, поэтому отображается таблица загрузок по умолчанию со ссылками для скачивания (не сгруппированная по продуктам). Итак, теперь код не влияет на уведомления по электронной почте. При желании вы можете заменить таблицу загрузок текстом, связанным с разделом «Загрузки» в моей учетной записи (см. дополнение)...

LoicTheAztec 21.03.2024 13:44

Другие вопросы по теме