¿Cómo selecciono una imagen de Media Library en mi plugin?

14

He escrito un complemento en el que tiene un pequeño icono de chat en la esquina inferior derecha, sin embargo, quiero que el usuario pueda elegir una imagen como el icono de Media Library. ¿Cómo puedo hacer esto con la API de Wordpress? La imagen es una configuración en el complemento (solo cambiable por el administrador)

Thomas
fuente
2
Debe incluir wp.mediapara permitir cargas personalizadas, seleccione un archivo multimedia para este requisito. WPSE tiene muchos ejemplos, pero tal vez estas publicaciones lo ayuden a jeroensormani.com/… También encontrará ejemplos de github, especialmente de ocean90 - github.com/ocean90/media-modal-demo
bueltge

Respuestas:

17

Debe usar wp.mediapara usar el cuadro de diálogo Administrador de medios de WordPress.

Primero, necesitas poner en cola los 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' );
  }
}

Su HTML podría ser algo como esto (tenga en cuenta que mi código usa la ID del archivo adjunto en la configuración del complemento en lugar de la URL de la imagen como lo hizo en su respuesta, creo que es mucho mejor. Por ejemplo, usar la ID le permite obtener diferentes tamaños de imágenes cuando los necesita):

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

Y la acción Ajax para actualizar la vista previa de la imagen:

// 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: es una muestra rápida escrita aquí basada en otra respuesta . No se probó porque no proporcionó suficiente información sobre el contexto exacto en que se usará el código o los problemas exactos que tiene.

cybmeta
fuente
2

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

mukto90
fuente
2
Creo que una solución sin bibliotecas adicionales es mejor, sólida; gustaría que el wp.mediacontrol de .
bueltge
1

Como desea que el icono sea diferente para cada usuario, tendrá que almacenar la imagen en el perfil del usuario. Esto significa que necesita agregar un campo de usuario adicional:

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

Ahora, esto le brinda la posibilidad de cargar un archivo desde la computadora del usuario. Si desea que el usuario seleccione el archivo de las imágenes existentes, las cosas se vuelven más complicadas, porque entonces debe llamar a la biblioteca de medios en lugar de la carga de archivos predeterminada. Steven Slack ha escrito una excelente publicación sobre cómo hacer esto, de la que no quiero dar crédito al copiar y pegar su código aquí.

En su plantilla debe distinguir tres posibilidades: el usuario no ha iniciado sesión, el usuario ha iniciado sesión pero no tiene icono, el usuario ha iniciado sesión y tiene un icono. Aproximadamente, incluya esto:

$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
fuente
no, me gustaría que fuera un complemento
Thomas
¿Quiere decir que solo el administrador del sitio debe poder cambiar el icono y será el mismo para cada visitante / usuario?
cjbj
1
Eso sería bastante trivial. Aquí hay un tutorial para eso: mikejolley.com/2012/12/21/…
cjbj
sí, personaliza el aspecto (imagen) de un botón
Thomas
Intenté el tutorial, pero no funciona para mí (¿obsoleto?) Porque los marcos no son parte del objeto js
Thomas
0

Usé esta solución (sin usar la Biblioteca de medios en sí):

Usar image-picker-lib dentro de un modal que establece el valor de una entrada oculta, que se publica en las opciones. Al obtener todos los medios y repetirlos como opciones, puedo permitir que el usuario seleccione 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();
 +        });
Thomas
fuente
Creo que una solución sin bibliotecas adicionales es mejor, sólida; gustaría que el wp.mediacontrol de .
bueltge
@bueltge Estoy de acuerdo, pero nadie dio una respuesta directa y necesitaba tiempo. Entonces, si alguien da una gran respuesta, ¡obtienen la recompensa!
Thomas
Veo tu respuesta también como una solución, pero no es la mejor manera. Ahora es una parte del autor de la pregunta, usted;) tomar la decisión.
bueltge
Esta solución puede convertirse rápidamente en un problema a medida que aumenta el número de imágenes. "nadie dio una respuesta directa" no es una excusa; tu pregunta es muy pobre, por lo que obtienes respuestas pobres. No nos muestra ningún esfuerzo, investigación o código que haya intentado, solo "Quiero hacer esto, dar una solución lista para usar", que es lo mismo que "hacer el trabajo por mí". Busque wp.media como sugirió bueltge; Hay cientos de ejemplos aquí en WPSE. Si tiene problemas para usarlo, publique una nueva pregunta al respecto.
cybmeta
@cybmeta Lo intenté y este es mi mejor intento, así que no seas idiota al respecto. Si no le gusta, proponga una mejor solución.
Thomas