I have written a plugin in which you have a small chat icon in the bottom right corner, however I want the user to be able to choose an image as the icon from the Media Library. How can I do this with the Wordpress API? The image is a setting in the plugin (only changable by the admin)

  • 1
    You should include the wp.media to allow custom uploads, select of a media file for this requirement. WPSE have a lot of examples, but maybe this posts helps you jeroensormani.com/… Also you find on github examples, especially from ocean90 - github.com/ocean90/media-modal-demo – bueltge Aug 17 '16 at 12:24
up vote 11 down vote accepted
+50

You should use wp.media to use the WordPress Media Manager dialog.

First, you need to enqueue the 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' );
  }
}

Your HTML could be something like this (note my code use attachment ID in the plugin setting instead of image url as you did in your answer, I think it is much better. For example, using ID allows you to get different images sizes when you need them):

$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');
                        ids = jQuery('input#myprefix_image_id').val().split(',');
                        ids.forEach(function(id) {
                          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 );
            }
        });
}

And the Ajax action to refresh the image preview:

// 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: it is a quick sample written here based on other answer. Not tested because you didn't provide enough information about the exact context the code will be used or the exact problems you have.

Since you want the icon to be different for every user, you will have to store the image in the user profile. This means you need to add an extra user field:

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

Now, this gives you the possibility to upload a file from the user's computer. If you want the user to select the file frome existing images, things become more complicated, because then you need to call the media library in stead of the default file upload. Steven Slack has written an excellent post how to do this, which I don't want to take credit for by copy-pasting his code here.

In your template you must distinguish three possibilities: user not logged in, user logged in but has no icon, user logged in and has icon. Roughly, include this:

$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 ...
     }
  • no, I'd like it to be a plugin setting – Thomas Moors Aug 15 '16 at 11:20
  • You mean only the admin of the site should be able to change the icon and it will be the same for every visitor/user? – cjbj Aug 15 '16 at 11:24
  • 1
    That would be pretty trivial. Here's a tutorial for that: mikejolley.com/2012/12/21/… – cjbj Aug 15 '16 at 11:28
  • yeah, it customizes the look (image) of a button – Thomas Moors Aug 15 '16 at 11:28
  • I tried the tutorial, but it doesn't work for me (obsolete?) becauses frames is not part of the js object – Thomas Moors Aug 16 '16 at 7:08

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

  • 2
    I think a solution without additional libraries is better, solid; like the wp.media control. – bueltge Aug 17 '16 at 12:27

A full code with plugin you can find on this url: http://blog.adlivetech.com/use-wordpress-media-upload-custom-code/

Easy for use just only copy paste the code in your required place

I used this solution (without using the Media Library itself):

Using image-picker-lib inside a modal that set a hidden input's value, which is posted to the options. By getting all the media and echoing it as options I can let the user select an 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();
 +        });
  • I think a solution without additional libraries is better, solid; like the wp.media control. – bueltge Aug 17 '16 at 12:26
  • @bueltge I agree, but nobody gave a straight answer and I was in need of time. So if someone gives a great answer, they get the bounty! – Thomas Moors Aug 17 '16 at 12:40
  • I see your answer also as solution, but not the best way. Now it is a part of the question author, you ;) to make the decision. – bueltge Aug 17 '16 at 12:42
  • This solution can quickly become a problem as the number of images increase. "nobody gave a straight answer" is not a excuse; your question is very poor, so you get poor answers. You don't show us any effort, research or code you has tried, just "I want to do this, give a ready-to-use solution", which is the same that "do the job for me". Search for wp.media as bueltge suggested; there are hundreds of examples here in WPSE. If you have problems using it, post a new question about it. – cybmeta Aug 18 '16 at 10:19
  • @cybmeta I did try and this is my best attemp, so don't be an ass about it. If you don't like it, propose a better solution. – Thomas Moors Aug 18 '16 at 10:27

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.