Как реализовать загрузку файлов в админке WordPress часть 2

Давным-давно я уже писал о том как добавить в админку WordPress произвольное поле с возможностью загрузки файлов, но код из той статьи все это время меня смущал. Дело в том что прошлый раз я описал не лучшую реализацию загрузчика да и код мягко говоря грязноват, поэтому я решил написать тоже самое но более красиво и удобно поэтому я изучил вопрос глубже и выяснилось вот что: в админке на странице редактирования поста в javascript определен глобальный объект wp который содержит все что нужно для реализации данной функциональности.
Содержимое объекта с комментариями можно посмотреть в файле wp-includes/js/media-editor.js.

Посмотрев на все это я написал кусочек JavaScript который по всем параметрам сильно лучше аналогичного из прошлого поста, код реше ряда недостатков, нет прямых обращений к window, url параметров и ссылок прописанных прямо в коде.

Благодаря всему этому стало возможным запихнуть весь функционал фронтенда загрузчика а один обработчик onclick.

jQuery(function ($) {
$("[href='#al_uploader_anchor']").on('click',function () {
var elem = $(this);
var img_wrap = $('.al_uploader-img-wrap');
var input = img_wrap.parent().find('input');
wp.media.editor.send.attachment = function (info, file) {
var id = file.id;
var url = file.url;
img_wrap.find('img').remove();
img_wrap.append("<img src='" + url + "' style='display: block; width:100%; height: auto' >");
input.attr('value', id);
elem.text(elem.attr('data-text'));
};
wp.media.editor.open(this);
return false;
});

});

Здесь аргумент file , callback-функции содержит всю необходимую информацию о медиафайле включая его id который я и буду использовать в дальнейшем на бекенде, а вот кстати и его код:

class  al_uploader
{
private $this_file;
private $form_attr_name;
private $post_types = array();
function __construct($file)
{
$this->post_types = apply_filters('al_uploader_post_types', array('post'));
$this->this_file = $file;
$this->form_attr_name = '_al_uploader_upload_field_';
add_action('admin_init', array($this, 'add_extra_fields'), 1);
add_action('save_post', array($this, 'fields_update'), 0);
add_action('admin_enqueue_scripts', array($this, 'upload_script'));
}
function upload_script()
{
if (!did_action('wp_enqueue_media')) {
wp_enqueue_media();
}
wp_enqueue_script('al_uploader_scripts', plugin_dir_url($this->this_file) . 'admin/js/scripts.js', array('jquery'), null, false);
}
function add_extra_fields()
{
add_meta_box('al_uploader', 'Загрузка файла', array($this, 'fields_html'), array('post'), 'side', 'low');
}
function fields_html($post)
{
$field_name='al_thumbnail';
$post_data = get_post_meta($post->ID, 'al_thumbnail', true);
?>

<?php
if ($post_data == '') {
echo "<a href='#al_uploader_anchor' data-text='Задать другую миниатюру'>Задать миниатюру</a>";
} else {
echo "<a href='#al_uploader_anchor' data-text='Задать миниатюру'>Задать новую миниатюру</a>";
}
?>

<input type="text" name="<?php echo $this->form_attr_name; ?>[<?php echo $field_name;?>]"
value="<?php echo $post_data[$field_name]; ?>" style="display: none"/>
<span class="al_uploader-img-wrap">
<?php if ($post_data !== '') {
$src = wp_get_attachment_image_url($post_data, array(300, 300));
echo "<img src='{$src}' style='display: block; width: 100%; height: auto'>";
}
?>
</span>

<input type="hidden" name="<?php echo $this->form_attr_name; ?>_fields_nonce"
value="<?php echo wp_create_nonce($this->this_file); ?>"/>
<?php } function fields_update($post_id) { if (!wp_verify_nonce($_POST[$this->form_attr_name . '_fields_nonce'], $this->this_file)) {
return false;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return false;
}
if (!current_user_can('edit_post', $post_id)) {
return false;
}
if (!isset($_POST[$this->form_attr_name])) {
return false;
};
$items = array_map('trim', $_POST[$this->form_attr_name]);
foreach ($items as $key=>$val){
update_post_meta($post_id, $key, $val);
}
return $post_id;
}
}
function al_uploader_init()
{
new al_uploader(__FILE__);
}
add_action('plugins_loaded', 'al_uploader_init');

тут все просто , сначала в методе upload_script подключаем необходимые JavaScript файлы, после с помощью add_extra_fields и add_meta_box создаем стандартный метабокс, метод fields_html добавляет разметку метабокса, и в конце обработчик POST запросов fields_update стандартным для меня способом который я когда то видел на сайте wp-kama.ru (кстати рекомендую почитать этот сайт).
Собственно всё, плагин готов исходники я выложил на Github. Теперь его можно установить, добавить изображение к какому либо посту и после сохранения можно будет получить его как обычное произвольное поле WordPress

 get_post_meta($post_id, 'al_thumbnail', true ); 

После чего его можно будет использовать например в коде шаблонов либо в любом другом месте на свое усмотрение.

Так же в конструктор класса плагина я добавил фильтр al_uploader_post_types что бы можно было при необходимости добавить метабок плагина к любому типу поста, а не только типа post

add_filter('al_uploader_post_types', function($arr){
$arr[]='page';
return $arr;
});

Прмерно вот так.

2 Комментариев

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *