Филипп, все возможно, если вы решите на это. Вы можете решить свою проблему, расширив класс редактора изображений WordPress.
Обратите внимание, что я использую WordPress 3.7 - я не проверял ни один из приведенного ниже кода в более ранних версиях и в последней версии 3.8.
Основы редактора изображений
WordPress имеет два встроенных класса, которые обрабатывают манипуляции с изображениями:
WP_Image_Editor_GD
( /wp-includes/class-wp-image-editor-gd.php
)
WP_Image_Editor_Imagick
( /wp-includes/class-wp-image-editor-imagick.php
)
Эти два класса расширяются, WP_Image_Editor
потому что они оба используют разные движки изображений (GD и ImageMagick соответственно) для загрузки, изменения размера, сжатия и сохранения изображений.
По умолчанию WordPress сначала пытается использовать движок ImageMagick, для которого требуется расширение PHP, потому что оно обычно предпочтительнее движка GD по умолчанию в PHP. На большинстве общих серверов расширение ImageMagick не включено.
Добавить редактор изображений
Чтобы решить, какой движок использовать, WordPress вызывает внутреннюю функцию __wp_image_editor_choose()
(расположена в /wp-includes/media.php
). Эта функция проходит по всем движкам, чтобы увидеть, какой движок может обработать запрос.
У функции также есть фильтр, wp_image_editors
который позволяет добавлять больше графических редакторов, например:
add_filter("wp_image_editors", "my_wp_image_editors");
function my_wp_image_editors($editors) {
array_unshift($editors, "WP_Image_Editor_Custom");
return $editors;
}
Обратите внимание, что мы добавляем наш класс редактора изображений, WP_Image_Editor_Custom
чтобы WordPress проверил, может ли наш движок обрабатывать изменение размера, прежде чем тестировать другие движки.
Создание нашего редактора изображений
Теперь мы напишем наш собственный редактор изображений, чтобы мы могли сами выбирать имена файлов. Именование файлов обрабатывается методом WP_Image_Editor::generate_filename()
(оба механизма наследуют этот метод), поэтому мы должны перезаписать это в нашем пользовательском классе.
Поскольку мы планируем изменять только имена файлов, нам следует расширить один из существующих движков, чтобы нам не пришлось изобретать велосипед. Я расширю WP_Image_Editor_GD
в моем примере, поскольку у вас, вероятно, не включено расширение ImageMagick. Код взаимозаменяем для установки ImageMagick, хотя. Вы можете добавить и то, и другое, если вы планируете использовать тему в разных настройках.
// 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";
class WP_Image_Editor_Custom extends WP_Image_Editor_GD {
public function generate_filename($prefix = NULL, $dest_path = NULL, $extension = NULL) {
// If empty, generate a prefix with the parent method get_suffix().
if(!$prefix)
$prefix = $this->get_suffix();
// Determine extension and directory based on file path.
$info = pathinfo($this->file);
$dir = $info['dirname'];
$ext = $info['extension'];
// Determine image name.
$name = wp_basename($this->file, ".$ext");
// Allow extension to be changed via method argument.
$new_ext = strtolower($extension ? $extension : $ext);
// Default to $_dest_path if method argument is not set or invalid.
if(!is_null($dest_path) && $_dest_path = realpath($dest_path))
$dir = $_dest_path;
// Return our new prefixed filename.
return trailingslashit($dir)."{$prefix}/{$name}.{$new_ext}";
}
}
Большая часть кода выше была непосредственно скопирована из WP_Image_Editor
класса и прокомментирована для вашего удобства. Единственное реальное изменение заключается в том, что суффикс теперь является префиксом.
В качестве альтернативы, вы можете просто позвонить parent::generate_filename()
и использовать, mb_str_replace()
чтобы изменить суффикс на префикс, но я подумал, что это будет более склонно пойти не так.
Сохранение новых путей к метаданным
После загрузки image.jpg
папка для загрузки выглядит следующим образом:
2013/12/150x150/image.jpg
2013/12/300x300/image.jpg
2013/12/image.jpg
Все идет нормально. Однако при вызове базовых функций, таких как wp_get_attachment_image_src()
, мы заметим, что все размеры изображений сохраняются image.jpg
без указания нового пути к каталогу.
Мы можем обойти эту проблему, сохранив новую структуру папок в метаданных изображения (где хранятся имена файлов). Трассы данных через различные фильтры ( wp_generate_attachment_metadata
среди других) перед вставкой в базу данных, но так как мы уже реализуем пользовательские редактор изображений, мы можем вернуться назад к источнику метаданных размера изображения: WP_Image_Editor::multi_resize()
. Он генерирует массивы как этот:
Array (
[thumbnail] => Array (
[file] => image.jpg
[width] => 150
[height] => 150
[mime-type] => image/jpeg
)
[medium] => Array (
[file] => image.jpg
[width] => 300
[height] => 300
[mime-type] => image/jpeg
)
)
Мы перезапишем multi_resize()
метод в нашем пользовательском классе:
function multi_resize($sizes) {
$sizes = parent::multi_resize($sizes);
foreach($sizes as $slug => $data)
$sizes[$slug]['file'] = $data['width']."x".$data['height']."/".$data['file'];
return $sizes;
}
Как видите, я не удосужился заменить какой-либо код. Я просто вызываю родительский метод и позволяю ему генерировать метаданные. Затем я перебираю полученный массив и корректирую file
значение для каждого размера.
Сейчас wp_get_attachment_image_src($att_id, array(300, 300))
возвращается 2013/12/300x300/image.jpg
. Ура!
Последние мысли
Я надеюсь, что это дало вам хорошую основу для дальнейшего развития. Тем не менее, обратите внимание, что если изображение меньше указанного размера (например, 280x300), сгенерированный суффикс (в нашем случае префикс) и размеры изображения составляют 280x300, а не 300x300. Если вы загрузите много небольших изображений, вы получите много разных папок.
Хорошее решение было бы использовать либо пули размера в качестве имени папки ( small
, medium
, и так далее) или расширить код для круглых размеров до ближайшего предпочтительного размера изображения.
Вы отметили, что хотите использовать только ширину в качестве имени каталога. Будьте осторожны - плагины или темы могут генерировать два разных размера с одинаковой шириной, но разной высоты.
Кроме того, вы можете удалить папки «год / месяц», отключив «Организовать мои загрузки в папки по месяцам и годам» в меню «Настройки»> «Мультимедиа» или generate_filename
еще больше изменив настройки .
Надеюсь это поможет. Удачи!