Laden Sie ein Bild von einer Webseite in den Standardordner für Uploads herunter

8

Ich schreibe ein benutzerdefiniertes Thema / Plugin, in dem ich Bilder programmgesteuert von bestimmten Webseiten in den Upload-Ordner herunterladen und sie dann als Teil des Beitrags einfügen muss.

So konnte ich die Bild-URLs programmgesteuert finden und sie dann im Upload-Ordner unter wp-content speichern. Dieser Ordner enthält jedoch eine bestimmte WordPress-Ordnerstruktur für die gespeicherten Bilder.

Meine Frage ist nun, gibt es eine WordPress-API oder -Funktion oder -Methode, mit der ich Bilder aus dem Internet herunterladen und im Upload-Ordner speichern kann? Und wenn ja, was ist das?

Was soll ich sonst tun, um diese Bilder zu speichern?

Bisher mache ich das

$filetype = wp_check_filetype(basename($image_file_name), null );

$upload_dir = wp_upload_dir();

$attachment = array(
    'guid' => $upload_dir['url'] . '/' . basename( $image_file_name ), 
    'post_mime_type' => $filetype['type'],
    'post_title' => preg_replace('/\.[^.]+$/', '', basename($image_file_name)),
    'post_content' => '',
    'post_status' => 'inherit'
);

$attachment_id = wp_insert_attachment( $attachment, $image_file_name, $post_id );

$attachment_data = wp_generate_attachment_metadata( $attachment_id, $image_file_name );

wp_update_attachment_metadata( $attachment_id,  $attachment_data );
set_post_thumbnail( $post_id, $attachment_id );

Aber der obige Code gibt mir den folgenden Fehler

imagejpeg(http://wscdn.bbc.co.uk/worldservice/assets/images/2013/07/21/130721173402_egypts_new_foreign_minister_fahmy_304x171_reuters-150x150.jpg): failed to open stream: HTTP wrapper does not support writeable connections in C:\dev\wordpress\pterodactylus\wp-includes\class-wp-image-editor.php on line 334

Und nach weiteren Untersuchungen sieht es so aus, als ob der Fehler durch verursacht wird

$attachment_data = wp_generate_attachment_metadata( $attachment_id, $image_file_name );

Und nach noch weiteren Untersuchungen heißt es in der Dokumentation für wp_insert_attachment(), dass The file MUST be on the uploads directoryin Bezug auf die$image_file_name

Wie lade ich ein Bild herunter und speichere es korrekt in meinem Beitrag?

Vielen Dank.

Greeso
quelle
Ich hatte Probleme damit, als es um Berechtigungsprobleme für die Bilder im Upload-Verzeichnis ging - sie mussten dem Serverbenutzer gehören (z. B. www-Daten unter Apache / Linux)
icc97
Dieses WordPress-Support-Thema hat weitere Informationen
icc97

Antworten:

11

Ich musste dies kürzlich über ein nächtliches Cron-Skript für einen Social-Media-Stream tun. $ parent_id ist die ID des Beitrags, an den Sie das Bild anhängen möchten.

function uploadRemoteImageAndAttach($image_url, $parent_id){

    $image = $image_url;

    $get = wp_remote_get( $image );

    $type = wp_remote_retrieve_header( $get, 'content-type' );

    if (!$type)
        return false;

    $mirror = wp_upload_bits( basename( $image ), '', wp_remote_retrieve_body( $get ) );

    $attachment = array(
        'post_title'=> basename( $image ),
        'post_mime_type' => $type
    );

    $attach_id = wp_insert_attachment( $attachment, $mirror['file'], $parent_id );

    require_once(ABSPATH . 'wp-admin/includes/image.php');

    $attach_data = wp_generate_attachment_metadata( $attach_id, $mirror['file'] );

    wp_update_attachment_metadata( $attach_id, $attach_data );

    return $attach_id;

}

Ex:

uploadRemoteImageAndAttach('http://some-external-site.com/the-image.jpg', 122);
Divups
quelle
1

Sie haben den Code zum Abrufen und Speichern des Bildes nicht veröffentlicht, daher ist es unmöglich zu sagen, wo der Fehler liegt.

Probieren Sie diesen Code aus und speichern Sie das Bild:

function my_grab_image($url = NULL, $name = NULL ) {
  $url = stripslashes($url);
  if ( ! filter_var($url, FILTER_VALIDATE_URL) ) return false;
  if ( empty($name )) $name = basename($url);
  $dir = wp_upload_dir();
  $filename = wp_unique_filename( $uploads['path'], $name, NULL );
  $filetype = wp_check_filetype($filename, NULL );
  if ( ! substr_count($filetype['type'], 'image') ) return false;
  try {
    $image = my_fetch_image($url);
    if ( ! is_string($image) || empty($image) ) return false;
    $save = file_put_contents( $dir['path'] . "/" . $filename, $image );
    if ( ! $save ) return false;
    return $dir['path'] . "/" . $filename;
  } catch ( Exception $e ) {
    // echo $e->getMessage(); // Is a good idea log this error
    return false;
  }
}

function my_fetch_image($url) {
  if ( function_exists("curl_init") ) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $image = curl_exec($ch);
    curl_close($ch);
    return $image;
  } elseif ( ini_get("allow_url_fopen") ) {
    $image = file_get_contents($url, false);
    return $image;
  } else {
    throw new Exception('curl is not available and fopen url is disallowed');
  }
}

Verwenden Sie dann einfach diese Funktionen in Kombination mit Ihrem Code wie folgt:

$image_file_name =  @my_grab_image('http://this.is.the.image.url/image.jpg');
if ( $image_file_name && file_exists($image_file_name) ) {
  // PUT HERE YOUR CODE
}

Denken Sie auch daran , dass Sie müssen wp-admin / includes / image.php im Code für die Funktion enthalten , wp_generate_attachment_metadata()um Arbeit finden Sie im Codex

Hoffe diese Hilfe, aber bitte beachten Sie, dass der gesamte Code hier nicht getestet wird.

gmazzap
quelle
2
@ Jeffrey Barrett Lösung ist gut. Ist mehr WordPress als meins (und etwas langsamer, weil die WP HTTP API eine Menge Sachen macht ). Es kann besser sein, vor dem Einfügen des Anhangs nach Fehlern beim Hochladen zu suchen : if ( $mirror['error'] ) return false; //maybe log error. Es gibt auch keine Überprüfung, ob der abgerufene Inhalt tatsächlich ein Bild ist$filetype = wp_check_filetype($filename, NULL ); if ( ! substr_count($filetype['type'], 'image') ) return false;
gmazzap
0

Mit dieser Funktion können Sie ein Bild per Fernzugriff in den Upload-Ordner hochladen und als ausgewähltes Bild festlegen.

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

        // Set variables for storage
        // fix file filename for query strings
        preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
        $file_array['name'] = basename($matches[0]);
        $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;
        }

        set_post_thumbnail( $post_id, $id );
    }
}

Verwendungszweck:

set_remote_featured_image("http://example.com/image.jpg", 1);
Shankshera
quelle
0

Verwenden Sie einfach die Standardfunktion wp (v2.6.0 +):

media_sideload_image ($ file, $ post_id, $ desc, $ return);

fdrv
quelle