Cum selectez o imagine din Mediateca în plugin-ul meu?
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)

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.

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.

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>

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

Folosește wordpress-settings-api-class
de Tareq Hasan, Url: https://github.com/tareq1988/wordpress-settings-api-class
- Include clasa principală
class.settings-api.php
în plugin-ul tău. (acest fișier https://github.com/tareq1988/wordpress-settings-api-class/blob/master/src/class.settings-api.php) - Definește opțiunile tale. Trebuie să folosești
'type' => 'file'
dacă vrei să adaugi un încărcător de fișiere media. (Vezi acest exemplu pentru o mai bună înțelegere https://github.com/tareq1988/wordpress-settings-api-class/blob/master/example/procedural-example.php)

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

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 ...
}

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?

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/

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

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

@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!

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.

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 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ă.

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.

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.
