web-dev-qa-db-fra.com

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

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) chargé un fichier portant le même nom (pourquoi? Parce qu'il s'agissait d'une résolution supérieure et que j'essayais de remplacer les versions basse résolution de la même image) et 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?

31
Ankur

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;
    }
}
28
Rarst

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.

14
Ego Ipse

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 plus tard 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;
}
3
Luke Gedeon

Ok j'ai trouvé la réponse que personne n'a sur le net que je cherchais depuis plusieurs jours. Conserver dans le mien ne fonctionne que si votre thème ou plug-in utilise la fonction WP_Customize_Image_Control() si vous utilisez la fonction WP_Customize_Media_Control(). La fonction get_theme_mod() renverra l'ID et non l'url.

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

Beaucoup de messages sur les forums ont la 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 );

Markup

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

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 votre find_image_post_id()

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

0
Lefan