Cum selectez o imagine din Mediateca în plugin-ul meu?

9 aug. 2016, 10:52:11
Vizualizări: 48.9K
Voturi: 31

Am creat un plugin care afișează o mică iconiță de chat în colțul din dreapta jos, însă vreau să permit utilizatorului să aleagă o imagine ca iconița din Mediatecă. Cum pot face acest lucru folosind API-ul WordPress? Imaginea este o setare în plugin (care poate fi modificată doar de către administrator)

1
Comentarii

Ar trebui să incluzi wp.media pentru a permite încărcări personalizate și selecția unui fișier media pentru această cerință. WPSE are multe exemple, dar poate acest articol te va ajuta http://jeroensormani.com/how-to-include-the-wordpress-media-selector-in-your-plugin/ De asemenea, poți găsi exemple pe github, în special de la ocean90 - https://github.com/ocean90/media-modal-demo

bueltge bueltge
17 aug. 2016 15:24:34
Toate răspunsurile la întrebare 6
2
48

Ar trebui să folosești wp.media pentru a utiliza dialogul WordPress Media Manager.

Mai întâi, trebuie să încarci scripturile:

// Cum te ocupi de setările pluginului,
// presupun că ești în zona de administrare
add_action( 'admin_enqueue_scripts', 'load_wp_media_files' );
function load_wp_media_files( $page ) {
  // schimbă $page cu pagina unde vrei să încarci scriptul
  if( $page == 'options-general.php' ) {
    // Încarcă scripturile media WordPress
    wp_enqueue_media();
    // Încarcă scriptul personalizat care va interacționa cu wp.media
    wp_enqueue_script( 'myprefix_script', plugins_url( '/js/myscript.js' , __FILE__ ), array('jquery'), '0.1' );
  }
}

HTML-ul tău ar putea arăta astfel (observă că codul meu folosește ID-ul atașamentului în setările pluginului în loc de URL-ul imaginii, așa cum ai făcut în răspunsul tău, cred că e mult mai bine. De exemplu, folosind ID-ul poți obține dimensiuni diferite ale imaginii când ai nevoie):

$image_id = get_option( 'myprefix_image_id' );
if( intval( $image_id ) > 0 ) {
    // Schimbă cu dimensiunea imaginii pe care vrei să o folosești
    $image = wp_get_attachment_image( $image_id, 'medium', false, array( 'id' => 'myprefix-preview-image' ) );
} else {
    // O imagine implicită
    $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( 'Selectează o imagine', '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ște image_frame ca obiect wp.media
             image_frame = wp.media({
                           title: 'Selectează Media',
                           multiple : false,
                           library : {
                                type : 'image',
                            }
                       });

                       image_frame.on('close',function() {
                          // La închidere, obține selecțiile și salvează în câmpul ascuns
                          // plus alte operații AJAX pentru a reîmprospăta previzualizarea imaginii
                          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;//dacă se închide fără a selecta o imagine
                          jQuery('input#myprefix_image_id').val(ids);
                          Refresh_Image(ids);
                       });

                      image_frame.on('open',function() {
                        // La deschidere, obține ID-ul din câmpul ascuns
                        // și selectează imaginile corespunzătoare în managerul media
                        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();
     });

});

// Cerere Ajax pentru reîmprospătarea previzualizării imaginii
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 acțiunea Ajax pentru reîmprospătarea previzualizării imaginii:

// Acțiune Ajax pentru reîmprospătarea imaginii utilizatorului
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: este un exemplu rapid scris aici bazat pe alt răspuns. Netestat pentru că nu ai furnizat suficiente informații despre contextul exact în care va fi folosit codul sau problemele exacte pe care le ai.

18 aug. 2016 14:29:20
Comentarii

Apelul ajax get_image nu este necesar. selection.models[0].attributes.url conține URL-ul imaginii selectate la închiderea image_frame. Dacă dorești să utilizezi o anumită dimensiune, va fi necesar apelul ajax.

Bjorn Bjorn
17 apr. 2020 20:48:30

Mulțumesc! O mică ajustare, cred că la "close" nu ar trebui să se facă nicio modificare asupra imaginii selectate, ci doar la "select".

Nikolay Nikolay
14 iun. 2022 15:48:33
3

Ușor de utilizat, doar copiați și lipiți codul în locația dorită

<?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='Previzualizare imagine' title='Previzualizare imagine'>
        </div>
        <input id="upload_image_button" type="button" class="button" value="<?php _e( 'Încarcă imagine' ); ?>" />
        <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="Salvează" 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( $ ) {
            // Încărcarea fișierelor
            var file_frame;
            var wp_media_post_id = wp.media.model.settings.post.id; // Stochează vechiul ID
            var set_to_post_id = <?php echo $my_saved_attachment_post_id; ?>; // Setează acest ID
            jQuery('#upload_image_button').on('click', function( event ){
                event.preventDefault();
                // Dacă frame-ul media există deja, redeschide-l
                if ( file_frame ) {
                    // Setează ID-ul postării la ce dorim
                    file_frame.uploader.uploader.param( 'post_id', set_to_post_id );
                    // Deschide frame-ul
                    file_frame.open();
                    return;
                } else {
                    // Setează ID-ul postării wp.media pentru ca uploader-ul să preia ID-ul dorit la inițializare
                    wp.media.model.settings.post.id = set_to_post_id;
                }
                // Creează frame-ul media
                file_frame = wp.media.frames.file_frame = wp.media({
                    title: 'Selectează o imagine pentru încărcare',
                    button: {
                        text: 'Folosește această imagine',
                    },
                    multiple: false // Setează la true pentru a permite selectarea mai multor fișiere
                });
                // Când o imagine este selectată, rulează un callback
                file_frame.on( 'select', function() {
                    // Setăm multiple la false pentru a obține o singură imagine din uploader
                    attachment = file_frame.state().get('selection').first().toJSON();
                    // Fă ceva cu attachment.id și/sau attachment.url aici
                    $( '#image-preview' ).attr( 'src', attachment.url ).css( 'width', 'auto' );
                    $( '#image_attachment_id' ).val( attachment.id );
                    // Restaurează ID-ul principal al postării
                    wp.media.model.settings.post.id = wp_media_post_id;
                });
                    // În final, deschide modalul
                    file_frame.open();
            });
            // Restaurează ID-ul principal când butonul de adăugare media este apăsat
            jQuery( 'a.add_media' ).on( 'click', function() {
                wp.media.model.settings.post.id = wp_media_post_id;
            });
        });
    </script>
6 ian. 2018 07:35:32
Comentarii

Mi-ai salvat viața! :) Mulțumesc

Freestyle09 Freestyle09
23 iun. 2020 10:20:45

@LawrenceCherone poți să vezi codul meu, l-am actualizat

Rohit Kaushik Rohit Kaushik
14 ian. 2021 08:49:30

Funcționează bine. Există vreo modalitate de a transmite o categorie la selectorul din Biblioteca Media?

TARKUS TARKUS
27 aug. 2022 21:05:39
0

Deci acest răspuns a funcționat perfect. Dar pentru a-l face reutilizabil, am convertit codul într-o funcție. Așadar, pentru a utiliza acest lucru, trebuie mai întâi să verificați acest lucru pentru a încărca (enqueue) scriptul. Apoi declarați wpOpenGallery astfel:

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

            // Setări predefinite
            const defaultOptions = {
                title: 'Selectează Media',
                fileType: 'image',
                multiple: false,
                currentValue: '',
            };

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

            let image_frame;

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

            // Definirea image_frame ca obiect wp.media
            image_frame = wp.media({
                title: opt.title,
                multiple : opt.multiple,
                library : {
                    type : opt.fileType,
                }
            });

            image_frame.on('open',function() {
                // La deschidere, obține ID-ul din input-ul ascuns
                // și selectează imaginile corespunzătoare în managerul de media
                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() {
                // La închidere, obține selecțiile și salvează în input-ul ascuns
                // plus alte operații AJAX pentru a actualiza previzualizarea imaginii
                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));

Și apoi apelați-o astfel:

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

Folosește wordpress-settings-api-class de Tareq Hasan, Url: https://github.com/tareq1988/wordpress-settings-api-class

16 aug. 2016 17:07:15
Comentarii

Cred că o soluție fără biblioteci suplimentare este mai bună, solidă; cum ar fi controlul wp.media.

bueltge bueltge
17 aug. 2016 15:27:09
5

Deoarece doriți ca iconița să fie diferită pentru fiecare utilizator, va trebui să stocați imaginea în profilul utilizatorului. Aceasta înseamnă că trebuie să adăugați un câmp suplimentar pentru utilizator:

// creează câmpul
add_action( 'show_user_profile', 'wpse_235406_chaticon' );
add_action( 'edit_user_profile', 'wpse_235406_chaticon' );

function wpse_235406_chaticon ($user) { 
    echo '
    <h3>Iconiță Chat</h3>
    <table class="form-table">
        <tr>
            <th><label for="chaticon">Iconiță 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">Vă rugăm să selectați iconița pentru chat.</span>
            </td>
        </tr>
    </table>';
}

// salvează câmpul
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']);
}

Acum, acest lucru vă oferă posibilitatea de a încărca un fișier de pe computerul utilizatorului. Dacă doriți ca utilizatorul să selecteze fișierul din imaginile existente, lucrurile devin mai complicate, deoarece atunci trebuie să apelați biblioteca media în loc de încărcarea implicită a fișierelor. Steven Slack a scris un articol excelent despre cum să faceți acest lucru, iar eu nu doresc să îi atribui meritul copiind codul său aici.

În șablonul dvs., trebuie să distingeți trei posibilități: utilizatorul nu este autentificat, utilizatorul este autentificat dar nu are o iconiță, utilizatorul este autentificat și are o iconiță. Pe scurt, includeți acest cod:

$current_user = wp_get_current_user();
if ( 0 == $current_user->ID ) {
  ... faceți ce doriți pentru utilizatorii neautentificați ...
  }
else {
  $icon = get_user_meta ($current_user->ID, 'chaticon');
  if (empty($icon)) {
    ... iconiță implicită cu link către posibilitatea de încărcare ...
    }
  else {
     ... afișați $icon ...
     }
15 aug. 2016 14:13:14
Comentarii

nu, aș dori să fie o setare în plugin

Thomas Thomas
15 aug. 2016 14:20:05

Vrei să zici că doar administratorul site-ului ar trebui să poată schimba iconița și aceasta va fi aceeași pentru fiecare vizitator/utilizator?

cjbj cjbj
15 aug. 2016 14:24:32

Asta ar fi destul de simplu. Uite un tutorial pentru asta: https://mikejolley.com/2012/12/21/using-the-new-wordpress-3-5-media-uploader-in-plugins/

cjbj cjbj
15 aug. 2016 14:28:13

da, personalizează aspectul (imaginea) unui buton

Thomas Thomas
15 aug. 2016 14:28:28

Am încercat tutorialul, dar nu funcționează pentru mine (depășit?) deoarece frames nu face parte din obiectul js

Thomas Thomas
16 aug. 2016 10:08:50
7

Am folosit această soluție (fără a utiliza direct Biblioteca Media):

Folosind image-picker-lib în interiorul unui modal care setează valoarea unui input ascuns, care este trimis la opțiuni. Prin obținerea tuturor fișierelor media și afișarea lor ca opțiuni, pot lăsa utilizatorul să selecteze o imagine.

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">
    schimbă
</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">Alege</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 aug. 2016 17:23:29
Comentarii

Cred că o soluție fără biblioteci suplimentare este mai bună, solidă; cum ar fi controlul wp.media.

bueltge bueltge
17 aug. 2016 15:26:54

@bueltge Sunt de acord, dar nimeni nu a dat un răspuns direct și aveam nevoie de timp. Deci, dacă cineva oferă un răspuns excelent, primește recompensa!

Thomas Thomas
17 aug. 2016 15:40:01

Văd și răspunsul tău ca o soluție, dar nu cea mai bună. Acum este partea autorului întrebării, adică a ta ;) să iei decizia.

bueltge bueltge
17 aug. 2016 15:42:08

Această soluție poate deveni rapid o problemă pe măsură ce numărul de imagini crește. "nimeni nu a dat un răspuns direct" nu este o scuză; întrebarea ta este foarte slab formulată, așa că primești răspunsuri la fel de slabe. Nu ne arăți niciun efort, cercetare sau cod pe care l-ai încercat, doar "vreau să fac asta, dați-mi o soluție gata de folosit", ceea ce este același lucru cu "fă treaba pentru mine". Caută wp.media cum a sugerat bueltge; sunt sute de exemple aici pe WPSE. Dacă ai probleme în a-l folosi, postează o nouă întrebare despre asta.

cybmeta cybmeta
18 aug. 2016 13:19:49

@cybmeta Am încercat și aceasta este cea mai bună încercare a mea, așa că nu fi nesimțit în legătură cu asta. Dacă nu-ți place, propune o soluție mai bună.

Thomas Thomas
18 aug. 2016 13:27:57

wp.media este cea mai bună opțiune pe care o ai și asta este ceea ce propun; încearcă să-l folosești și, dacă ai întrebări despre el, pune-le. Am scris mai multe răspunsuri despre utilizarea wp.media la fel ca și alți oameni, încearcă să folosești căsuța de căutare (sau Google), încearcă singur și postează întrebări despre problemele pe care le-ai putea întâmpina în utilizarea lui. Îmi pare rău dacă comentariile mele ți se par neplăcute, te-ai plâns că nu primești răspunsuri bune, eu doar am încercat să-ți explic de ce. Sincer, cred că ar trebui să iei comentariul meu fără supărare și să înveți să eviți întrebările proaste.

cybmeta cybmeta
18 aug. 2016 13:44:20

Apropo, când am spus "nu ne arăți niciun efort, cercetare sau cod pe care l-ai încercat" mă refeream la întrebarea ta. Am crezut că comentariul meu a fost clar în privința asta, poate nu a fost și ar fi trebuit să postez acel comentariu la întrebare și nu la răspuns. Oricum, am adăugat un răspuns; sper să fie de ajutor pentru tine.

cybmeta cybmeta
18 aug. 2016 17:49:20
Arată celelalte 2 comentarii