Можно ли реорганизовать каталог загрузок WordPress?

8

У меня есть сайт WordPress, на который были загружены все загрузки /wp-content/uploads/*. Теперь, когда есть тысячи изображений, наблюдается снижение производительности, и мне поручили помочь исправить это.

Кто-нибудь пересортировал каталог закачек раньше? Переместить его в более структурированный YYYY / MM? Я хотел бы услышать некоторые стратегии о том, как это было достигнуто.

thejimbirch
источник

Ответы:

10

К сожалению, это очень печальный факт о WordPress, он почти не предоставляет настройки для загрузки в бэкэнд (кроме организационной структуры y / m).

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

Шаг 1,2 и 3. Сделайте резервную копию всех ваших загрузок. То, что вы собираетесь сделать, не может быть отменено, если у вас нет резервной копии вашей папки загрузки!

Шаг 4: Загрузите и установите плагин Thumbnail Cleaner . Это позволяет удалить каждый созданный эскиз.

Шаг 5: Создайте свой собственный метод генерации. У меня есть пример для вас:

add_filter('wp_image_editors', 'my_wp_image_editors');
function my_wp_image_editors($editors) {
    array_unshift($editors, "my_WP_Image_Editor");
    return $editors;
}
// Include the existing classes first in order to extend them.
require_once ABSPATH . WPINC . "/class-wp-image-editor.php";
require_once ABSPATH . WPINC . "/class-wp-image-editor-gd.php";
// Now we extend the original image editor class
class my_WP_Image_Editor extends WP_Image_Editor_GD {
    public function generate_filename($suffix = null, $dest_path = null, $extension = null) {
        // $suffix will be appended to the destination filename, just before the extension
        if (!$suffix) {
            $suffix = $this->get_suffix();
        }
        $dir = pathinfo($this->file, PATHINFO_DIRNAME);
        $ext = pathinfo($this->file, PATHINFO_EXTENSION);
        $name = wp_basename($this->file, ".$ext");
        $new_ext = strtolower($extension ? $extension : $ext );
        if (!is_null($dest_path) && $_dest_path = realpath($dest_path)) {
            $dir = $_dest_path;
        }
        //we get the dimensions using explode, we could have used the properties of $this->file[height] but the suffix could have been provided
        $size_from_suffix = explode("x", $suffix);
        //we get the slug_name for this dimension
        $slug_name = $this->get_slug_by_size($size_from_suffix[0], $size_from_suffix[1]);
        return trailingslashit( $dir ) . "{$slug_name}/{$name}.{$new_ext}";
    }
    function multi_resize($sizes) {
        $metadata = array();
        $orig_size = $this->size;
        foreach ( $sizes as $size => $size_data ) {
            if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) {
                continue;
            }
            if ( ! isset( $size_data['width'] ) ) {
                $size_data['width'] = null;
            }
            if ( ! isset( $size_data['height'] ) ) {
                $size_data['height'] = null;
            }
            if ( ! isset( $size_data['crop'] ) ) {
                $size_data['crop'] = false;
            }
            $image = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] );
            if ( ! is_wp_error( $image ) ) {
                $resized = $this->_save( $image );
                imagedestroy( $image );
                if ( ! is_wp_error( $resized ) && $resized ) {
                    unset( $resized['path'] );
                    $metadata[$size] = $resized;
                }
            }
            $this->size = $orig_size;
        }
        //we add the slug to the file path
        foreach ($metadata as $slug => $data) {
            $metadata[$slug]['file'] = $slug . "/" . $data['file'];
        }
        return $metadata;
    }
    // Our custom function to retrieve the proper slug by weight and height
    function get_slug_by_size($width, $height) {
        // Make thumbnails and other intermediate sizes.
        $_wp_additional_image_sizes = wp_get_additional_image_sizes();
        $image_sizes = array(); //all sizes the default ones and the custom ones in one array
        foreach (get_intermediate_image_sizes() as $s) {
            $image_sizes[$s] = array('width' => '', 'height' => '', 'crop' => false);
            if (isset($_wp_additional_image_sizes[$s]['width'])) {
                // For theme-added sizes
                $image_sizes[$s]['width'] = intval($_wp_additional_image_sizes[$s]['width']);
            } else {
                // For default sizes set in options
                $image_sizes[$s]['width'] = get_option("{$s}_size_w");
            }
            if (isset($_wp_additional_image_sizes[$s]['height'])) {
                // For theme-added sizes
                $image_sizes[$s]['height'] = intval($_wp_additional_image_sizes[$s]['height']);
            } else {
                // For default sizes set in options
                $image_sizes[$s]['height'] = get_option("{$s}_size_h");
            }
            if (isset($_wp_additional_image_sizes[$s]['crop'])) {
                // For theme-added sizes
                $image_sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop'];
            } else {
                // For default sizes set in options
                $image_sizes[$s]['crop'] = get_option("{$s}_crop");
            }
        }
        $slug_name = ""; //the slug's name
        if($width >= $height){
            foreach ($image_sizes as $slug => $data) { // we start checking
                if ($data['width'] == $width) {//we use only width because regardless of the height, the width is the one used for resizing in all cases with crop 1 or 0
                    $slug_name = $slug;
                }
                /*
                 * There could be custom added image sizes that have the same width as one of the defaults so we also use height here
                 * if there are several image sizes with the same width all of them will override the previous one leaving the last one, here we get also the last one
                 * since is looping the entire list, the height is used as a max value for non-hard cropped sizes
                 *  */
                  if ($data['width'] == $width && $data['height'] == $height) {
                      $slug_name = $slug;
                  }
        }
        } else {
            foreach ($image_sizes as $slug => $data) {
                if ($data['height'] == $height) {
                    $slug_name = $slug;
                }
                if ($data['height'] == $height && $data['width'] == $width ) {
                    $slug_name = $slug;
                }
            }
        }
        return $slug_name;
    }
}

Этот класс почти скопирован из исходного класса, включенного в него class-wp-image-editor-gd.php, с одним отличием: он будет хранить миниатюры в отдельных папках, все в каталоге загрузок, в зависимости от размера файла. Поэтому после загрузки изображения у вас получится что-то вроде этого:

/uploads/image.jpg
/uploads/thumbnail/image.jpg
/uploads/medium/image.jpg
/uploads/large/image.jpg
// And so on...

Это предотвратит миллион изображений в одной папке. Вы можете редактировать класс так, как вы хотите, изменять пути и многое другое. Это было предоставлено в качестве примера, чтобы продемонстрировать, как изображения генерируются и хранятся.

Шаг 6: Используйте плагин Regenerate Thumbnails, чтобы причудливо заполнить папку загрузок новыми сгенерированными миниатюрами. Это предотвратит сохранение нескольких тысяч миниатюр в одной папке. Рабочий пример можно найти здесь . Щелкните правой кнопкой мыши и откройте миниатюру на новой вкладке и попробуйте изменить слаг, чтобы увидеть, как он работает.

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

Джек Йоханссон
источник