web-dev-qa-db-fra.com

Détecter si le fichier image est une miniature

Je veux être capable de détecter si un fichier à un certain chemin est une vignette générée par WordPress. La seule caractéristique distinctive de la vignette WordPress, en ce qui concerne les fichiers individuels, est qu’elle se terminerait par deux ou trois chiffres, "x", deux ou trois autres chiffres, puis l’extension de fichier. La seule façon pour moi de faire cela serait d'utiliser une expression régulière pour détecter littéralement ce motif dans le nom du fichier. Y a-t-il un meilleur moyen auquel je ne pense pas? Sinon, quelqu'un peut-il m'aider avec la regex?

2
heller_benjamin

Vous devez connaître les paramètres actuels de la dimension de la vignette de votre site pour pouvoir détecter si l’URL $ est de la taille de la vignette.

$thumbnail_width = get_option( 'thumbnail_size_w' );
$thumbnail_height = get_option( 'thumbnail_size_h' );

// The do detection
// Assuming you have the image $url

$pattern = '%' . $thumbnail_width . 'x' . $thumbnail_height . '%';

if ( preg_match( $pattern, $url ) ) {
    // do your stuff here ...
}
3
Irene Mitchell

Voici deux autres approches qui pourraient ou non convenir à votre cas:

Approche n ° 1

Prenons par exemple la taille 300x200:

https://example.tld/wp-content/2017/03/vatnajokull-300x200.jpg

alors voici une façon de vérifier si cela fait vraiment partie de la médiathèque:

  1. Supprimez la partie -\d+x\d+ du nom du fichier afin qu'elle devienne:

    $url = 'https://example.tld/wp-content/2017/03/vatnajokull.jpg';
    
  2. Utilisez la fonction de base $attachment_id = attachment_url_to_postid( $url ) pour obtenir l’ID de pièce jointe possible.

  3. Utilisez l'ID de pièce jointe de la partie 2. pour extraire les métadonnées avec $meta = wp_get_attachment_metadata( $attahcment_id ) qui contient toutes les tailles d'image générées. Il récupère la valeur méta _wp_attachment_metadata.
  4. Vérifiez si la taille de 300x200 a été générée en regardant dans le tableau de métadonnées de tailles (c'est-à-dire $meta['sizes']) et par exemple. file_exists( $path ) pour vous assurer qu'il existe réellement.

J'espère que vous pourrez remplir les parties manquantes ;-)

Approche # 2

Le noyau utilise une recherche générique LIKE sur les méta-valeurs _wp_attachment_metadata, au sein de wp_delete_attachment() ( source ), pour voir si d’autres pièces jointes l’utilisent comme une vignette, avant de le supprimer. Cela pourrait fonctionner ici mais serait moins précis car il effectue une recherche dans des tableaux sérialisés. Cela ressemble à ceci dans le noyau:

if ( ! $wpdb->get_row( 
    $wpdb->prepare( 
        "SELECT meta_id FROM $wpdb->postmeta 
         WHERE meta_key = '_wp_attachment_metadata' 
             AND meta_value LIKE %s 
             AND post_id <> %d", 
        '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', 
        $post_id
    )
) ) {
1
birgire

J'ai cloné ma médiathèque et ai exécuté ce script de noeud sur mes fichiers Wordpress Media imbriqués, puis j'ai parcouru les fichiers/dossiers en boucle. Insérez une logique dans la boucle pour que le nom de fichier repose sur une expression régulière correspondant à la convention de dénomination de la vignette filename-SIZExSIZE.ext. J'ai utilisé le système de fichiers nœud et le chemin d'accès pour déplacer les fichiers de manière appropriée.

const glob = require("glob");
const fs = require('fs');
const { resolve, basename } = require('path');

glob("./../media/**/*.png", {}, function (er, files) {

  var count = 0;
  for (const file of files) {
    if(/\b\d{2,4}[x.]?\d{2,4}[..]([a-z\.]{3})\b/.test(file) === false){

      let oldFileNamePath = resolve(file);
      let newFileNamePath = resolve('./../media-new/'+ basename(file));

       fs.rename(oldFileNamePath, newFileNamePath, function (err) {
         if (err) throw err;
         console.log(count, 'renamed complete', newFileNamePath);
       });

       count++;
    }

  }

});
0
Kameron Zach

Ok voici comment je l'ai fait. J'ai d'abord vérifié si elle avait des extensions de fichier image prises en charge, car nous pouvons enregistrer une requête DB sinon. Ensuite, j'ai simplement vérifié dans la base de données un identifiant de pièce jointe. S'il n'y a pas d'ID de pièce jointe, je suppose qu'il s'agit d'une vignette. Peut-être pas parfait pour chaque solution mais fonctionnera pour mon application. Merci pour les suggestions, ils ont fait passer mon esprit dans la bonne direction.

function is_not_thumbnail( $url ) {
    $result = true;
    $ext = substr( $url, -4 );

    if ( 
        $ext === '.jpg' || 
        $ext ===  '.JPG' ||
        $ext === 'jpeg' ||
        $ext === 'JPEG' ||
        $ext === '.png' ||
        $ext === '.PNG' ||
        $ext === '.gif' ||
        $ext === '.GIF' ||
        $ext === '.ico' ||
        $ext === '.ICO' 
     ) {
        if ( get_attachment_id_from_url( $url ) === 'null' ) {
            $result = false;
        }
    }

    return $result;

}

function get_attachment_id_from_url( $url ) {
    global $wpdb;

    $result = $wpdb->get_results( 'SELECT ID FROM ' . $wpdb->prefix . 'posts WHERE guid = "' . $url . '"' );


    if ( !empty( $result[0] ) ) {
        return $result[0]->ID;  
    } else {
        return false;
    }

}
0
heller_benjamin