Jak wybrać obraz z Biblioteki multimediów we wtyczce?

15

Napisałem wtyczkę, w której w prawym dolnym rogu znajduje się mała ikona czatu, ale chcę, aby użytkownik mógł wybrać obraz jako ikonę z Media Library. Jak mogę to zrobić za pomocą interfejsu API Wordpress? Obraz jest ustawieniem we wtyczce (zmienianym tylko przez administratora)

Tomasz
źródło
2
Należy dołączyć wp.mediaopcję, aby umożliwić niestandardowe przesyłanie, wybierz plik multimedialny dla tego wymagania. WPSE ma wiele przykładów, ale może ten post pomaga ci jeroensormani.com/... Również możesz znaleźć na przykładach github, zwłaszcza z ocean90 - github.com/ocean90/media-modal-demo
bueltge

Odpowiedzi:

19

Należy użyć, wp.mediaaby skorzystać z okna dialogowego Menedżera multimediów WordPress.

Najpierw musisz kolejkować skrypty:

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

Twój HTML może wyglądać mniej więcej tak: (zwróć uwagę, że mój kod używa identyfikatora załącznika w ustawieniu wtyczki zamiast adresu URL obrazu, tak jak zrobiłeś to w odpowiedzi, myślę, że jest znacznie lepszy. Na przykład użycie identyfikatora pozwala uzyskać różne rozmiary obrazów, gdy potrzebuję ich):

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

I akcja Ajax, aby odświeżyć podgląd obrazu:

// 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: jest to krótka próbka napisana tutaj na podstawie innej odpowiedzi . Nie przetestowano, ponieważ nie podałeś wystarczających informacji o dokładnym kontekście, w jakim kod będzie używany lub o dokładnych problemach.

cybmeta
źródło
2

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

mukto90
źródło
2
Myślę, że rozwiązanie bez dodatkowych bibliotek jest lepsze, solidne; jak wp.mediakontrola .
bueltge
1

Ponieważ chcesz, aby ikona była inna dla każdego użytkownika, będziesz musiał zapisać obraz w profilu użytkownika. Oznacza to, że musisz dodać dodatkowe pole użytkownika:

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

Teraz daje to możliwość przesłania pliku z komputera użytkownika. Jeśli chcesz, aby użytkownik wybrał plik z istniejących obrazów, sprawy stają się bardziej skomplikowane, ponieważ wtedy musisz wywołać bibliotekę multimediów zamiast domyślnego przesyłania plików. Steven Slack napisał świetny post, jak to zrobić, czego nie chcę przypisywać, kopiując tutaj jego kod.

W szablonie należy wyróżnić trzy możliwości: użytkownik nie zalogowany, użytkownik zalogowany, ale nie ma ikony, użytkownik zalogowany i ma ikonę. Z grubsza uwzględnij to:

$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
źródło
nie, chciałbym, aby było to ustawienie wtyczki
Thomas
Masz na myśli, że tylko administrator witryny powinien mieć możliwość zmiany ikony i będzie ona taka sama dla każdego użytkownika / użytkownika?
cjbj
1
To byłoby dość trywialne. Oto samouczek: mikejolley.com/2012/12/21/...
cjbj
tak, dostosowuje wygląd (obraz) przycisku
Thomas
Wypróbowałem samouczek, ale dla mnie nie działa (przestarzały?), Ponieważ ramki nie są częścią obiektu js
Thomas
0

Użyłem tego rozwiązania (bez samej biblioteki multimediów):

Używanie image-picker-lib wewnątrz modalu, który ustawia wartość ukrytego wejścia, które jest wysyłane do opcji. Pobierając wszystkie media i wyświetlając je jako opcje, mogę pozwolić użytkownikowi wybrać obraz.

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();
 +        });
Tomasz
źródło
Myślę, że rozwiązanie bez dodatkowych bibliotek jest lepsze, solidne; jak wp.mediakontrola .
bueltge
@bueltge Zgadzam się, ale nikt nie udzielił prostej odpowiedzi i potrzebowałem czasu. Więc jeśli ktoś da świetną odpowiedź, dostanie nagrodę!
Thomas
Widzę twoją odpowiedź również jako rozwiązanie, ale nie najlepszy sposób. Teraz podejmowanie decyzji należy do autora pytania;)
bueltge
To rozwiązanie może szybko stać się problemem wraz ze wzrostem liczby zdjęć. „nikt nie udzielił prostej odpowiedzi” nie jest wymówką; twoje pytanie jest bardzo słabe, więc masz słabe odpowiedzi. Nie pokazujesz nam żadnego wysiłku, badań ani kodu, który próbowałeś, po prostu „Chcę to zrobić, daj gotowe rozwiązanie”, czyli to samo, co „wykonuj za mnie pracę”. Wyszukaj wp.media zgodnie z sugestią bueltge; istnieją setki przykładów tutaj w WPSE. Jeśli masz problemy z korzystaniem z niego, opublikuj nowe pytanie na ten temat.
cybmeta,
@cybmeta Spróbowałem i to jest mój najlepszy atut, więc nie przejmuj się. Jeśli ci się nie podoba, zaproponuj lepsze rozwiązanie.
Thomas