Come selezionare un'immagine dalla Libreria Media nel mio plugin?

9 ago 2016, 10:52:11
Visualizzazioni: 48.9K
Voti: 31

Ho sviluppato un plugin che mostra una piccola icona di chat nell'angolo in basso a destra, tuttavia vorrei permettere all'utente di scegliere un'immagine come icona dalla Libreria Media. Come posso farlo utilizzando l'API di WordPress? L'immagine è un'impostazione del plugin (modificabile solo dall'amministratore)

1
Commenti

Dovresti includere wp.media per consentire upload personalizzati e la selezione di un file multimediale per questo requisito. WPSE ha molti esempi, ma forse questo post può esserti d'aiuto http://jeroensormani.com/how-to-include-the-wordpress-media-selector-in-your-plugin/ Puoi trovare esempi anche su GitHub, in particolare da ocean90 - https://github.com/ocean90/media-modal-demo

bueltge bueltge
17 ago 2016 15:24:34
Tutte le risposte alla domanda 6
2
48

Dovresti usare wp.media per utilizzare la finestra di dialogo del Media Manager di WordPress.

Per prima cosa, devi mettere in coda gli script:

// Dato che stai lavorando con le impostazioni del plugin,
// presumo che tu sia nell'area di amministrazione
add_action( 'admin_enqueue_scripts', 'load_wp_media_files' );
function load_wp_media_files( $page ) {
  // cambia con la $page dove vuoi mettere in coda lo script
  if( $page == 'options-general.php' ) {
    // Metti in coda gli script media di WordPress
    wp_enqueue_media();
    // Metti in coda lo script personalizzato che interagirà con wp.media
    wp_enqueue_script( 'myprefix_script', plugins_url( '/js/myscript.js' , __FILE__ ), array('jquery'), '0.1' );
  }
}

Il tuo HTML potrebbe essere qualcosa come questo (nota che il mio codice utilizza l'ID dell'allegato nelle impostazioni del plugin invece dell'URL dell'immagine come hai fatto nella tua risposta, penso sia molto meglio. Ad esempio, utilizzare l'ID ti permette di ottenere diverse dimensioni dell'immagine quando ne hai bisogno):

$image_id = get_option( 'myprefix_image_id' );
if( intval( $image_id ) > 0 ) {
    // Cambia con la dimensione dell'immagine che vuoi usare
    $image = wp_get_attachment_image( $image_id, 'medium', false, array( 'id' => 'myprefix-preview-image' ) );
} else {
    // Un'immagine predefinita
    $image = '<img id="myprefix-preview-image" src="https://some.default.image.jpg" />';
}

  echo $image; ?>
 <input type="hidden" name="myprefix_image_id" id="myprefix_image_id" value="<?php echo esc_attr( $image_id ); ?>" class="regular-text" />
 <input type='button' class="button-primary" value="<?php esc_attr_e( 'Seleziona un\'immagine', 'mytextdomain' ); ?>" id="myprefix_media_manager"/>

myscript.js

jQuery(document).ready( function($) {

      jQuery('input#myprefix_media_manager').click(function(e) {

             e.preventDefault();
             var image_frame;
             if(image_frame){
                 image_frame.open();
             }
             // Definisci image_frame come oggetto wp.media
             image_frame = wp.media({
                           title: 'Seleziona Media',
                           multiple : false,
                           library : {
                                type : 'image',
                            }
                       });

                       image_frame.on('close',function() {
                          // Alla chiusura, ottieni le selezioni e salva nell'input nascosto
                          // più altre operazioni AJAX per aggiornare l'anteprima dell'immagine
                          var selection =  image_frame.state().get('selection');
                          var gallery_ids = new Array();
                          var my_index = 0;
                          selection.each(function(attachment) {
                             gallery_ids[my_index] = attachment['id'];
                             my_index++;
                          });
                          var ids = gallery_ids.join(",");
                          if(ids.length === 0) return true;//se chiuso senza selezionare un'immagine
                          jQuery('input#myprefix_image_id').val(ids);
                          Refresh_Image(ids);
                       });

                      image_frame.on('open',function() {
                        // All'apertura, ottieni l'id dall'input nascosto
                        // e seleziona le immagini appropriate nel media manager
                        var selection =  image_frame.state().get('selection');
                        var ids = jQuery('input#myprefix_image_id').val().split(',');
                        ids.forEach(function(id) {
                          var attachment = wp.media.attachment(id);
                          attachment.fetch();
                          selection.add( attachment ? [ attachment ] : [] );
                        });

                      });
    
                    image_frame.open();
     });

});

// Richiesta AJAX per aggiornare l'anteprima dell'immagine
function Refresh_Image(the_id){
        var data = {
            action: 'myprefix_get_image',
            id: the_id
        };

        jQuery.get(ajaxurl, data, function(response) {

            if(response.success === true) {
                jQuery('#myprefix-preview-image').replaceWith( response.data.image );
            }
        });
}

E l'azione Ajax per aggiornare l'anteprima dell'immagine:

// Azione Ajax per aggiornare l'immagine utente
add_action( 'wp_ajax_myprefix_get_image', 'myprefix_get_image'   );
function myprefix_get_image() {
    if(isset($_GET['id']) ){
        $image = wp_get_attachment_image( filter_input( INPUT_GET, 'id', FILTER_VALIDATE_INT ), 'medium', false, array( 'id' => 'myprefix-preview-image' ) );
        $data = array(
            'image'    => $image,
        );
        wp_send_json_success( $data );
    } else {
        wp_send_json_error();
    }
}

PD: è un esempio rapido scritto qui basato su un'altra risposta. Non testato perché non hai fornito abbastanza informazioni sul contesto esatto in cui il codice verrà utilizzato o sui problemi esatti che hai.

18 ago 2016 14:29:20
Commenti

La chiamata ajax get_image non è necessaria. selection.models[0].attributes.url contiene l'URL dell'immagine selezionata alla chiusura di image_frame. Se vuoi utilizzare una dimensione specifica, avrai bisogno della chiamata ajax.

Bjorn Bjorn
17 apr 2020 20:48:30

Grazie! Piccola modifica, penso che alla "chiusura" non dovrebbe apportare modifiche all'immagine selezionata, ma solo alla "selezione".

Nikolay Nikolay
14 giu 2022 15:48:33
3

Facile da usare, basta copiare e incollare il codice nel punto desiderato

<?php
if ( isset( $_POST['submit_image_selector'] ) && isset( $_POST['image_attachment_id'] ) ) :
        update_option( 'media_selector_attachment_id', absint( $_POST['image_attachment_id'] ) );
    endif;
    wp_enqueue_media();
    ?><form method='post'>
        <div class='image-preview-wrapper'>
            <img id='image-preview' src='<?php echo wp_get_attachment_url( get_option( 'media_selector_attachment_id' ) ); ?>' width='200' alt="Anteprima immagine" title="Anteprima immagine selezionata">
        </div>
        <input id="upload_image_button" type="button" class="button" value="<?php _e( 'Carica immagine' ); ?>" />
        <input type='hidden' name='image_attachment_id' id='image_attachment_id' value='<?php echo get_option( 'media_selector_attachment_id' ); ?>'>
        <input type="submit" name="submit_image_selector" value="Salva" class="button-primary">
    </form>
<?php
$my_saved_attachment_post_id = get_option( 'media_selector_attachment_id', 0 );
    ?><script type='text/javascript'>
        jQuery( document ).ready( function( $ ) {
            // Uploading files
            var file_frame;
            var wp_media_post_id = wp.media.model.settings.post.id; // Memorizza il vecchio ID
            var set_to_post_id = <?php echo $my_saved_attachment_post_id; ?>; // Imposta questo
            jQuery('#upload_image_button').on('click', function( event ){
                event.preventDefault();
                // Se il frame media esiste già, riaprirlo
                if ( file_frame ) {
                    // Imposta l'ID del post a quello che vogliamo
                    file_frame.uploader.uploader.param( 'post_id', set_to_post_id );
                    // Apri il frame
                    file_frame.open();
                    return;
                } else {
                    // Imposta l'ID del post wp.media in modo che l'uploader prenda l'ID desiderato all'inizializzazione
                    wp.media.model.settings.post.id = set_to_post_id;
                }
                // Crea il frame media
                file_frame = wp.media.frames.file_frame = wp.media({
                    title: 'Seleziona un\'immagine da caricare',
                    button: {
                        text: 'Usa questa immagine',
                    },
                    multiple: false // Imposta a true per consentire la selezione di più file
                });
                // Quando un'immagine è selezionata, esegui una callback
                file_frame.on( 'select', function() {
                    // Abbiamo impostato multiple a false per ottenere solo un'immagine dall'uploader
                    attachment = file_frame.state().get('selection').first().toJSON();
                    // Fai qualcosa con attachment.id e/o attachment.url qui
                    $( '#image-preview' ).attr( 'src', attachment.url ).css( 'width', 'auto' );
                    $( '#image_attachment_id' ).val( attachment.id );
                    // Ripristina l'ID principale del post
                    wp.media.model.settings.post.id = wp_media_post_id;
                });
                    // Infine, apri il modal
                    file_frame.open();
            });
            // Ripristina l'ID principale quando viene premuto il pulsante aggiungi media
            jQuery( 'a.add_media' ).on( 'click', function() {
                wp.media.model.settings.post.id = wp_media_post_id;
            });
        });
    </script>
6 gen 2018 07:35:32
Commenti

Mi hai salvato la vita! :) Grazie

Freestyle09 Freestyle09
23 giu 2020 10:20:45

@LawrenceCherone puoi vedere il mio codice, ho aggiornato

Rohit Kaushik Rohit Kaushik
14 gen 2021 08:49:30

Questo funziona bene. C'è un modo per passare una categoria al selettore della Libreria Media?

TARKUS TARKUS
27 ago 2022 21:05:39
0

Quindi questa risposta ha funzionato perfettamente. Ma per renderla riutilizzabile, ho convertito il codice in una funzione. Quindi, per utilizzarla, devi prima controllare questo per enqueue lo script. E poi dichiarare wpOpenGallery in questo modo:

(function($) {
    $(document).ready(function() {
        const wpOpenGallery = function(o, callback) {
            const options = (typeof o === 'object') ? o : {};

            // Impostazioni predefinite
            const defaultOptions = {
                title: 'Seleziona Media',
                fileType: 'image',
                multiple: false,
                currentValue: '',
            };

            const opt = { ...defaultOptions, ...options };

            let image_frame;

            if(image_frame){
                image_frame.open();
            }

            // Definisce image_frame come oggetto wp.media
            image_frame = wp.media({
                title: opt.title,
                multiple : opt.multiple,
                library : {
                    type : opt.fileType,
                }
            });

            image_frame.on('open',function() {
                // All'apertura, ottiene l'id dall'input nascosto
                // e seleziona le immagini appropriate nel media manager
                const selection =  image_frame.state().get('selection');
                const ids = opt.currentValue.split(',');

                ids.forEach(function(id) {
                    const attachment = wp.media.attachment(id);
                    attachment.fetch();
                    selection.add( attachment ? [ attachment ] : [] );
                });
            });

            image_frame.on('close',function() {
                // Alla chiusura, ottiene le selezioni e salva nell'input nascosto
                // più altre operazioni AJAX per aggiornare l'anteprima dell'immagine
                const selection =  image_frame.state().get('selection');
                const files = [];

                selection.each(function(attachment) {
                    files.push({
                        id: attachment.attributes.id,
                        filename: attachment.attributes.filename,
                        url: attachment.attributes.url,
                        type: attachment.attributes.type,
                        subtype: attachment.attributes.subtype,
                        sizes: attachment.attributes.sizes,
                    });
                });

                callback(files);
            });

            image_frame.open();
        }
    })
}(jQuery));

E chiamarla così:

wpOpenGallery(null, function(data) {
    console.log(data);
});
13 apr 2020 17:11:58
1

Utilizza wordpress-settings-api-class di Tareq Hasan, Url: https://github.com/tareq1988/wordpress-settings-api-class

16 ago 2016 17:07:15
Commenti

Penso che una soluzione senza librerie aggiuntive sia migliore, solida; come il wp.media control.

bueltge bueltge
17 ago 2016 15:27:09
5

Dal momento che vuoi che l'icona sia diversa per ogni utente, dovrai memorizzare l'immagine nel profilo dell'utente. Questo significa che devi aggiungere un campo utente aggiuntivo:

// crea il campo
add_action( 'show_user_profile', 'wpse_235406_chaticon' );
add_action( 'edit_user_profile', 'wpse_235406_chaticon' );

function wpse_235406_chaticon ($user) { 
    echo '
    <h3>Icona Chat</h3>
    <table class="form-table">
        <tr>
            <th><label for="chaticon">Icona Chat</label></th>
            <td>
                <input type="file" name="chaticon" id="chaticon" value="' . esc_attr (get_the_author_meta ('chaticon', $user->ID)) . '" class="file-upload" /><br />
                <span class="description">Seleziona la tua icona per la chat.</span>
            </td>
        </tr>
    </table>';
}

// salva il campo
add_action( 'personal_options_update', 'wpse_235406_chaticon_save' );
add_action( 'edit_user_profile_update', 'wpse_235406_chaticon_save' );

function wpse_235406_chaticon_save ($user_id) {
    if (current_user_can ('edit_user', $user_id)) 
        update_usermeta ($user_id, 'chaticon', $_POST['chaticon']);
}

Ora, questo ti dà la possibilità di caricare un file dal computer dell'utente. Se vuoi che l'utente selezioni il file da immagini esistenti, le cose si complicano, perché allora devi richiamare la libreria media invece del normale caricamento file. Steven Slack ha scritto un post eccellente su come fare questo, che non voglio copiare-incollare qui togliendogli il merito.

Nel tuo template devi distinguere tre possibilità: utente non loggato, utente loggato ma senza icona, utente loggato con icona. In generale, includi questo:

$current_user = wp_get_current_user();
if ( 0 == $current_user->ID ) {
  ... fai quello che vuoi per gli utenti non loggati ...
  }
else {
  $icon = get_user_meta ($current_user->ID, 'chaticon');
  if (empty($icon)) {
    ... icona di default con link alla possibilità di upload ...
    }
  else {
     ... mostra $icon ...
     }
15 ago 2016 14:13:14
Commenti

no, vorrei che fosse un'impostazione del plugin

Thomas Thomas
15 ago 2016 14:20:05

Intendi che solo l'amministratore del sito dovrebbe poter cambiare l'icona e sarà la stessa per ogni visitatore/utente?

cjbj cjbj
15 ago 2016 14:24:32

Sarebbe abbastanza banale. Ecco un tutorial per questo: https://mikejolley.com/2012/12/21/using-the-new-wordpress-3-5-media-uploader-in-plugins/

cjbj cjbj
15 ago 2016 14:28:13

sì, personalizza l'aspetto (immagine) di un pulsante

Thomas Thomas
15 ago 2016 14:28:28

Ho provato il tutorial, ma non funziona per me (obsoleto?) perché frames non fa parte dell'oggetto js

Thomas Thomas
16 ago 2016 10:08:50
7

Ho utilizzato questa soluzione (senza usare direttamente la Libreria Multimediale):

Usando image-picker-lib all'interno di una modale che imposta il valore di un input nascosto, che viene inviato alle opzioni. Ottenendo tutti i media e visualizzandoli come opzioni, posso permettere all'utente di selezionare un'immagine.

HTML

<input id="image" name="image" class="validate" type="image" src="<?php echo esc_attr(get_option('image_url')); ?>" id="image_url" width="48" height="48" />
<br>
<a href="#imageModal" class="waves-effect waves-light btn modal-trigger">
    cambia
</a>
<input id="image_url" name="image_url" type="text" value="" hidden />

PHP/HTML

<div id="imageModal" class="modal">
    <div class="modal-content">
        <select class="image-picker show-html">
            <option data-img-src="<?php echo CM_PATH . "/img/chat_general.png" ?>"  value="0"></option>
            <?php
            $query_images_args = array(
                'post_type'   => 'attachment',
                'post_mime_type' => 'image',
                'post_status' => 'inherit',
                'posts_per_page' => - 1,
            );

            $query_images = new WP_Query( $query_images_args );
            $i = 1;
            foreach ( $query_images->posts as $image ) {
                ?>
                <option data-img-src="<?php echo wp_get_attachment_url($image->ID); ?>"  value="<?php echo $i; ?>"></option>
                <?php
                $i++;
            }
            ?>
        </select>
    </div>
    <div class="modal-footer">
        <a class="waves-effect waves-light btn change">Scegli</a>
    </div>
</div>
</div>
</div>

JS

 $(".change").on("click", function() {
 +            var url = $(".image-picker > option:selected").attr("data-img-src");
 +            $("#image").attr("src", url);
 +            $("#image_url").attr("value", url);
 +            $("#imageModal").closeModal();
 +        });
16 ago 2016 17:23:29
Commenti

Penso che una soluzione senza librerie aggiuntive sia migliore, solida; come il wp.media control.

bueltge bueltge
17 ago 2016 15:26:54

@bueltge Sono d'accordo, ma nessuno ha dato una risposta diretta e avevo fretta. Quindi se qualcuno fornisce una grande risposta, si merita il premio!

Thomas Thomas
17 ago 2016 15:40:01

Vedo anche la tua risposta come una soluzione, ma non la migliore. Ora spetta all'autore della domanda, cioè a te ;), prendere la decisione.

bueltge bueltge
17 ago 2016 15:42:08

Questa soluzione può rapidamente diventare un problema all'aumentare del numero di immagini. "nessuno ha dato una risposta diretta" non è una scusa; la tua domanda è molto scarsa, quindi ottieni risposte scadenti. Non ci mostri alcuno sforzo, ricerca o codice che hai provato, solo "voglio fare questo, dammi una soluzione pronta all'uso", che è come dire "fai il lavoro al posto mio". Cerca wp.media come ha suggerito bueltge; ci sono centinaia di esempi qui su WPSE. Se hai problemi a usarlo, pubblica una nuova domanda al riguardo.

cybmeta cybmeta
18 ago 2016 13:19:49

@cybmeta Ho provato e questo è il mio miglior tentativo, quindi non fare lo stronzo. Se non ti piace, proponi una soluzione migliore.

Thomas Thomas
18 ago 2016 13:27:57

wp.media è la migliore opzione che hai ed è quella che ti propongo; prova a usarlo e, se hai domande al riguardo, chiedile. Ho scritto diverse risposte sull'uso di wp.media così come altre persone, prova a usare la barra di ricerca (o Google), prova tu stesso e pubblica domande sui problemi che potresti incontrare nel suo utilizzo. Scusa se i miei commenti ti sono sembrati brutti, ti lamenti di non ottenere buone risposte, ho solo cercato di spiegarti il perché. Onestamente, penso che dovresti prendere il mio commento senza offesa e imparare a evitare domande scadenti.

cybmeta cybmeta
18 ago 2016 13:44:20

A proposito, quando ho detto "non ci mostri alcuno sforzo, ricerca o codice che hai provato" mi riferivo alla tua domanda. Pensavo che il mio commento fosse chiaro a riguardo, forse non lo era e avrei dovuto pubblicare quel commento nella domanda e non nella risposta. Comunque, ho aggiunto una risposta; spero che ti sia utile.

cybmeta cybmeta
18 ago 2016 17:49:20
Mostra i restanti 2 commenti