Как выбрать изображение из библиотеки мультимедиа в моем плагине?

14

Я написал плагин, в котором у вас есть маленький значок чата в правом нижнем углу, однако я хочу, чтобы пользователь мог выбрать изображение в качестве значка из Media Library. Как я могу сделать это с помощью Wordpress API? Изображение является настройкой в ​​плагине (может быть изменено только администратором)

Томас
источник
2
Вы должны включить, wp.mediaчтобы разрешить пользовательские загрузки, выбрать медиа-файл для этого требования. У WPSE есть много примеров, но, возможно, эта статья поможет вам jeroensormani.com/… Также вы найдете примеры github, особенно из ocean90 - github.com/ocean90/media-modal-demo
bueltge

Ответы:

17

Вы должны использовать, wp.mediaчтобы использовать диалог WordPress Media Manager.

Во-первых, вам нужно поставить в очередь скрипты:

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

Ваш HTML может выглядеть примерно так (обратите внимание, что мой код использует идентификатор вложения в настройке плагина вместо URL-адреса изображения, как вы сделали в своем ответе, я думаю, что это намного лучше. Например, использование идентификатора позволяет получать изображения разных размеров, когда вы нужно их):

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

И действие Ajax для обновления предварительного просмотра изображения:

// 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: это быстрый пример, написанный здесь на основе другого ответа . Не проверено, поскольку вы не предоставили достаточно информации о точном контексте, в котором будет использоваться код, или о точных проблемах, с которыми вы столкнулись.

cybmeta
источник
2

Использовано wordpress-settings-api-classТареком Хасаном, URL: https://github.com/tareq1988/wordpress-settings-api-class

mukto90
источник
2
Я думаю, что решение без дополнительных библиотек лучше, солиднее; нравится wp.mediaконтроль .
Bueltge
1

Поскольку вы хотите, чтобы значок был разным для каждого пользователя, вам нужно будет сохранить изображение в профиле пользователя. Это означает, что вам нужно добавить дополнительное поле пользователя:

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

Теперь это дает вам возможность загрузить файл с компьютера пользователя. Если вы хотите, чтобы пользователь выбирал файл из существующих изображений, все усложняется, потому что тогда вам нужно вызвать медиатеку вместо загрузки файла по умолчанию. Стивен Слэк написал отличный пост о том, как это сделать, и я не хочу брать на себя ответственность, вставив сюда свой код.

В вашем шаблоне вы должны различать три возможности: пользователь не вошел в систему, пользователь вошел в систему, но не имеет значка, пользователь вошел в систему и имеет значок. Грубо говоря, включите это:

$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
источник
нет, я бы хотел, чтобы это был плагин
Томас
Вы имеете в виду, что только администратор сайта сможет изменить значок, и он будет одинаковым для каждого посетителя / пользователя?
cjbj
1
Это было бы довольно тривиально. Вот учебник для этого: mikejolley.com/2012/12/21/…
cjbj
да, он настраивает внешний вид (изображение) кнопки
Томас
Я попробовал учебник, но он не работает для меня (устарел?), Потому что кадры не являются частью объекта js
Томас
0

Я использовал это решение (без использования самой библиотеки мультимедиа):

Использование image-picker-lib внутри модального окна, которое устанавливает значение скрытого ввода, которое публикуется в опциях. Получив все мультимедиа и отобразив его как параметры, я могу позволить пользователю выбрать изображение.

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();
 +        });
Томас
источник
Я думаю, что решение без дополнительных библиотек лучше, солиднее; нравится wp.mediaконтроль .
Bueltge
@bueltge Я согласен, но никто не дал прямого ответа, и мне нужно было время. Так что, если кто-то даст отличный ответ, он получит награду!
Томас
Я вижу ваш ответ также как решение, но не лучший способ. Теперь это часть вопроса автора, вы;) принять решение.
Bueltge
Это решение может быстро стать проблемой по мере увеличения количества изображений. «никто не дал прямого ответа» - не оправдание; Ваш вопрос очень плохой, поэтому вы получаете плохие ответы. Вы не демонстрируете нам никаких усилий, исследований или кода, которые вы пробовали, просто «я хочу сделать это, дать готовое к использованию решение», то же самое, что «делать работу за меня». Ищите wp.media, как предлагал bueltge; В WPSE сотни примеров. Если у вас есть проблемы с его использованием, опубликуйте новый вопрос об этом.
Cybmeta
@cybmeta Я пытался, и это моя лучшая попытка, так что не стесняйтесь. Если вам это не нравится, предложите лучшее решение.
Томас