Перестроить кэш изображений


У меня есть поле изображения для каждого узла, которое выполняется через кэш изображений. Поскольку imagecache кэширует по требованию, файлы/варианты кэша не создаются до тех пор, пока они не будут запрошены в первый раз. Поэтому, если я обновлю кучу изображений, повторно разверну или иным образом уничтожу весь кэш, первый посетитель должен обработать этот файл.

Как я могу сэкономить этому пользователю время загрузки и вручную перестроить весь кэш?

В последний раз, когда это произошло, я программно загрузил каждый узел связь с jquery...

Кажется идеальным плагином Drush... вероятно, следует подумать о том, чтобы написать это, но мне любопытно, есть ли у кого-нибудь еще решение для этого.

 5
Author: Benedikt, 2011-03-02

6 answers

Вы можете создать пользовательский модуль, а затем использовать hook_cron() для восстановления ячейки изображений.

Обновление

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

/**
 * Implements hook_cron().
 */
function rebuildimagecache_cron() {
    global $base_url;

    // get published nodes
    $result = db_query('SELECT nid FROM {node} WHERE status = 1');
    while ($nodes = db_fetch_array($result)) {
        $node = node_load($nodes['nid']);
        $node_type = $node->type;

        // get cck fields for the current nodes node_type
        $fields = content_fields(NULL, $node_type);
        foreach ($fields as $key => $value) {

            // only deal with file fields that use the image widegt tyoe
            if ($value['type'] == 'filefield' && $value['widget']['type'] == 'imagefield_widget') {
                $preset_tokens = explode('_', $value['display_settings']['full']['format']);
                $imagecache_preset = $preset_tokens[0];
                $field_name = $value['field_name'];

                // iterate over each field instance 
                foreach ($node->$field_name as $field_instance) {
                    $filepath = $field_instance['filepath'];
                    $cachedpath = imagecache_create_path($imagecache_preset, $filepath);
                    file_get_contents($base_url . base_path() . $cachedpath);
                }
            }
        }       
    }   
}

Как это работает:

  1. Получить все опубликованные узлы
  2. Для каждого узла получает тип узла
  3. Получает массив полей для текущего узла, который повторяется
  4. Перебирает все поля и проверяет, есть ли какие-либо поля изображений
  5. Если поле изображения найдено, то получите предустановку кэша изображений, связанную с
  6. Перебирать экземпляры полей изображений узла
  7. Для каждого экземпляра поля изображения получить путь к файлу изображения
  8. Преобразовать путь к файлу изображения в путь к кэшу изображения
  9. Прочитайте путь к файлу с помощью file_get_contents() по протоколу HTTP, чтобы заставить кэш изображений генерировать кэшированное изображение.

Я протестировал его, и он отлично сработал для меня в Drupal 6. Версия Drupal 7 была бы немного сложнее из-за изменения в базовом файловом API.

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

Я использовал hook_cron(), чтобы он запускался при запуске cron, но вы можете запустить его вручную с помощью команды drush.

 12
Author: Camsoft, 2011-03-03 23:46:49

Низкотехнологичный подход...

  1. Создайте новое представление узла.
  2. Установите фильтр для типа контента, который содержит поля изображения.
  3. Добавьте поля изображения, используя любую предустановку ImageCache, которую вы хотите предварительно кэшировать.
  4. Установите для него значение не страница, без ограничения количества узлов.
  5. Загрузите представление.
  6. Наблюдайте, как ваш сервер ломается под нагрузкой. Если время ожидания истекло, перезагрузите представление.

О, и убедитесь, что только у администраторов есть разрешения на это представление.

 5
Author: rogerhoward, 2011-09-09 23:22:00

Один совет по производительности: Вам не нужно загружать все содержимое изображения, чтобы вызвать кэш изображений, вы также можете просто запросить заголовки. Итак, эта строка:

file_get_contents($base_url . base_path() . $cachedpath);

Становится

get_headers($base_url . base_path() . $cachedpath);
 4
Author: Stan James, 2011-05-16 21:17:19

Мое решение:

function example_cron() {
    $result = db_query('SELECT fid, uri FROM {file_managed} WHERE filemime like :mime AND status = :status', array('mime' => 'image/%', 'status' => FILE_STATUS_PERMANENT));
    $queue = DrupalQueue::get('generate_image_styles');
    foreach ($result as $img_info) {
        foreach(image_styles() as $style) {
            $derivative_uri = image_style_path($style['name'], $img_info->uri);
            if (file_exists($derivative_uri)) continue; // skip existing files
            $data = (object) array(
                    'style' => $style,
                    'img_info' => $img_info,
                    'derivative_uri' => $derivative_uri
                     );
        $queue->createItem($data);
        }
    }
}


function example_cron_queue_info(){
    $queues['generate_image_styles'] = array(
        'worker callback' => '_example_generate_image_styles',
        'time' => 30
        );
return $queues;
}

function _example_generate_image_styles($data){
    if (!file_exists($data->derivative_uri)) {
        image_style_create_derivative($data->style, $data->img_info->uri, $data->derivative_uri);
    }
}
 3
Author: atavio, 2012-02-08 15:53:18

Была попытка заставить работать такие вещи, см. Пакет Imagecache, но я не уверен, на каком этапе находится разработка этих функций. Вы не упоминаете, имеете ли вы дело с D6 или D7, но я бы изучил действия и правила в 6.x-2.x-dev и посмотрел, где это находится.

 2
Author: George, 2012-03-06 19:53:38

Это было сделано и хорошо работает, смотрите здесь https://drupal.org/node/587086

Попробуйте установить полное исправление файла в конце потока. Убедитесь, что вы запускаете его внутри /sites/all/modules/imagecache/imagecache.drush.inc, а не в корне, как обычно.

 0
Author: Gabriel R., 2013-04-11 15:24:16