it-swarm-es.com

Reconstruir caché de imágenes

Tengo un campo de imagen por nodo que se ejecuta a través de imagecache. Dado que el almacenamiento en caché de imágenes a pedido, los archivos/variaciones de caché no se crean hasta que se solicitan por primera vez. Por lo tanto, si actualizo un montón de imágenes, vuelvo a implementarlas o, de lo contrario, elimino todo el caché, corresponde al primer visitante procesar ese archivo.

¿Cómo puedo ahorrarle a ese usuario el tiempo de carga y reconstruir manualmente todo el caché?

La última vez que esto ocurrió, cargué programáticamente cada enlace de nodo con jquery ...

Parece un complemento Drush perfecto ... probablemente debería considerar escribirlo, pero tengo curiosidad por saber si alguien más tiene una solución para esto.

5
ack

Puede crear un módulo personalizado y luego usar hook_cron () para reconstruir la caja de imágenes.

Actualizar

Acabo de pasar la última hora tratando de averiguar cómo hacerlo en el lado del servidor y creo que lo he descifrado.

/**
 * 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);
                }
            }
        }       
    }   
}

Cómo funciona:

  1. Obtenga todos los nodos publicados
  2. Para cada nodo obtiene el tipo de nodo
  3. Obtiene una matriz de campos para el nodo actual que se está iterando
  4. Itera sobre todos los campos y comprueba si alguno son campos de imagen
  5. Si se encuentra el campo de imagen, obtenga el preajuste de caché de imagen asociado
  6. Iterar sobre instancias de campo de imagen del nodo
  7. Para cada instancia de campo de imagen, obtenga la ruta del archivo de imagen
  8. Convertir ruta de archivo de imagen en ruta de caché de imagen
  9. Lea la ruta del archivo usando file_get_contents () a través de HTTP para forzar el caché de imagen para generar la imagen en caché.

Lo probé y funcionó muy bien para mí en Drupal 6. A Drupal 7 sería un poco más difícil debido a los cambios en el archivo subyacente API.

Tendrá que crear un módulo personalizado y pegar esta función. Asegúrese de cambiar también el nombre del gancho de rebuildimagecache al nombre de su módulo personalizado.

He usado hook_cron() para que se ejecute cuando se ejecuta cron, pero puede ejecutarlo manualmente mediante un comando drush.

12
Camsoft

Enfoque de baja tecnología ...

  1. Crea una nueva vista de nodo.
  2. Establezca un filtro para el tipo de contenido que contenga los campos de imagen.
  3. Agregue sus campos de imagen, utilizando cualquier valor preestablecido de ImageCache que desee almacenar previamente en caché.
  4. Establézcalo en no página, sin límite de conteo de nodos.
  5. Cargue la vista.
  6. Observe cómo su servidor se aplasta bajo la carga. Si se agotó el tiempo, vuelva a cargar la vista.

Ah, y asegúrese de que solo los administradores tengan permisos en esa vista.

5
rogerhoward

Un consejo de rendimiento: no necesita cargar todo el contenido de la imagen para activar el almacenamiento en caché de imágenes, también puede solicitar los encabezados. Entonces esta línea:

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

se convierte

get_headers($base_url . base_path() . $cachedpath);
4
Stan James

Mi solución:

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
atavio

Se intentó hacer funcionar este tipo de cosas, vea Imagecache Batch pero no estoy seguro de dónde se encuentra el desarrollo de estas características. No mencionas si estás lidiando con D6 o D7, pero buscaría en las acciones y reglas en 6.x-2.x-dev y vería dónde está.

2
George

Esto se hizo y funciona bien, vea aquí https://drupal.org/node/587086

Pruebe el parche de archivo completo al final del hilo. Asegúrate de ejecutarlo dentro de /sites/all/modules/imagecache/imagecache.drush.inc y no en la raíz, como es estándar.

0
Gabriel R.