Drupal удаляет не используемые изображения. С одной стороны это правильная стратегия — зачем хранить картинки, файлы, которые уже не используются? С другой стороны есть причины, когда их требуется сохранить.
Вот хотя бы две:
- SEO-шникам важно, чтобы картинки однажды попавшие в индекс от туда не пропадали.
- Возможно картинку нужно будет использовать в другом месте, в другое время или же требуется «подключить» к другому материалу, а в данной статье связь требуется убрать.
При удалении файла/изображения из поля, во время сохранения материала, связь будет удалена, а файл стерт. Поля файла/изображения при каждой загрузке даже одного и того же файла создают независимую запись в базе данных и файл с новым именем. Это приводит к тому, что файл всегда связан только с одной публикацией (или entity). При его удалении из поля, Drupal удаляет последнюю его связь и сам файл с диска.
Многократное использование одних и тех же файлов/картинок
Среди 3d part модулей есть хорошее решение для управления медиа-файлами плагин media, которое позволяет многократно прикреплять один и тот же файл к разным сущностям, ну и много ещё чего.
К нему можно еще добавить плагин media_library, который позволяет маркировать файлы как часть медиа-библиотеки. В объекте file появляется соответствующее свойство —
1 |
$file->library |
это признак того, что файл добавлен в библиотеку.
Было бы удачно, если бы при этом файлы, добавленные в библиотеку, не удалялись, когда пропадает последняя связь. Но в drupal 7 нельзя зацепиться за функцию удаления в том месте, где решается можно ли удалять файл или ещё нет (функция file_delete в /includes/file.inc).
Обходим удаление файлов
Пусть мы установили плагины media, media_library. Мы можем ставить флажок — library, но проблема в том, что нужна ещё одна дополнительная связь, которая бы удерживала файл от удаления.
Вы можете вручную прикреплять все нужные файлы к какой-то специальной публикации. Это нудно и не удобно. Но это не потребует от вас навыков программирования.
Второй путь — автоматизировать первый вариант — т.е. написать плагин, который бы все файлы, получающие флаг «library», подключал дополнительно к какой то системной entity и отключал бы от неё при сбрасывании этого флага. Требует некоторого времени, но было бы здорово иметь такой плагин, т.к. это самый правильный путь.
Есть и третий путь — это немного пропатчить /includes/file.inc, чтобы добавить проверку на то, что файл включен в библиотеку. Путь не очень хороший, но для седьмой версии Друпала подойдет, т.к. обновляется ядро уже не часто, а патч добавляет лишь несколько строк.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@@ -1298,10 +1298,16 @@ function file_delete(stdClass $file, $force = FALSE) { // that tests as TRUE. if (!$force && ($references = file_usage_list($file))) { return $references; } + // Patch preventing delete library file. + if (!empty($file->library)) { + watchdog('file', 'File %file could not be deleted because it is in Library.', array('%file' => $file->uri)); + return FALSE; + } + // Let other modules clean up any references to the deleted file. module_invoke_all('file_delete', $file); module_invoke_all('entity_delete', $file, 'file'); // Make sure the file is deleted before removing its row from the |