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

10

Je souhaite télécharger une image et la définir comme image sélectionnée dans un message. J'ai essayé 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 l'obtenir image_id?

Xavin
la source

Réponses:

28

Voici un exemple de la façon de contourner cette limitation en utilisant des 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 quand il media_sideload_imageest exécuté, il:

  • télécharge l'image
  • l'ajoute en pièce jointe (un message de type attachment)
  • attache ensuite cette pièce jointe au message dont vous avez fourni l'ID ($ post_id)

Votre problème est qu'il ne fournit pas l'ID de la pièce jointe nouvellement créée.

Mais , lorsqu'une pièce jointe est créée, une action est déclenchée contenant son ID. Nous pouvons nous y connecter avant de créer la pièce jointe, et enregistrer la vignette en vedette avec l'ID du message qu'elle nous a donné, puis décrocher après.

Tom J Nowell
la source
1
Brillant! Cela a beaucoup aidé.
m-torin
2
Si cela répond à votre question, pourriez-vous la marquer comme correcte?
Tom J Nowell
je ne peux pas lire votre anglais. quelqu'un peut-il modifier ce post?
HiDd3N
2
@ HiDd3N J'ai simplifié une partie de l'anglais utilisé, il devrait avoir des mots plus courants avec un âge de lecture inférieur
Tom J Nowell
6

J'ai construit une fonction pour obtenir l'ID de la base de données, en recherchant 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 (insted de 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);
yondemon
la source
4

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

Dans mon cas, j'ai un tableau de messages $ avec tous les messages que je veux insérer et un $ media séparé (mêmes clés $ nid que $ posts) avec les médias. Mon code est la même solution que Tom mais refactorisé 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] doit être l'image sélectionnée de son message.

WordPress devrait définitivement changer media_sideload_image () pour qu'il retourne le $ id. En fait, la fonction l'a à portée de main, voir la source ici . En fait, il y a un ticket de piste pour cela et ils ont même des correctifs pour l'appliquer à votre cœur en attendant si vous le souhaitez.

Jorge Orpinel
la source
On dirait qu'il devrait être corrigé en 4.8
Tom Auger
3

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

Je l'ai modifié pour renvoyer la pièce jointe idau lieu de la source html de l'image, et j'ai 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;
}
Dario Zadro
la source