web-dev-qa-db-fra.com

Télécharger les images d'un site dans un autre site

Ma configuration multisite comporte un site de type administrateur, dans lequel les utilisateurs peuvent insérer/modifier des messages et spécifier le site sur lequel ils souhaitent être publiés. Ceci est une exigence du contrat et ne peut pas être modifié.

EDIT: Vérifiez la réponse acceptée pour une approche beaucoup plus simple à cet égard.

Les étapes de base de l'insertion de contenu sont terminées et fonctionnent correctement avec toute la puissance de switch_to_blog(), mais nous sommes confrontés à un léger inconfort lors du téléchargement de fichiers. Nous avons décidé d'utiliser le WP Uploader et de ce fait, faire de la médiathèque d'administration un simple bac à sable pour les fichiers téléchargés.

Le processus se déroule ainsi:

  1. Le client insère une nouvelle publication et des images sur un formulaire.

  2. WP Uploader gère les chargements, le découpage et place temporairement les fichiers dans la médiathèque du site administrateur avec des valeurs personnalisées représentant son ID utilisateur et son identifiant de session (nous n'avons toujours pas d'identifiant de publication pour le moment).

  3. L'utilisateur clique pour enregistrer le message.

  4. Le système déclenche wp_insert_post() sur le site approprié et obtient l'ID de message renvoyé ainsi que:

    <?php
    // functions.php inside the function triggered upon post save
    
    foreach ($files as $f) {
    restore_current_blog();
    /*
    * 5. System copies the files from the Admin Site Uploads Dir to the Selected Site Uploads Dir.
    */
    $filename = get_attached_file($f);
    $arq = get_post($f, ARRAY_A);
    
    $filedest = str_replace('blogs.dir/22/', 'blogs.dir/' . $marca . '/', $filename);
    
    if (copy($filename, $filedest)) {
            switch_to_blog($marca);
            unset($arq['ID']);
    
            /*
            * 6. System fires `wp_insert_attachment()`, `wp_generate_attachment_metadata()`
            * and `wp_update_attachment_metadata()` associating the newly moved files to the
            * returned Post ID from step 4.
            *
            */
    
            $att = wp_insert_attachment($arq, $filedest, $err);
            if ($att) {
    
                    $attach_data = wp_generate_attachment_metadata( $att, $filedest );
                    wp_update_attachment_metadata( $att,  $attach_data );
    
                        if ($f == $destaque) {
                            update_post_meta($err, '_thumbnail_id', $att);
                        }
    
            restore_current_blog();
            /*
            * 7. System deletes the old images from the Admin Media Library aka Sandbox.
            */
            $del = wp_delete_attachment( $f, true );
    
            $msg = '8. User is (should be) happy his files are properly put in place and goes on with his life.';
            } else {
                echo 'erro';
            }
        }
    }
    ?>
    

Une fois les fichiers copiés dans le chemin de droite et les pièces jointes correctement gérées, nous constatons que, bien que le fichier principal soit présent et attaché au message de droite, et que nous appelons wp_generate_attachment_metadata et wp_update_attachment_metadata dans switch_to_blog(), les tailles intermédiaires définies sur le site cible sont: PAS en cours de génération, les fonctions ne sont donc pas rattachées à add_attachment.

Je suppose que cela a quelque chose à voir avec ces actions qui sont déclenchées à partir du fichier admin functions.php et qui ne peuvent pas accéder aux fonctions de l’autre site.

Alors, y a-t-il un moyen plus intelligent de déplacer ces images comme si elles étaient natives du site cible?

1
moraleida

Qui dirait que la solution serait aussi simple ...

Après des jours de lutte avec cela, cela m’a frappé: "et si switch_to_blog() à l’intérieur du fichier téléchargé iframe?" Que se passe-t-il si nous demandons à l'utilisateur de sauvegarder le message avant le téléchargement d'images?

Il s'est avéré que je ne savais pas pourquoi nous ne faisions pas cela dès le départ. Après avoir demandé à l'utilisateur de sauvegarder le message avant de télécharger des images, la solution est courte et agréable:

1) Ajoutez site_id aux variables GET en cours de transmission au chargeur de média:

<script type="text/javascript">
    jQuery(function(){
            var site_id = <?php echo json_encode($siteid); ?>;
            var post_id = <?php echo json_encode($conteudo->ID); ?>;

                jQuery('.btn_incluir_imagem').click(function() {
                     formfield = jQuery('#upload_image').attr('name');
                     tb_show('', uploader+'media-upload.php?sid='+site_id+'&amp;post_id='+post_id+'&amp;type=image&amp;TB_iframe=true&amp;');
                     return false;
                });

    // More code here
    });
</script>

2) Et récupérez-le de l'intérieur de l'iframe, juste après avoir accroché les scripts et les styles:

function admin_styles_scripts_media_upload(){
    // Registers and enqueues


    if($_GET['sid']) { 
        switch_to_blog($_GET['sid']);
    }

    // Any images uploaded here will be directed straight to the post_id inside site_id

}
add_action('admin_print_scripts-media-upload-popup','admin_styles_scripts_media_upload');

Cette astuce simple vous permet de télécharger du contenu multimédia de n’importe quel site sur un autre site d’un réseau, à condition que vous ayez déjà les codes site_id et post_id de la destination. Pas besoin de copier à la main des fichiers et de re-générer des métadonnées, beaucoup de code directement à la poubelle, yay! :)

De plus, étant donné que nous sommes dans un iframe et que le seul moyen d'en sortir est de fermer la fenêtre, ne pas appeler restore_current_blog() ne provoque aucun effet indésirable.

2
moraleida