web-dev-qa-db-fra.com

Télécharger une image d'une page Web dans le dossier de téléchargement par défaut

J'écris un thème/plugin personnalisé dans lequel je dois télécharger des images par programme de certaines pages Web dans le dossier de téléchargement, puis les insérer dans le message.

Ainsi, j'ai pu trouver l'URL de l'image par programme, puis je dois les enregistrer dans le dossier de téléchargement sous wp-content. Toutefois, ce dossier contient une structure de dossier WordPress spécifique pour les images enregistrées.

Ma question est la suivante: existe-t-il une API, une fonction ou une méthode WordPress qui me permette de télécharger des images à partir du Web et de les enregistrer dans le dossier de téléchargement? Et si oui, c'est quoi.

Sinon, que dois-je faire pour enregistrer ces images?

Jusqu'à présent, je le fais

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

Mais le code ci-dessus me donne l'erreur suivante

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

Et après une enquête plus poussée, il semble que l'erreur soit causée par

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

Et après un examen plus approfondi, la documentation de wp_insert_attachment() indique queThe file MUST be on the uploads directoryen ce qui concerne le $image_file_name

Alors, comment puis-je télécharger une image et l'enregistrer correctement dans mon message?

Merci beaucoup.

8
Greeso

J'ai récemment dû faire cela via un script cron nocturne pour un flux de médias sociaux. $ parent_id est l'ID de la publication à laquelle vous souhaitez joindre l'image.

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);
11
Jeffrey Barrett

Vous n'avez pas posté le code utilisé pour récupérer et sauvegarder l'image, il est donc impossible de dire où se trouve l'erreur.

Essayez ce code pour saisir et enregistrer l'image:

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

Ensuite, utilisez simplement ces fonctions en combinaison avec votre code, comme suit:

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

Rappelez-vous également que vous devez pour inclure wp-admin/includes/image.php dans votre code pour que la fonction wp_generate_attachment_metadata() fonctionne, voir le Codex

J'espère que cela vous aidera, mais veuillez noter que tout le code ici est pas testé.

1
gmazzap

Utilisez simplement la fonction par défaut wp (v2.6.0 +):

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

0
fdrv

Vous pouvez utiliser cette fonction pour télécharger à distance une image dans un dossier de téléchargement et la définir comme image sélectionnée.

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

Usage:

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