web-dev-qa-db-fra.com

Reconstruire imagecache

J'ai un champ d'image par nœud qui passe par imagecache. Comme imagecache met en cache à la demande, les fichiers/variantes de cache ne sont créés que lorsqu'ils sont demandés pour la première fois. Donc, si je mets à jour un tas d'images, redéploie ou autrement fais exploser le cache entier, c'est au premier visiteur de traiter ce fichier.

Comment puis-je épargner à cet utilisateur le temps de chargement et reconstruire manuellement tout le cache?

La dernière fois que cela est arrivé, j'ai chargé par programme chaque lien de nœud avec jquery ...

On dirait un plugin Drush parfait ... devrait probablement chercher à l'écrire, mais je suis curieux de savoir si quelqu'un d'autre a une solution pour cela.

5
ack

Vous pouvez créer un module personnalisé, puis utiliser hook_cron () pour reconstruire l'imagecage.

Mise à jour

Je viens de passer la dernière heure à essayer de trouver comment le faire côté serveur et je pense que je l'ai craqué.

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

Comment ça fonctionne:

  1. Obtenez tous les nœuds publiés
  2. Pour chaque nœud obtient le type de nœud
  3. Obtient un tableau de champs pour le nœud actuel en cours d'itération
  4. Itère tous les champs et vérifie s'il y a des champs d'image
  5. Si le champ d'image est trouvé, obtenez le préréglage de cache d'image associé
  6. Itérer sur les instances de champ d'image du nœud
  7. Pour chaque instance de champ d'image, obtenez le chemin du fichier d'image
  8. Convertir le chemin du fichier image en chemin du cache d'image
  9. Lisez le chemin du fichier en utilisant file_get_contents () sur HTTP pour forcer le cache d'image à générer une image mise en cache.

Je l'ai testé et cela a très bien fonctionné pour moi dans Drupal 6. Une Drupal 7 serait légèrement plus délicate en raison des changements dans le fichier sous-jacent) API.

Vous devrez créer un module personnalisé et coller cette fonction. Assurez-vous également de changer le nom du hook de rebuildimagecache au nom de votre module personnalisé.

J'ai utilisé hook_cron() pour qu'il s'exécute lorsque cron est exécuté mais vous pouvez l'exécuter manuellement via une commande drush.

12
Camsoft

Approche low tech ...

  1. Créez une nouvelle vue de nœud.
  2. Définissez un filtre pour le type de contenu qui contient les champs d'image.
  3. Ajoutez vos champs d'image en utilisant le préréglage ImageCache que vous souhaitez pré-mettre en cache.
  4. Définissez-le sur pas de page, sans limite de nombre de nœuds.
  5. Chargez la vue.
  6. Regardez votre serveur s'écraser sous la charge. Si le délai est écoulé, rechargez la vue.

Oh, et assurez-vous que seuls les administrateurs ont des autorisations sur cette vue.

5
rogerhoward

Un conseil de performance: vous n'avez pas besoin de charger tout le contenu de l'image pour déclencher le cache d'image, vous pouvez également simplement demander les en-têtes. Donc cette ligne:

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

devient

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

Ma solution:

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

Il y a eu une tentative pour faire fonctionner ce genre de chose, voir Imagecache Batch mais je ne sais pas où en est le développement de ces fonctionnalités. Vous ne mentionnez pas si vous avez affaire à D6 ou D7, mais je voudrais examiner les actions et les règles dans 6.x-2.x-dev et voir où elles en sont.

2
George

Cela a été fait et fonctionne bien, voir ici https://drupal.org/node/587086

Essayez le patch de fichier complet à la fin du fil. Assurez-vous de l'exécuter à l'intérieur /sites/all/modules/imagecache/imagecache.drush.inc et non à la racine, comme c'est standard.

0
Gabriel R.