web-dev-qa-db-fra.com

Obtenez $ image_id après le téléchargement avec media_sideload_image ()

Je souhaite télécharger une image et la définir en tant qu'image sélectionnée dans un message. Ce que j'ai essayé était ceci:

$image_id = media_sideload_image($image_url, $post_id, $post_id);
update_post_meta($post_id, '_thumbnail_id', $image_id);

Mais media_sideload_image() ne renvoie pas le image_id, mais l'image de rendu HTML. Comment puis-je obtenir le image_id?

10
Xavin

Voici un exemple de contournement de cette limitation à l'aide d'actions/hooks:

function new_attachment( $att_id ){
    // the post this was sideloaded into is the attachments parent!

    // fetch the attachment post
    $att = get_post( $att_id );

    // grab it's parent
    $post_id = $att->post_parent;

    // set the featured post
    set_post_thumbnail( $post_id, $att_id );
}

// add the function above to catch the attachments creation
add_action('add_attachment','new_attachment');

// load the attachment from the URL
media_sideload_image($image_url, $post_id, $post_id);

// we have the image now, and the function above will have fired too setting the thumbnail ID in the process, so lets remove the hook so we don't cause any more trouble 
remove_action('add_attachment','new_attachment');

L'idée est que lorsque media_sideload_image est exécuté, il:

  • télécharge l'image
  • l'ajoute en pièce jointe (un message de type attachment)
  • puis joint cette pièce jointe à la publication dont vous avez fourni l'identifiant ($ post_id)

Votre problème est qu'il ne fournit pas l'ID de publication de pièces jointes nouvellement créé.

Mais , lors de la création d'une pièce jointe, une action contenant son identifiant est déclenchée. Nous pouvons nous en occuper avant de créer la pièce jointe, puis enregistrer la vignette présentée avec l'identifiant de publication qu'elle nous a fourni, puis la décrocher ensuite.

28
Tom J Nowell

J'ai créé une fonction pour obtenir l'ID de la base de données en effectuant une recherche par URL.

function get_attachment_id_from_src ($image_src) {
  global $wpdb;
  $query = "SELECT ID FROM {$wpdb->posts} WHERE guid='$image_src'";
  $id = $wpdb->get_var($query);
  return $id;
}

Vous pouvez obtenir une URL (à partir du code HTML) avec un quatrième paramètre défini sur 'src'Codex: media_sideload_image ()

$src = media_sideload_image($url, $item_id, $desc,'src');
get_attachment_id_from_src($src);
6
yondemon

La réponse de @Tom J Nowell est parfaite. J'ai trouvé une autre alternative (en utilisant différentes fonctions) expliqué ici mais j'aime celui-ci plus.

Dans mon cas, j'ai un tableau de $ posts avec tous les articles que je veux insérer et un $ media distinct (même clé que le $ nid en tant que $ posts) avec le média. Mon code est la même solution que celle de Tom, mais il a été modifié pour utiliser une fonction anonyme:

foreach( $posts as $nid=>$post )
    $posts[$nid]['ID'] = wp_insert_post( $post );

foreach( $posts as $nid=>$post )
    foreach( $media[$nid] as $m=>$mitem ) {

        if( 0 == $m ) add_action( 'add_attachment',
            function( $att_id ) use ($posts, $nid, $mitem) {
                update_post_meta($posts[$nid]['ID'], '_thumbnail_id', $att_id);
                $posts[$nid]['media_urls'][] = $mitem['url'];
            }
        );
        media_sideload_image($mitem['url'], $post['ID']);
        remove_all_actions( 'add_attachment' );
    }

Dans mon cas, je suppose que le premier élément de chaque $ media [$ nid] shuold est l’image sélectionnée de son message.

WordPress devrait définitivement changer media_sideload_image () afin de renvoyer l'ID $. En fait, la fonction l’a sous la main, voir le source ici . En fait, il existe un ticket de piste pour cela et ils ont même des correctifs pour l’appliquer à votre coeur entre temps si vous le souhaitez.

4
Jorge Orpinel

Les anciennes solutions ne sont plus nécessaires.

Vous pouvez obtenir l'ID avec un quatrième paramenter ($ return) défini sur 'id'

<?php media_sideload_image($file, $post_id, $desc, $return); ?> 

https://codex.wordpress.org/Function_Reference/media_sideload_image

4
olaf

Je cherchais une solution et j'ai décidé de regarder le code de media_sideload_image() qui était très simple. Il utilise media_handle_sideload() qui nous donne l’attachement id.

Je l'ai modifié pour renvoyer l'attachement id à la place de la source html de l'image, et même ajouté un moyen de lui envoyer un nouveau nom de fichier.

function media_sideload_image_custom($file, $post_id, $desc = null, $file_name = null)
{
    if ( ! empty($file) ) {
        // Download file to temp location
        $tmp = download_url( $file );

        // fix file filename for query strings
        if( empty($file_name) ) { 
            preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $file, $matches);
            $file_array['name'] = basename($matches[0]);
        } else {
            $file_array['name'] = sanitize_file_name($file_name);
        }
        $file_array['tmp_name'] = $tmp;

        // If error storing temporarily, unlink
        if ( is_wp_error( $tmp ) ) {
            @unlink($file_array['tmp_name']);
            $file_array['tmp_name'] = '';
        }

        // do the validation and storage stuff
        $id = media_handle_sideload( $file_array, $post_id, $desc );

        // If error storing permanently, unlink
        if ( is_wp_error($id) ) {
            @unlink($file_array['tmp_name']);
        }
        return $id;
    }
    return null;
}
3
Dario Zadro