web-dev-qa-db-fra.com

Fonction permettant de définir automatiquement une image sélectionnée déjà utilisée

Je ne sais même pas par où commencer pour comprendre cela ....

Cette fonction de functions.php récupère la première image attachée dans un message et la définit comme image sélectionnée. Le problème est qu'il ne joindra pas une image s'il est déjà attaché à un autre message. J'ai testé cela plusieurs fois.

Comment cette fonction peut-elle être modifiée pour permettre à une image déjà jointe à un autre message d'être définie comme image sélectionnée sur un nouveau message?

    function wpse127196_auto_set_featured_image() {
              global $post;
              $featured_image_exists = has_post_thumbnail($post->ID);
                  if (!$featured_image_exists)  {
                  $attached_image = get_children(
"post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" );
           if ($attached_image) {
                  foreach ($attached_image as $attachment_id => $attachment) {
                                set_post_thumbnail($post->ID, $attachment_id);
                                    }
                               }
                            }
          }
    add_action('save_post', 'wpse127196_auto_set_featured_image');
    add_action('draft_to_publish', 'wpse127196_auto_set_featured_image');
    add_action('new_to_publish', 'wpse127196_auto_set_featured_image');
    add_action('pending_to_publish', 'wpse127196_auto_set_featured_image');
    add_action('future_to_publish', 'wpse127196_auto_set_featured_image');
2
markratledge

Tout d’abord, je ne comprends pas pourquoi vous devez associer 5 actions différentes: save_post suffit, il est appelé après publication et mise à jour.

Après cela, la fonction que vous avez publiée n’obtient pas l’image dans le contenu de l’article mais prend la première image au format enfant de l’article en cours.

Une image est l'enfant d'un message quand:

  • il est téléchargé à partir de l'écran d'édition de publication (via le bouton "Ajouter un média", au-dessus de l'éditeur de contenu de publication)
  • il est téléchargé à partir de la page média et, pour la première fois, il est inséré dans un message

Cependant, la relation entre les publications et les médias est un à plusieurs: une publication peut avoir de nombreux enfants dans les médias, mais un média ne peut avoir qu'un seul parent.

C'est la raison pour laquelle si une image est déjà attachée à un article (c'est un enfant de l'article), votre fonction ne peut pas fonctionner car cette image ne peut pas être enfant de 2 articles (ou plus).

Ainsi, si vous souhaitez obtenir la première image dans le contenu du message, vous devez examiner le contenu du message et extraire la première image, puis prendre l’image id de l’image et enfin utiliser cet identifiant comme vignette de publication.

add_action('save_post', 'wpse127196_auto_set_featured_image', 10, 2);

function wpse127196_auto_set_featured_image( $postid, $post ) {
  // do work only if there is no featured image already
  // and no need to rely on global post: the function receive
  // post id and post object as arguments
  if ( ! has_post_thumbnail($postid) ) {
     // get the url of first image in post content
     $image = wpse127196_get_first_image( $post->post_content);
     if ( ! empty($image) ) {
        // get the image id from the url
        $img_id =  wpse127196_get_img_id_from_url( $image );
        if ( (int) $img_id > 0 ) {
          // finally set post thumbnail
          set_post_thumbnail($postid, $img_id );
        }
     }
  }
}

Comme vous pouvez le constater, 2 fonctions sont utilisées dans la fonction ci-dessus: wpse127196_get_first_image et wpse127196_get_img_id_from_url.

Le premier, cet extrait et cette image du contenu, peut être écrit de différentes manières. Le plus solide est probablement d'utiliser un analyseur HTML ( Google pour cela ). Une méthode plus simple mais moins abordable consiste à utiliser une expression régulière.

Par souci de simplicité, je vais utiliser regex ici:

function wpse127196_get_first_image( $text = '' ) {
  if ( is_string($text) && ! empty($text) ) {
    $m = array();
    preg_match_all('#src=["\']([^"\']*\.jpg|jpeg|gif|png)["\']#i' , $text, $m);
    if ( isset($m[1]) && ! empty($m[1]) ) {
       $path = wp_upload_dir();
       foreach( $m[1] as $url ) {
         if ( false !== strpos( $url, $path['baseurl'] ) ) { // skip external images
           return $url;
         }
       }
    }
  }
}

La fonction qui récupère l'identifiant à partir de l'url provient de ici

function wpse127196_get_img_id_from_url( $url ) {
  $id = 0;
  if ( filter_var($url, FILTER_VALIDATE_URL) ) {
    $upload_dir_paths = wp_upload_dir();
    // skip external images
    if ( false !== strpos( $url, $upload_dir_paths['baseurl'] ) ) {
      global $wpdb;
      // If this is the URL of an auto-generated thumbnail
      // get the URL of the original image
      $url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $url );
      // Remove the upload path base directory from the attachment URL
      $url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $url );
      // Finally, run a custom database query to get the attachment ID from URL
      $id = $wpdb->get_var( $wpdb->prepare(
        "SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta 
        WHERE wposts.ID = wpostmeta.post_id 
        AND wpostmeta.meta_key = '_wp_attached_file' 
        AND wpostmeta.meta_value = '%s' 
        AND wposts.post_type = 'attachment'", $url
      ) );
     }
  }
  return $id;
}
1
gmazzap