WordPress. API настроек (опций). Часть 4 из 4

29.07.2019

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

Давайте создадим плагин, у которого будет отдельная страница настроек в панели управления. И на этой странце будут не только поля для редактирования опций, но и будет еще одно поле — для загрузки файлов. Для этого нам потребуется добавить атрибут enctype для формы и установить для него значение multipart/form-data.

<?php
/*
 * Plugin name: Example
 * Description: Пример загрузки файлов в панели управления
 */

register_activation_hook(__FILE__, function() {
    // проверяем права пользователя
    if (!current_user_can('activate_plugins')) {
        return;
    }
    // создаем директорию для загрузки
    if (!is_dir(plugin_dir_path(__FILE__) . 'upload')) {
        mkdir(plugin_dir_path(__FILE__) . 'upload');
    }
});
/*
 * Добавляем страницу настроек плагина в панели управления
 */
add_action('admin_menu', function () {
    add_menu_page(
        // содержимое тега title этой страницы
        'Настройки плагина «Example»',
        // название пункта меню для этой страницы
        'Плагин «Example»',
        // права доступа, чтобы был показан этот пункт меню
        'manage_options',
        // уникальный идентификатор меню (страницы)
        'plugin_example_page',
        // функция выводит содержимое этой страницы
        function () {
            ?>
            <div class="wrap">
                <h1>Плагин «Example»</h1>
                <?php settings_errors(); ?>
                <form method="post" action="options.php" enctype="multipart/form-data">
                    <?php
                    settings_fields('plugin_example_page');
                    do_settings_sections('plugin_example_page');
                    submit_button();
                    ?>
                </form>
            </div>
            <?php
        },
        // иконка для страницы настроек плагина
        'dashicons-upload',
        // позиция страницы, в конце списка
        90
    );
});
/*
 * 1. Регистрируем две опции для плагина «Example»
 * 2. Добавляем новую секцию для этих двух опций
 * 3. Добавляем поля формы для редактирования опций
 * 4. Регистрируем псевдо-опцию, нужна для загрузки
 * 5. Регистрируем секцию для нашей псевдо-опции
 * 6. Добавляем поле формы для загрузки файлов
 */
add_action('admin_init', function () {

    /*
     * 1.1. Регистрируем первую опцию для плагина
     */
    register_setting(
        // страница меню, куда будет добавлена эта опция
        'plugin_example_page',
        // уникальный идентификатор этой опции (slug)
        'some_option_for_example'
    );
    /*
     * 1.2. Регистрируем вторую опцию для плагина
     */
    register_setting(
        // страница меню, куда будет добавлена эта опция
        'plugin_example_page',
        // уникальный идентификатор этой опции (slug)
        'other_option_for_example'
    );

    /*
     * 2. Регистрируем новую секцию для этих двух опций
     */
    add_settings_section(
    // уникальный идентификатор секции
        'example_option_section',
        // заголовок секции нам не нужен
        'Настройки плагина',
        // функция выводит описание секции
        function () {
            ?>
            <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet
                deserunt eius eligendi est et hic illum inventore iusto labore
                laboriosam maxime nemo numquam quae sequi, sit tenetur velit.
            </p>
            <?php
        },
        // страница, куда будет добавлена эта секция
        'plugin_example_page'
    );

    /*
     * 3.1. Добавляем поле формы для редактирования первой опции
     */
    add_settings_field(
        'some_option_for_example', // идентификатор поля формы
        'Первая настройка плагина', // заголовок поля формы
        function () { // выводит html-код поля формы
            $value = esc_attr(get_option('some_option_for_example', ''));
            ?>
            <input type="text"
                id="some_option_for_example"
                name="some_option_for_example"
                value="<?= $value; ?>" />
            <?php
        },
        'plugin_example_page', // страница меню
        'example_option_section', // идентификатор секции
        ['label_for' => 'some_option_for_example']
    );
    /*
     * 3.2. Добавляем поле формы для редактирования второй опции
     */
    add_settings_field(
        'other_option_for_example', // идентификатор поля формы
        'Вторая настройка плагина', // заголовок поля формы
        function () { // выводит html-код поля формы
            $value = esc_attr(get_option('other_option_for_example', ''));
            ?>
            <input type="text"
                id="other_option_for_example"
                name="other_option_for_example"
                value="<?= $value; ?>" />
            <?php
        },
        'plugin_example_page', // страница меню
        'example_option_section', // идентификатор секции
        ['label_for' => 'other_option_for_example']
    );

    /*
     * 4. Регистрируем псевдо-опцию для загрузки файлов
     */
    register_setting(
        // страница меню, куда будет добавлена эта опция
        'plugin_example_page',
        // уникальный идентификатор этой опции (slug)
        'upload_files_for_example',
        /*
         * Эта функция нужна, чтобы обработать опцию перед сохранением.
         * Но мы будем ее использовать для того, чтобы загрузить файлы.
         * А в таблицу БД wp_options в качестве значения опции всегда
         * будет записываться пустая строка.
         */
        function ($option) {
            example_upload_files(plugin_dir_path(__FILE__) . 'upload');
            return '';
        }
    );

    /*
     * 5. Регистрируем новую секцию для псевдо-опции
     */
    add_settings_section(
    // уникальный идентификатор секции
        'example_upload_section',
        // заголовок секции нам не нужен
        'Загрузка файлов',
        // функция выводит описание секции
        function () {
            ?>
            <p>
                Файлы для загрузки должны иметь расширения jpg, jpeg, gif, png,
                bmp, doc, docx, xls, xlsx, ppt, pptx, zip, pdf.
            </p>
            <?php
        },
        // страница, куда будет добавлена эта секция
        'plugin_example_page'
    );

    /*
     * 6. Добавляем поле формы для загрузки файлов
     */
    add_settings_field(
        'upload_files_for_example', // идентификатор поля формы
        'Файл(ы) для загрузки', // заголовок поля формы
        function () { // выводит html-код поля формы
            ?>
            <input type="file"
                id="upload_files_for_example"
                name="upload_files_for_example[]"
                multiple />
            <?php
        },
        'plugin_example_page', // страница меню
        'example_upload_section', // идентификатор секции
        ['label_for' => 'upload_files_for_example']
    );
});
/*
 * Функция для загрузки файлов, работает с массивом $_FILES
 */
function example_upload_files($dir) {
    if (empty($_FILES['upload_files_for_example']['name'][0])) {
        return;
    }
    $mimeTypes = [
        'image/jpeg',
        'image/pjpeg',
        'image/gif',
        'image/png',
        'image/x-png',
        'image/bmp',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'application/vnd.ms-powerpoint',
        'application/vnd.openxmlformats-officedocument.presentationml.presentation',
        'application/zip',
        'application/x-zip-compressed',
        'application/pdf'
    ];
    $exts = array(
        'jpg', 'jpeg', 'gif', 'png', 'bmp', 'doc', 'docx',
        'xls', 'xlsx', 'ppt', 'pptx', 'zip', 'pdf'
    );
    // цикл по всем загруженным файлам
    $count = count($_FILES['upload_files_for_example']['name']);
    for ($i = 0; $i < $count; $i++) {
        $name = $_FILES['upload_files_for_example']['name'][$i];
        $type = $_FILES['upload_files_for_example']['type'][$i];
        $temp = $_FILES['upload_files_for_example']['tmp_name'][$i];
        // произошла ошибка при загрузке файла
        if ($_FILES['upload_files_for_example']['error'][$i]) {
            add_settings_error(
                'upload_files_for_example',
                'example-upload-file',
                'Ошибка при загрузке файла ' . $name,
                'error'
            );
            continue;
        }
        $ext = pathinfo($name, PATHINFO_EXTENSION);
        // недопустимое расширение файла
        if (!in_array($ext, $exts)) {
            add_settings_error(
                'upload_files_for_example',
                'example-upload-file',
                'Недопустимое расширение файла ' . $name,
                'error'
            );
            continue;
        }
        // недопустимый mime-тип файла
        if (!in_array($type, $mimeTypes)) {
            add_settings_error(
                'upload_files_for_example',
                'example-upload-file',
                'Недопустимый mime-тип файла ' . $name,
                'error'
            );
            continue;
        }
        $result = move_uploaded_file($temp, $dir . '/'. $name);
        if ($result) {
            add_settings_error(
                'upload_files_for_example',
                'example-upload-file',
                'Файл ' . $name . ' успешно загружен',
                'updated'
            );
        } else {
            add_settings_error(
                'upload_files_for_example',
                'example-upload-file',
                'Ошибка при загрузке файла ' . $name,
                'error'
            );
        }
    }
}

И создадим еще файл uninstall.php, который удалит настройки из БД при удалении плагина:

<?php
if (!defined('WP_UNINSTALL_PLUGIN')) {
    exit;
}

delete_option('some_option_for_example');
delete_option('other_option_for_example');
delete_option('upload_files_for_example');

Максимальный суммарный объем загружаемых файлов по умолчанию ограничен 2 Мб, а количество файлов не может быть больше 20. Эти значения задаются в файле php.ini:

; Maximum allowed size for uploaded files. http://php.net/upload-max-filesize
upload_max_filesize = 2M

; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20

Если нужно закачивать много файлов большого размера за раз, есть смысл изменить эти значения. При этом следует помнить о директиве post_max_size, которая ограничивает максимальный размер POST-данных. При увеличении значения upload_max_filesize, следует увеличить и значение post_max_size. Так, чтобы максимальный размер POST-данных был больше или равен максимальному объему загружаемых файлов.

Поиск: API • Web-разработка • WordPress • Настройка • Файл • Форма • CMS • Опция

Каталог оборудования
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.