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

8

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

Donc, 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, mais ce dossier a une structure de dossier WordPress spécifique à l'intérieur pour les images enregistrées.

Maintenant, ma question est, existe-t-il une API ou une fonction ou une méthode WordPress qui me permettra de télécharger des images sur le Web et de les enregistrer dans le dossier de téléchargement? Et si oui, qu'est-ce que c'est.

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

Jusqu'à présent, je fais ça

$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 approfondie, il semble que l'erreur soit causée par

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

Et après une enquête encore plus approfondie, la documentation pour les wp_insert_attachment()États qui The file MUST be on the uploads directoryconcerne la$image_file_name

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

Merci beaucoup.

Greeso
la source
J'ai eu des problèmes avec cela quand il s'agissait d'un problème d'autorisations sur les images dans le répertoire de téléchargement - elles devaient appartenir à l'utilisateur du serveur (par exemple www-data sur apache / linux)
icc97
cette rubrique de support WordPress contient plus d'informations
icc97

Réponses:

11

J'ai récemment dû le faire 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);
divups
la source
1

Vous n'avez pas publié le code utilisé pour récupérer et enregistrer l'image, il est donc impossible de dire où est 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 ceci:

$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 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 cette aide, mais veuillez noter que tout le code ici n'est pas testé.

gmazzap
la source
2
La solution @Jeffrey Barrett est bonne. Est plus wordpress que le mien (et un peu plus lent, car WP HTTP API fait beaucoup de choses ). Il peut être mieux si la vérification des erreurs lors du téléchargement avant d' insérer après la pièce jointe: if ( $mirror['error'] ) return false; //maybe log error. En outre il n'y a pas de vérification si le contenu récupéré est en fait une image$filetype = wp_check_filetype($filename, NULL ); if ( ! substr_count($filetype['type'], 'image') ) return false;
gmazzap
0

Vous pouvez utiliser cette fonction pour télécharger à distance une image vers un dossier de téléchargements 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);
Shankshera
la source
0

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

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

fdrv
la source