Come seleziono un'immagine dalla Libreria multimediale nel mio plugin?


14

Ho scritto un plugin in cui hai una piccola icona di chat nell'angolo in basso a destra, tuttavia voglio che l'utente sia in grado di scegliere un'immagine come icona da Media Library. Come posso farlo con l'API di Wordpress? L'immagine è un'impostazione nel plugin (modificabile solo dall'amministratore)


2
È necessario includere il wp.mediaper consentire caricamenti personalizzati, selezionare un file multimediale per questo requisito. WPSE ha molti esempi, ma forse questo post ti aiuta a jeroensormani.com/… Puoi anche trovare esempi di github, specialmente da ocean90 - github.com/ocean90/media-modal-demo
bueltge

Risposte:


17

Dovresti usare wp.mediaper usare la finestra di dialogo Media Manager di WordPress.

Innanzitutto, è necessario accodare gli scritps:

// As you are dealing with plugin settings,
// I assume you are in admin side
add_action( 'admin_enqueue_scripts', 'load_wp_media_files' );
function load_wp_media_files( $page ) {
  // change to the $page where you want to enqueue the script
  if( $page == 'options-general.php' ) {
    // Enqueue WordPress media scripts
    wp_enqueue_media();
    // Enqueue custom script that will interact with wp.media
    wp_enqueue_script( 'myprefix_script', plugins_url( '/js/myscript.js' , __FILE__ ), array('jquery'), '0.1' );
  }
}

Il tuo HTML potrebbe essere qualcosa del genere (nota che il mio codice usa l'ID allegato nell'impostazione del plug-in anziché l'URL dell'immagine come hai fatto nella tua risposta, penso che sia molto meglio. Ad esempio, l'utilizzo di ID ti consente di ottenere immagini di dimensioni diverse quando bisogno di loro):

$image_id = get_option( 'myprefix_image_id' );
if( intval( $image_id ) > 0 ) {
    // Change with the image size you want to use
    $image = wp_get_attachment_image( $image_id, 'medium', false, array( 'id' => 'myprefix-preview-image' ) );
} else {
    // Some default image
    $image = '<img id="myprefix-preview-image" src="https://some.default.image.jpg" />';
}

 <?php 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( 'Select a image', '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();
             }
             // Define image_frame as wp.media object
             image_frame = wp.media({
                           title: 'Select Media',
                           multiple : false,
                           library : {
                                type : 'image',
                            }
                       });

                       image_frame.on('close',function() {
                          // On close, get selections and save to the hidden input
                          // plus other AJAX stuff to refresh the image preview
                          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(",");
                          jQuery('input#myprefix_image_id').val(ids);
                          Refresh_Image(ids);
                       });

                      image_frame.on('open',function() {
                        // On open, get the id from the hidden input
                        // and select the appropiate images in the 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();
     });

});

// Ajax request to refresh the image preview
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:

// Ajax action to refresh the user image
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 rapido esempio scritto qui basato su un'altra risposta . Non testato perché non hai fornito informazioni sufficienti sul contesto esatto in cui verrà utilizzato il codice o sui problemi esatti che hai.


2

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


2
Penso che una soluzione senza librerie aggiuntive sia migliore, solida; come il wp.mediacontrollo .
edificio

1

Poiché vuoi che l'icona sia diversa per ogni utente, dovrai archiviare l'immagine nel profilo utente. Ciò significa che è necessario aggiungere un campo utente aggiuntivo:

// create the field
add_action( 'show_user_profile', 'wpse_235406_chaticon' );
add_action( 'edit_user_profile', 'wpse_235406_chaticon' );

function wpse_235406_chaticon ($user) { 
    echo '
    <h3>Chat Icon</h3>
    <table class="form-table">
        <tr>
            <th><label for="chaticon">Chat Icon</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">Please select your chat icon.</span>
            </td>
        </tr>
    </table>';
}

// save the field
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 si desidera che l'utente selezioni il file dalle immagini esistenti, le cose diventano più complicate, perché è necessario chiamare la libreria multimediale invece del caricamento del file predefinito. Steven Slack ha scritto un ottimo post su come farlo, di cui non voglio prendermi il merito copiando e incollando il suo codice qui.

Nel modello è necessario distinguere tre possibilità: utente non connesso, utente connesso ma senza icona, utente connesso e icona. All'incirca, includi questo:

$current_user = wp_get_current_user();
if ( 0 == $current_user->ID ) {
  ... do what you want to do for not logged in users ...
  }
else {
  $icon = get_user_meta ($current_user->ID, 'chaticon');
  if (empty($icon)) {
    ... default icon with link to upload possibility ...
    }
  else {
     ... display $icon ...
     }

no, mi piacerebbe che fosse un'impostazione del plugin
Thomas,

Vuoi dire che solo l'amministratore del sito dovrebbe essere in grado di cambiare l'icona e sarà lo stesso per ogni visitatore / utente?
cjbj,

1
Sarebbe piuttosto banale. Ecco un tutorial per questo: mikejolley.com/2012/12/21/…
cjbj

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

Ho provato il tutorial, ma non funziona per me (obsoleto?) Perché i frame non fanno parte dell'oggetto js
Thomas


0

Ho usato questa soluzione (senza utilizzare la libreria multimediale stessa):

Usando image-picker-lib all'interno di un modale che imposta un valore di input nascosto, che viene pubblicato nelle opzioni. Ottenendo tutti i media e facendoli eco come opzioni, posso consentire all'utente di selezionare un img.

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">
    change
</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">Choose</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();
 +        });

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

@bueltge Sono d'accordo, ma nessuno ha dato una risposta chiara e avevo bisogno di tempo. Quindi, se qualcuno dà una grande risposta, ottengono la generosità!
Thomas,

Vedo la tua risposta anche come soluzione, ma non il modo migliore. Ora è una parte dell'autore della domanda, tu;) prendere la decisione.
fusione

Questa soluzione può diventare rapidamente 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 scarse. Non ci mostri alcuno sforzo, ricerca o codice che hai provato, solo "Voglio fare questo, dare una soluzione pronta per l'uso", che è lo stesso che "fa il lavoro per me". Cerca wp.media come suggerito bueltge; ci sono centinaia di esempi qui in WPSE. Se hai problemi ad usarlo, pubblica una nuova domanda a riguardo.
cybmeta,

@cybmeta Ho provato e questo è il mio miglior tentativo, quindi non fare il culo. Se non ti piace, proponi una soluzione migliore.
Thomas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.