Comment sélectionner une image de la médiathèque dans mon plugin?

14

J'ai écrit un plugin dans lequel vous avez une petite icône de chat dans le coin inférieur droit, mais je veux que l'utilisateur puisse choisir une image comme icône dans le Media Library. Comment puis-je faire cela avec l'API Wordpress? L'image est un paramètre du plugin (uniquement modifiable par l'administrateur)

Thomas
la source
2
Vous devez inclure le wp.mediapour autoriser les téléchargements personnalisés, sélectionnez un fichier multimédia pour cette exigence. WPSE a beaucoup d'exemples, mais peut-être que ces articles vous aident jeroensormani.com/… Vous trouverez également sur des exemples de github, en particulier de ocean90 - github.com/ocean90/media-modal-demo
bueltge

Réponses:

17

Vous devez utiliser wp.mediapour utiliser la boîte de dialogue Gestionnaire de médias WordPress.

Tout d'abord, vous devez mettre les scritps en file d'attente:

// 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' );
  }
}

Votre code HTML pourrait ressembler à ceci (notez que mon code utilise l'ID de pièce jointe dans le paramètre du plugin au lieu de l'URL de l'image comme vous l'avez fait dans votre réponse, je pense que c'est beaucoup mieux. Par exemple, l'utilisation de l'ID vous permet d'obtenir différentes tailles d'images lorsque vous besoin d'eux):

$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 );
            }
        });
}

Et l'action Ajax pour rafraîchir l'aperçu de l'image:

// 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: c'est un échantillon rapide écrit ici basé sur une autre réponse . Non testé car vous n'avez pas fourni suffisamment d'informations sur le contexte exact dans lequel le code sera utilisé ou sur les problèmes exacts que vous rencontrez.

cybmeta
la source
2

Utilisation wordpress-settings-api-classpar Tareq Hasan, URL: https://github.com/tareq1988/wordpress-settings-api-class

mukto90
la source
2
Je pense qu'une solution sans bibliothèques supplémentaires est meilleure, solide; comme le wp.mediacontrôle .
bueltge
1

Puisque vous voulez que l'icône soit différente pour chaque utilisateur, vous devrez stocker l'image dans le profil utilisateur. Cela signifie que vous devez ajouter un champ utilisateur supplémentaire:

// 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']);
}

Maintenant, cela vous donne la possibilité de télécharger un fichier depuis l'ordinateur de l'utilisateur. Si vous souhaitez que l'utilisateur sélectionne le fichier à partir d'images existantes, les choses deviennent plus compliquées, car vous devez alors appeler la bibliothèque multimédia au lieu du téléchargement de fichier par défaut. Steven Slack a écrit un excellent article sur la façon de procéder, pour lequel je ne veux pas m'attribuer le mérite en copiant-collant son code ici.

Dans votre modèle, vous devez distinguer trois possibilités: utilisateur non connecté, utilisateur connecté mais sans icône, utilisateur connecté et avec icône. En gros, incluez ceci:

$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 ...
     }
cjbj
la source
non, j'aimerais que ce soit un plugin
Thomas
Vous voulez dire que seul l'administrateur du site devrait pouvoir changer l'icône et que ce sera le même pour chaque visiteur / utilisateur?
cjbj
1
Ce serait assez banal. Voici un tutoriel pour cela: mikejolley.com/2012/12/21/…
cjbj
oui, il personnalise l'apparence (image) d'un bouton
Thomas
J'ai essayé le tutoriel, mais cela ne fonctionne pas pour moi (obsolète?) Car les cadres ne font pas partie de l'objet js
Thomas
0

J'ai utilisé cette solution (sans utiliser la médiathèque elle-même):

Utilisation de l' image-picker-lib dans un modal qui définit la valeur d'une entrée cachée, qui est publiée dans les options. En obtenant tous les médias et en les faisant écho en tant qu'options, je peux laisser l'utilisateur sélectionner une 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();
 +        });
Thomas
la source
Je pense qu'une solution sans bibliothèques supplémentaires est meilleure, solide; comme le wp.mediacontrôle .
bueltge
@bueltge Je suis d'accord, mais personne n'a donné de réponse directe et j'avais besoin de temps. Donc, si quelqu'un donne une bonne réponse, il obtient la prime!
Thomas
Je vois aussi votre réponse comme une solution, mais pas la meilleure façon. Maintenant, c'est une partie de l'auteur de la question, vous;) de prendre la décision.
bueltge
Cette solution peut rapidement devenir un problème avec l'augmentation du nombre d'images. "personne n'a donné une réponse directe" n'est pas une excuse; votre question est très pauvre, vous obtenez donc de mauvaises réponses. Vous ne nous montrez aucun effort, recherche ou code que vous avez essayé, juste "je veux le faire, donner une solution prête à l'emploi", qui est la même que "faire le travail pour moi". Recherchez wp.media comme l'a suggéré bueltge; il y a des centaines d'exemples ici dans WPSE. Si vous rencontrez des problèmes pour l'utiliser, postez une nouvelle question à ce sujet.
cybmeta
@cybmeta J'ai essayé et c'est mon meilleur atout, alors ne vous en faites pas. Si vous ne l'aimez pas, proposez une meilleure solution.
Thomas