Holen Sie sich $ image_id nach dem Hochladen mit media_sideload_image ()

10

Ich möchte ein Bild hochladen und es als empfohlenes Bild in einem Beitrag festlegen. Was ich versucht habe war folgendes:

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

Gibt media_sideload_image()aber nicht das image_id, sondern das Render-HTML-Bild zurück. Wie kann ich das bekommen image_id?

Xavin
quelle

Antworten:

28

Hier ist ein Beispiel, wie Sie diese Einschränkung mithilfe von Aktionen / Hooks umgehen können:

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');

Die Idee ist, dass wenn es ausgeführt media_sideload_imagewird, es:

  • lädt das Bild herunter
  • fügt es als Anhang hinzu (ein Beitrag vom Typ attachment)
  • Hängt dann diesen Anhang an den Beitrag an, dessen ID Sie angegeben haben ($ post_id).

Ihr Problem ist, dass die neu erstellte ID für Anhangsposten nicht angegeben wird.

Aber , wenn eine Anlage erstellt wird, wird eine Aktion seine ID fired enthält. Wir können uns daran anschließen, bevor wir den Anhang erstellen, und das vorgestellte Miniaturbild mit der Post-ID speichern, die es uns gegeben hat, und anschließend aushaken.

Tom J Nowell
quelle
1
Brillant! Das hat so viel geholfen.
M-Torin
2
Wenn dies Ihre Frage beantwortet, können Sie sie als richtig markieren?
Tom J Nowell
Ich kann dein Englisch nicht lesen. Kann jemand diesen Beitrag bearbeiten?
HiDd3N
2
@ HiDd3N Ich habe einige der verwendeten Englisch vereinfacht, es sollte häufigere Wörter mit einem niedrigeren Lesealter haben
Tom J Nowell
6

Ich habe eine Funktion erstellt, um die ID von der Datenbank abzurufen und nach URL zu suchen.

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

Sie können eine URL (installiert von HTML-Code) mit einem vierten Parameter erhalten, der auf 'src' Codex gesetzt ist: media_sideload_image ()

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

@ Tom J Nowells Antwort ist genau richtig. Ich habe eine andere Alternative gefunden (mit verschiedenen Funktionen) , die hier erklärt wurde, aber ich mag diese noch mehr.

In meinem Fall habe ich ein Array von $ posts mit allen Posts, die ich einfügen möchte, und ein separates $ media (dieselben $ nid-Schlüssel wie $ posts) mit dem Medium. Mein Code ist die gleiche Lösung wie der von Tom, wurde jedoch überarbeitet, um eine anonyme Funktion zu verwenden:

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' );
    }

In meinem Fall gehe ich davon aus, dass das erste Element in jedem $ media [$ nid] das vorgestellte Bild seines Beitrags sein sollte.

WordPress sollte media_sideload_image () definitiv ändern, damit es die $ id zurückgibt. In der Tat hat die Funktion es zur Hand, siehe die Quelle hier . Tatsächlich gibt es dafür ein Track Ticket und sie haben sogar Patches, um dies in der Zwischenzeit auf Ihren Kern anzuwenden, wenn Sie möchten.

Jorge Orpinel
quelle
Sieht so aus, als ob es geplant ist, in 4.8 gepatcht zu werden
Tom Auger
3

Ich suchte nach einer Lösung und beschloss, mir den Code anzusehen, der media_sideload_image()sehr einfach war. Es verwendet media_handle_sideload(), was uns den Eigensinn gibt id.

Ich habe es geändert, um den Anhang idanstelle der HTML-Quelle des Bildes zurückzugeben, und sogar eine Möglichkeit hinzugefügt, ihm einen neuen Dateinamen zu senden.

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
quelle