Transformer une URL en pièce jointe / identifiant de publication

32

Existe-t-il un moyen de prendre l'URL d'une image et de trouver la pièce jointe ou l'ID de publication de cette image dans la base de données?

Voici la situation:

Je suis en train de parcourir toutes les balises 'img' entourées par les balises 'a' dans le contenu de mon message. si l'attribut src de la balise 'img' ne correspond pas à l'attribut href de la balise 'a' extérieure, je souhaite remplacer la balise 'img'. Ce faisant, si le "img" à supprimer est dans la galerie, je souhaite supprimer ce message, puis mettre mon remplaçant "img" à sa place. J'ai essayé d'utiliser une fonction comme celle-ci:

function find_image_post_id($url) {
  global $wpdb;
  $postid = $wpdb->get_var($wpdb->prepare("SELECT DISTINCT ID FROM $wpdb->posts WHERE guid='$url'"));
  if ($postid) {
    return $postid;
  }
  return false;
}

Cela n’apparaît apparemment pas correct, car le guide n’est ironiquement pas unique au monde. J'avais (précédemment dans le même script) téléchargé un fichier portant le même nom (pourquoi? Car il s'agissait d'une résolution supérieure et j'essaie de remplacer les versions basse résolution de la même image) et bien que wordpress enregistre l'image sous un nom différent le répertoire, les guides étaient définis pour être les mêmes. (éventuellement un bug).

Y a-t-il une autre technique que je peux utiliser?

Ankur
la source
Vous pouvez définir des variables de requête en fonction de votre URL, instancier WP_Query et en obtenir les informations.
hakre
Cela vous aiderait si vous pouviez mettre à jour votre question et poster quelques exemples de votre code HTML incluant les URL que vous souhaitez remplacer afin que nous puissions en discuter.
MikeSchinkel
Mike est juste là. Les images plus grandes que vous associez-vous à des sites externes? Si ce n'est pas le cas, il vous suffit de choisir la taille réelle lorsque vous ajoutez l'image à votre message et vous avez la possibilité de ne pas la lier n'importe où si cela n'a aucun sens.
Sanchothefat

Réponses:

30

Fonction massivement améliorée développée pour le plugin lourd d'images:

if ( ! function_exists( 'get_attachment_id' ) ) {
    /**
     * Get the Attachment ID for a given image URL.
     *
     * @link   http://wordpress.stackexchange.com/a/7094
     *
     * @param  string $url
     *
     * @return boolean|integer
     */
    function get_attachment_id( $url ) {

        $dir = wp_upload_dir();

        // baseurl never has a trailing slash
        if ( false === strpos( $url, $dir['baseurl'] . '/' ) ) {
            // URL points to a place outside of upload directory
            return false;
        }

        $file  = basename( $url );
        $query = array(
            'post_type'  => 'attachment',
            'fields'     => 'ids',
            'meta_query' => array(
                array(
                    'key'     => '_wp_attached_file',
                    'value'   => $file,
                    'compare' => 'LIKE',
                ),
            )
        );

        // query attachments
        $ids = get_posts( $query );

        if ( ! empty( $ids ) ) {

            foreach ( $ids as $id ) {

                // first entry of returned array is the URL
                if ( $url === array_shift( wp_get_attachment_image_src( $id, 'full' ) ) )
                    return $id;
            }
        }

        $query['meta_query'][0]['key'] = '_wp_attachment_metadata';

        // query attachments again
        $ids = get_posts( $query );

        if ( empty( $ids) )
            return false;

        foreach ( $ids as $id ) {

            $meta = wp_get_attachment_metadata( $id );

            foreach ( $meta['sizes'] as $size => $values ) {

                if ( $values['file'] === $file && $url === array_shift( wp_get_attachment_image_src( $id, $size ) ) )
                    return $id;
            }
        }

        return false;
    }
}
Rarst
la source
1
Pouvez-vous expliquer pourquoi vous interrogez les deux _wp_attached_fileet _wp_attachment_metadata?
Stephen Harris
3
@StephenHarris car l'URL peut pointer sur n'importe quelle taille d'image, qui portent toutes un nom de fichier différent
Rarst
1
Cela fonctionne très bien, mais il convient de noter ici que, depuis WordPress 4, il existe une fonction intégrée pour le faire, comme mentionné par Gabriel dans une autre réponse. Cela fonctionne exactement de la même façon que celui-ci.
Chris Rae
2
@ChrisRae Si vous regardez la source, la fonction principale ne fonctionnera pas avec les tailles d'image, mais uniquement avec l'image principale.
Rarst
Je pense que la fonction intégrée dans WordPress fonctionne mieux. Cela ne fonctionnait pas dans ma production mais fonctionnait sur Staging (qui ne possède pas de certificat SSL). La fonction intégrée (comme indiqué par Ego Ipse ci-dessous) fonctionne dans les deux environnements.
Syed Priom
15

Toutes ces fonctions complexes peuvent être réduites à une seule fonction:

attachment_url_to_postid ()

Il vous suffit d'analyser l'URL de l'image pour récupérer l'ID de pièce jointe:

$attachment_id = attachment_url_to_postid( $image_url );
echo $attachment_id;

C'est tout ce dont vous avez besoin.

Ego Ipse
la source
6
Notamment, cela ne fonctionnera pas avec les tailles d'image, la version principale ne recherchant que le fichier "principal" joint.
Rarst
3

J'ai modifié le code de Rarst pour vous permettre de ne faire correspondre que le nom du fichier au lieu du chemin complet. Ceci est utile si vous êtes sur le point de charger de côté l’image si elle n’existe pas. Actuellement, cela ne fonctionne que si les noms de fichiers sont uniques, mais j'ajouterai une vérification de hachage ultérieurement pour aider les images portant le même nom de fichier.

function get_attachment_id( $url, $ignore_path = false ) {

if ( ! $ignore_path ) {

    $dir = wp_upload_dir();
    $dir = trailingslashit($dir['baseurl']);

    if( false === strpos( $url, $dir ) )
        return false;
}

$file = basename($url);

$query = array(
    'post_type' => 'attachment',
    'fields' => 'ids',
    'meta_query' => array(
        array(
            'key'     => '_wp_attached_file',
            'value'   => $file,
            'compare' => 'LIKE',
        )
    )
);

$ids = get_posts( $query );

foreach( $ids as $id ) {
    $match = array_shift( wp_get_attachment_image_src($id, 'full') );
    if( $url == $match || ( $ignore_path && strstr( $match, $file ) ) )
        return $id;
}

$query['meta_query'][0]['key'] = '_wp_attachment_metadata';
$ids = get_posts( $query );

foreach( $ids as $id ) {

    $meta = wp_get_attachment_metadata($id);

    foreach( $meta['sizes'] as $size => $values ) {
        if( $values['file'] == $file && ( $ignore_path || $url == array_shift( wp_get_attachment_image_src($id, $size) ) ) )
            return $id;
    }
}

return false;
}
Luke Gedeon
la source
3

Ok j'ai trouvé la réponse que personne n'a sur le net que je cherchais depuis plusieurs jours. Garder dans le mien, cela ne fonctionne que si votre thème ou plugin utilise le WP_Customize_Image_Control()si vous utilisez WP_Customize_Media_Control()le get_theme_mod()renverra l'identifiant et non l'url.

Pour ma solution, j'utilisais la version la plus récente WP_Customize_Image_Control()

Beaucoup de messages sur les forums ont le get_attachment_id()qui ne fonctionne plus. j'ai utiliséattachment_url_to_postid()

Voici comment j'ai pu le faire. J'espère que cela aide quelqu'un là-bas

// This is getting the image / url
$feature1 = get_theme_mod('feature_image_1');

// This is getting the post id
$feature1_id = attachment_url_to_postid($feature1);

// This is getting the alt text from the image that is set in the media area
$image1_alt = get_post_meta( $feature1_id, '_wp_attachment_image_alt', true );

Balisage

<a href="<?php echo $feature1_url; ?>"><img class="img-responsive center-block" src="<?php echo $feature1; ?>" alt="<?php echo $image1_alt; ?>"></a>
DevTurtle
la source
0

Voici une solution alternative:

$image_url = get_field('main_image'); // in case of custom field usage
$image_id = attachment_url_to_postid($image_url);

// retrieve the thumbnail size of our image
$image_thumb = wp_get_attachment_image_src($image_id, 'thumbnail');

Depuis WP 4.0, ils ont introduit une fonction attachment_url_to_postid()qui se comporte de la même manière que la vôtre.find_image_post_id()

S'il vous plaît vérifier le cette URL pour votre référence.

Lefan
la source