WordPress. Загрузка файлов. Часть 2 из 3

03.08.2019

Теги: CMSPOSTWeb-разработкаWordPressФайлФорма

Хорошо, в панели управления загружать файлы мы теперь умеем, посмотрим, как это можно сделать в публичной части. Во-первых, добавим шорткод, чтобы форму загрузки файлов можно было разместить на статической странице или в записи блога. Во-вторых, предоставим возможность загрузки файлов всем авторизованным пользователям.

Загрузка файлов в публичной части

Простая загрузка одного файла

Для начала — самый простой вариант, т.е. просто загружаем файл в директорию uploads. Поскольку нам потребуется функция wp_handle_upload(), подключим php-файл, который содержит код этой функции. После отправки формы выполним редирект, чтобы предотвратить повторную отправку данных, если пользователь обновит страницу. Результаты загрузки файла сохраним в сессию, чтобы показать сообщение пользователю после перезагрузки страницы.

<?php
/*
 * Plugin name: Загрузка файлов
 * Description: Пример загрузки файлов в публичной части
 */

register_activation_hook(__FILE__, function() {
    // проверяем права пользователя на активацию плагинов
    if (!current_user_can('activate_plugins')) {
        return;
    }
    // для загрузки файлов из публичной части у всех
    // пользователей должны быть права на это
    $subscriber = get_role('subscriber');
    if (!$subscriber->has_cap('upload_files')) {
        $subscriber->add_cap('upload_files');
    }
});

register_deactivation_hook(__FILE__, function() {
    // проверяем права пользователя на деактивацию плагинов
    if (!current_user_can('deactivate_plugins')) {
        return;
    }
    // удаляем права на загрузку файлов, которую
    // предоставили на этапе активации плагина
    $subscriber = get_role('subscriber');
    if ($subscriber->has_cap('upload_files')) {
        $subscriber->remove_cap('upload_files');
    }
});

/*
 * Регистрируем шорткод [tokmakov-upload-file], который позволит
 * вставить форму загрузки файлов на страницу или запись блога
 */
add_shortcode('tokmakov-upload-file', function () {
    if (!is_user_logged_in()) {
        return '';
    }
    ob_start();
    ?>
    <div class="tokmakov-upload-file">
        <div class="response">
            <?php if (isset($_SESSION['tokmakov_upload_file'])): ?>
                <p><?= $_SESSION['tokmakov_upload_file']; ?></p>
                <?php unset($_SESSION['tokmakov_upload_file']); ?>
            <?php endif; ?>
        </div>
        <form action="<?= admin_url('admin-post.php'); ?>" method="post"
              enctype="multipart/form-data">
            <?php wp_nonce_field('tokmakov_upload_file'); ?>
            <input type="hidden" name="action" value="tokmakov_upload_file" />
            <input type="hidden" name="redirect" value="<?= get_permalink(); ?>" />
            <input type="file" name="tokmakov_upload_file" required />
            <input type="submit" value="Загрузить файл" />
        </form>
    </div>
    <?php
    return ob_get_clean();
});

/*
 * Подключаем файл стилей, чтобы красиво оформить наш блок загрузки
 */
add_action('wp_print_styles', function () {
    if (is_user_logged_in()) {
        wp_enqueue_style(
            'tokmakov-upload-file-css',
            plugin_dir_url(__FILE__) . 'style.css'
        );
    }
});

/*
 * Запускаем сессию, чтобы передавать сообщение о результате
 * обработки файла после перезагрузки страницы
 */
add_action('init', function () {
    if (session_id() == '') {
        session_start();
    }
});

/*
 * Обрабатываем данные формы, загружаем файл(ы). Сообщение о результате
 * записываем в сесиию, чтобы показать пользователю на странице с формой.
 */
add_action('admin_post_tokmakov_upload_file', function () {
    // подключаем файл с функцией wp_handle_upload()
    require_once ABSPATH . 'wp-admin/includes/file.php';
    // проверяем защиту nonce и права пользователя
    $check1 = wp_verify_nonce(
        $_POST['_wpnonce'],
        'tokmakov_upload_file'
    );
    $check2 = current_user_can('upload_files');
    ob_start();
    if ($check1 && $check2) {
        // проверка пройдена, можно загружать файл
        $overrides = ['test_form' => false];
        $result = wp_handle_upload(
            $_FILES['tokmakov_upload_file'],
            $overrides
        );
        // показываем результаты загрузки файла
        if (isset($result['error'])) {
            echo 'Ошибка при загрузке файла';
        } else {
            echo 'Файл был успешно загружен';
        }
    } else {
        echo 'Проверка не пройдена, файл не загружен';
    }
    $_SESSION['tokmakov_upload_file'] = ob_get_clean();
    // после отправки формы делаем редирект, чтобы предотвратить
    // повторную отправку, если пользователь обновит страницу
    $redirect = home_url();
    if (isset($_POST['redirect'])) {
        $redirect = $_POST['redirect'];
        $redirect = wp_validate_redirect($redirect, home_url());
    }
    wp_redirect($redirect);
    die();
});
.tokmakov-upload-file {
    padding: 10px;
    margin: 10px 0;
    background-color: #f5f5f5;
    border: 1px solid #e3e3e3;
}
    .tokmakov-upload-file input[type="file"],
    .tokmakov-upload-file input[type="submit"] {
        display: inline-block;
        padding: 5px;
        background-color: #e3e3e3;
        border: none;
    }
    .tokmakov-upload-file p,
    .tokmakov-upload-file ul {
        margin-top: 0;
    }

Загрузка одного вложения (attachment)

Действуем, как и раньше — используем функцию media_handle_upload(), для этого необходимо подключить три файла:

  • wp-admin/includes/image.php
  • wp-admin/includes/media.php
  • wp-admin/includes/file.php

Когда мы загружали файлы в панели управления, это скрипты подключал WordPress. А теперь мы должны сделать это самостоятельно.

<?php
/*
 * Plugin name: Загрузка файлов
 * Description: Пример загрузки файлов в публичной части
 */

register_activation_hook(__FILE__, function() {
    /*...*/
});

register_deactivation_hook(__FILE__, function() {
    /*...*/
});

/*
 * Регистрируем шорткод [tokmakov-upload-file], который позволит
 * вставить форму загрузки файлов на страницу или запись блога
 */
add_shortcode('tokmakov-upload-file', function () {
    if (!is_user_logged_in()) {
        return '';
    }
    ob_start();
    ?>
    <div class="tokmakov-upload-file">
        <div class="response">
            <?php if (isset($_SESSION['tokmakov_upload_file'])): ?>
                <p><?= $_SESSION['tokmakov_upload_file']; ?></p>
                <?php unset($_SESSION['tokmakov_upload_file']); ?>
            <?php endif; ?>
        </div>
        <form action="<?= admin_url('admin-post.php'); ?>" method="post"
              enctype="multipart/form-data">
            <?php wp_nonce_field('tokmakov_upload_file'); ?>
            <input type="hidden" name="action" value="tokmakov_upload_file" />
            <input type="hidden" name="redirect" value="<?= get_permalink(); ?>" />
            <input type="file" name="tokmakov_upload_file" required />
            <input type="submit" value="Загрузить файл" />
        </form>
    </div>
    <?php
    return ob_get_clean();
});

/*
 * Подключаем файл стилей, чтобы красиво оформить наш блок загрузки
 */
add_action('wp_print_styles', function () {
    if (is_user_logged_in()) {
        wp_enqueue_style(
            'tokmakov-upload-file-css',
            plugin_dir_url(__FILE__) . 'style.css'
        );
    }
});

/*
 * Запускаем сессию, чтобы передавать сообщение о результате
 * обработки файла после перезагрузки страницы
 */
add_action('init', function () {
    if (session_id() == '') {
        session_start();
    }
});

/*
 * Обрабатываем данные формы, загружаем файл(ы). Сообщение о результате
 * записываем в сесиию, чтобы показать пользователю на странице с формой.
 */
add_action('admin_post_tokmakov_upload_file', function () {
    // подключаем все файлы, которые нужны для загрузки
    require_once ABSPATH . 'wp-admin/includes/image.php';
    require_once ABSPATH . 'wp-admin/includes/file.php';
    require_once ABSPATH . 'wp-admin/includes/media.php';
    // проверяем защиту nonce и права пользователя
    $check1 = wp_verify_nonce(
        $_POST['_wpnonce'],
        'tokmakov_upload_file'
    );
    $check2 = current_user_can('upload_files');
    ob_start();
    if ($check1 && $check2) {
        // проверка пройдена, можно загружать файл
        $result = media_handle_upload('tokmakov_upload_file', 0);
        if (is_wp_error($result)) {
            echo 'Ошибка при загрузке файла';
        } else {
            echo 'Файл был успешно загружен';
        }
    } else {
        echo 'Проверка не пройдена, файл не загружен';
    }
    $_SESSION['tokmakov_upload_file'] = ob_get_clean();
    // после отправки формы делаем редирект, чтобы предотвратить
    // повторную отправку, если пользователь обновит страницу
    $redirect = home_url();
    if (isset($_POST['redirect'])) {
        $redirect = $_POST['redirect'];
        $redirect = wp_validate_redirect($redirect, home_url());
    }
    wp_redirect($redirect);
    die();
});

Простая загрузка нескольких файлов

Давайте теперь загрузим несколько файлов. Для этого добавим атрибут multiple для элемента формы и будем «скармливать» функции wp_handle_upload() по одному файлу за раз.

<?php
/*
 * Plugin name: Загрузка файлов
 * Description: Пример загрузки файлов в публичной части
 */

register_activation_hook(__FILE__, function() {
    /*...*/
});

register_deactivation_hook(__FILE__, function() {
    /*...*/
});

/*
 * Регистрируем шорткод [tokmakov-upload-file], который позволит
 * вставить форму загрузки файлов на страницу или запись блога
 */
add_shortcode('tokmakov-upload-file', function () {
    if (!is_user_logged_in()) {
        return '';
    }
    ob_start();
    ?>
    <div class="tokmakov-upload-file">
        <div class="response">
            <?php if (isset($_SESSION['tokmakov_upload_file'])): ?>
                <ul>
                <?php foreach ($_SESSION['tokmakov_upload_file'] as $message): ?>
                    <li><?= $message; ?></li>
                <?php endforeach; ?>
                </ul>
                <?php unset($_SESSION['tokmakov_upload_file']); ?>
            <?php endif; ?>
        </div>
        <form action="<?= admin_url('admin-post.php'); ?>" method="post"
              enctype="multipart/form-data">
            <?php wp_nonce_field('tokmakov_upload_file'); ?>
            <input type="hidden" name="action" value="tokmakov_upload_file" />
            <input type="hidden" name="redirect" value="<?= get_permalink(); ?>" />
            <input type="file" name="tokmakov_upload_file[]" required multiple />
            <input type="submit" value="Загрузить файлы" />
        </form>
    </div>
    <?php
    return ob_get_clean();
});

/*
 * Подключаем файл стилей, чтобы красиво оформить наш блок загрузки
 */
add_action('wp_print_styles', function () {
    if (is_user_logged_in()) {
        wp_enqueue_style(
            'tokmakov-upload-file-css',
            plugin_dir_url(__FILE__) . 'style.css'
        );
    }
});

/*
 * Запускаем сессию, чтобы передавать сообщение о результате
 * обработки файла после перезагрузки страницы
 */
add_action('init', function () {
    if (session_id() == '') {
        session_start();
    }
});

/*
 * Обрабатываем данные формы, загружаем файл(ы). Сообщение о результате
 * записываем в сесиию, чтобы показать пользователю на странице с формой.
 */
add_action('admin_post_tokmakov_upload_file', function () {
    // подключаем файл с функцией wp_handle_upload()
    require_once ABSPATH . 'wp-admin/includes/file.php';
    // проверяем защиту nonce и права пользователя
    $check1 = wp_verify_nonce(
        $_POST['_wpnonce'],
        'tokmakov_upload_file'
    );
    $check2 = current_user_can('upload_files');
    if ($check1 && $check2) {
        // проверка пройдена, можно загружать файлы
        $overrides = ['test_form' => false];
        // перебираем все файлы в цикле и загружаем по одному
        $messages = [];
        foreach ($_FILES['tokmakov_upload_file']['name'] as $i => $v) {
            $file = [
                'name' => $_FILES['tokmakov_upload_file']['name'][$i],
                'type' => $_FILES['tokmakov_upload_file']['type'][$i],
                'tmp_name' => $_FILES['tokmakov_upload_file']['tmp_name'][$i],
                'error' => $_FILES['tokmakov_upload_file']['error'][$i],
                'size' => $_FILES['tokmakov_upload_file']['size'][$i],
            ];
            // загружаем очередной файл в директорию uploads
            $result = wp_handle_upload($file, $overrides);
            // показываем результаты загрузки очередного файла
            if (isset($result['error'])) {
                $messages[] = 'Ошибка при загрузке файла ' . $file['name'];
            } else {
                $messages[] = 'Файл ' . $file['name'] . ' успешно загружен';
            }
        }
    } else {
        $messages[] = 'Проверка не пройдена, файлы не загружены';
    }
    $_SESSION['tokmakov_upload_file'] = $messages;
    // после отправки формы делаем редирект, чтобы предотвратить
    // повторную отправку, если пользователь обновит страницу
    $redirect = home_url();
    if (isset($_POST['redirect'])) {
        $redirect = $_POST['redirect'];
        $redirect = wp_validate_redirect($redirect, home_url());
    }
    wp_redirect($redirect);
    die();
});

Загрузка нескольких вложений (attachments)

Перебираем все загруженные файлы в цикле и «скармливаем» функции media_handle_sideload() по одному.

<?php
/*
 * Plugin name: Загрузка файлов
 * Description: Пример загрузки файлов в публичной части
 */

register_activation_hook(__FILE__, function() {
    /*...*/
});

register_deactivation_hook(__FILE__, function() {
    /*...*/
});

/*
 * Регистрируем шорткод [tokmakov-upload-file], который позволит
 * вставить форму загрузки файлов на страницу или запись блога
 */
add_shortcode('tokmakov-upload-file', function () {
    if (!is_user_logged_in()) {
        return '';
    }
    ob_start();
    ?>
    <div class="tokmakov-upload-file">
        <div class="response">
            <?php if (isset($_SESSION['tokmakov_upload_file'])): ?>
                <ul>
                <?php foreach ($_SESSION['tokmakov_upload_file'] as $message): ?>
                    <li><?= $message; ?></li>
                <?php endforeach; ?>
                </ul>
                <?php unset($_SESSION['tokmakov_upload_file']); ?>
            <?php endif; ?>
        </div>
        <form action="<?= admin_url('admin-post.php'); ?>" method="post"
              enctype="multipart/form-data">
            <?php wp_nonce_field('tokmakov_upload_file'); ?>
            <input type="hidden" name="action" value="tokmakov_upload_file" />
            <input type="hidden" name="redirect" value="<?= get_permalink(); ?>" />
            <input type="file" name="tokmakov_upload_file[]" required multiple />
            <input type="submit" value="Загрузить файлы" />
        </form>
    </div>
    <?php
    return ob_get_clean();
});

/*
 * Подключаем файл стилей, чтобы красиво оформить наш блок загрузки
 */
add_action('wp_print_styles', function () {
    if (is_user_logged_in()) {
        wp_enqueue_style(
            'tokmakov-upload-file-css',
            plugin_dir_url(__FILE__) . 'style.css'
        );
    }
});

/*
 * Запускаем сессию, чтобы передавать сообщение о результате
 * обработки файла после перезагрузки страницы
 */
add_action('init', function () {
    if (session_id() == '') {
        session_start();
    }
});

/*
 * Обрабатываем данные формы, загружаем файл(ы). Сообщение о результате
 * записываем в сесиию, чтобы показать пользователю на странице с формой.
 */
add_action('admin_post_tokmakov_upload_file', function () {
    // подключаем все файлы, которые нужны для загрузки
    require_once ABSPATH . 'wp-admin/includes/image.php';
    require_once ABSPATH . 'wp-admin/includes/file.php';
    require_once ABSPATH . 'wp-admin/includes/media.php';
    // проверяем защиту nonce и права пользователя
    $check1 = wp_verify_nonce(
        $_POST['_wpnonce'],
        'tokmakov_upload_file'
    );
    $check2 = current_user_can('upload_files');
    if ($check1 && $check2) {
        // проверка пройдена, можно загружать файлы
        $messages = [];
        // перебираем все файлы в цикле и загружаем по одному
        foreach ($_FILES['tokmakov_upload_file']['name'] as $i => $v) {
            $file = [
                'name' => $_FILES['tokmakov_upload_file']['name'][$i],
                'type' => $_FILES['tokmakov_upload_file']['type'][$i],
                'tmp_name' => $_FILES['tokmakov_upload_file']['tmp_name'][$i],
                'error' => $_FILES['tokmakov_upload_file']['error'][$i],
                'size' => $_FILES['tokmakov_upload_file']['size'][$i],
            ];
            // загружаем очередной файл в директорию uploads
            $result = media_handle_sideload($file, 0);
            if (is_wp_error($result)) {
                $messages[] = 'Ошибка при загрузке файла ' . $file['name'];
            } else {
                $messages[] = 'Файл ' . $file['name'] . ' успешно загружен';
            }
        }
    } else {
        $messages[] = 'Проверка не пройдена, файлы не загружены';
    }
    $_SESSION['tokmakov_upload_file'] = $messages;
    // после отправки формы делаем редирект, чтобы предотвратить
    // повторную отправку, если пользователь обновит страницу
    $redirect = home_url();
    if (isset($_POST['redirect'])) {
        $redirect = $_POST['redirect'];
        $redirect = wp_validate_redirect($redirect, home_url());
    }
    wp_redirect($redirect);
    die();
});

Поиск: CMS • Web-разработка • WordPress • Файл • Форма • Загрузка • Upload • File • POST

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.