Пользовательский аватар WordPress (Кастомные поля в профиле пользователя).
Сегодня рассмотрим вариант, как можно добавить в профиль пользователя WordPress возможность загружать изображения, в качестве аватара, а так же выведем его в комментариях, в качестве примера.
Использовать будем как обычно для вывода нужных Нам полей два события: show_user_profile и edit_user_profile. А для обработки данных personal_options_update и edit_user_profile_update. Помимо этого сделаем проверку загрузки определенного расширения и выведем при не соответствии сообщение с ошибкой. Для этого нам понадобятся ещё два события.
- load-user-edit.php — будет выводить сообщения на странице user-edit.php, при редактировании администратором страницы юзера
- load-profile.php — будет выводить сообщения на странице profile.php, когда пользователь редактирует свой профиль
if(!function_exists('VAB_user_fields')){ function VAB_user_fields($user){ global $pagenow; if($pagenow=='profile.php'||$pagenow=='user-edit.php'){ wp_nonce_field('VAB_mode_ufields_nonce','VAB_ufields_nonce'); $id=$user->ID; $myAvatar=get_the_author_meta('myAvatar',$id); $del_But='<img style="margin-bottom:-7px!important;cursor:pointer;" id="VAB_remove" src="'.get_template_directory_uri().'/images/delete.png" width="auto" height="33">'; $avka=!empty($myAvatar)?'<img style="width:64px;height:64px;" src="'.get_site_url()."/wp-content/uploads/myAvatar/".$myAvatar.'" />'.$del_But.'<input id="checkrem" style="display:none;" type="checkbox" name="removemyAvatar">':''; echo'<label for="myAvatar">'.__('Пользовательский аватар','VAB').' »» '.__('только JPEG','VAB').' <input type="file" name="filename" id="myAvatar"/></label>'.$avka.'<script type="text/javascript">jQuery(\'form\').attr(\'enctype\',\'multipart/form-data\');jQuery(\'#checkrem\').prop("checked",false);jQuery(document).on(\'click\',\'#VAB_remove\',function(){jQuery(this).prev(\'img\').remove();jQuery(this).next(\'#checkrem\').prop("checked",true);});</script>'; }}} add_action('show_user_profile','VAB_user_fields'); add_action('edit_user_profile','VAB_user_fields');
Разберем код подробнее:
- переменная $del_But — это просто какое-либо изображение, в данном случае корзина, при нажатии на которую будет происходить удаление из разметки аватарки с помощью jQuery (тут может быть что угодно, не обязательно изображение главно идентификатор, который важен для клика)
- переменная $avka — через тернарное выражение определяем в переменную (при наличии мета данных в базе) либо изображение (будущая аватарка) совместно с кнопкой для удаления и скрытым полем type=»checkbox», которое будет служить сигналом для удаления данных из базы, а так же изображения из папки, либо оставим пустым значением
- через echo выводим на экран input type=»file» для выбора изображения, переменную $avka, которая либо пустая, либо наполнена данными и скрипт, который можно выводить так же через события в подвале, либо подключать файл (я же вывел его по месту)
Разберем подробнее скрипт
jQuery('form').attr('enctype','multipart/form-data');
Для работы с файлами у формы должен быть обязательно атрибут enctype=»multipart/form-data». А что такое функционал в админки вордпресс? Это все формы. Если его не добавить будем ловить довольно знаменитую ошибку
Warning: Cannot modify header information — headers already sent by
jQuery('#checkrem').prop("checked",false);
В данном случае при загрузки страницы Мы на всякий случай снимаем со скрытого поля с идентификатором #checkrem флажок, т.к. в обработчике у нас по условию будет очистка данных в базе и удаление аватарки из папки при установленном флажке.
jQuery(document).on('click','#VAB_remove',function(){ jQuery(this).prev('img').remove(); jQuery(this).next('#checkrem').prop("checked",true); });
Ну а сдесь Мы по нажатию на изображение корзина, удаляем из разметки предыдущий тег из разметки (это тег img — наша аватарка) и на следующий за корзиной скрытый инпут (идентификатор #checkrem) выставляем флажок (checked — отмеченый), благодаря чему, нажав на кнопку «Обновить профиль» произойдет удаление данных.
if(!function_exists('save_VAB_user_fields')){ function save_VAB_user_fields($user_id){ $nonce=filter_input(INPUT_POST,'VAB_ufields_nonce',FILTER_SANITIZE_STRING); if(!$nonce){return;}//проверяем наши nonce поля if(!wp_verify_nonce($nonce,'VAB_mode_ufields_nonce')){return;}//проверяем наши nonce поля $myAvatar=get_the_author_meta('myAvatar',$user_id);//проверяем данные в базе if(is_uploaded_file($_FILES["filename"]["tmp_name"])){//Если файл загружен при помощи HTTP POST $inp=$_FILES['filename'];$FILES_name=$inp['name'];$FILES_tmp_name=$inp['tmp_name'];//собираем данные на файл $ext=substr($FILES_name,strpos($FILES_name,'.'),strlen($FILES_name)-1);//получаем расширение файла if($ext==".jpg"||$ext=='.jpeg'){//если расширение jpg или jpeg $DiR=ABSPATH.'wp-content/uploads/myAvatar'; if(!file_exists($DiR)){//если директории, куда будем отправлять аватарки нет mkdir($DiR,0777,true);}// создадим её move_uploaded_file($FILES_tmp_name, $DiR."/".$user_id.$ext);//перемещаем загруженный файл в директорию update_user_meta($user_id,'myAvatar',$user_id.$ext);//сохраняем в базе информацию о загруженном файле }else{//если расширение не прошло валидацию $erR='<div class="error"><p><strong>'.__('Ошибка','VAB').'</strong>: '.__('Выбран неверный формат изображения','VAB').'</p></div>';//формируем для вывода на экран текст ошибки set_transient('erRorUser',array('nonce'=>$erR),10); return;}}//и сохраняем в базе во временной опции на 10 секунд if(isset($_POST['removemyAvatar'])&&isset($myAvatar)){//если при нажатии на кнопку «Обновить профиль» скрытый чекбокс был отмечен и есть данные в базе if(file_exists(ABSPATH.'wp-content/uploads/myAvatar/'.$myAvatar)){ unlink(ABSPATH.'wp-content/uploads/myAvatar/'.$myAvatar);}//удаляем файл, при наличии delete_user_meta($user_id,'myAvatar');}//удаляем мета данные из базы }} add_action('personal_options_update','save_VAB_user_fields'); add_action('edit_user_profile_update','save_VAB_user_fields');
Важно!!! При загрузке файла необходимо учесть и то, что пользователь может загружать файлы больших объемов и разрешений. Можно, разумеется, добавить проверку на размер файла, но в идеале, думаю, их необходимо, при необходимости, проверять и обрезать до нужных размеров, а так же оптимизировать. Для этих целей я использую самописную функцию, в которой собран нужный мне набор Imagick. Все возможности Imagick Вы можете посмотреть здесь. Функцию выкладывать я не стал, т.к. это отдельная история…
Теперь оформим вывод ошибки в админ панели WordPress на случай, если формат будет не верным. Используем два события (add_action) load-user-edit.php и load-profile.php. Прикрепляем к ним произвольную функцию. В данном случае VAB_add_error, в которой проверяем наличие в базе временной опции get_transient(‘erRorUser’) и при наличии данных запускаем событие (add_action) admin_notices, к которому прикрепляем функцию (VAB_show_error), которая уже выводит на экран через echo данные временной опции get_transient(‘erRorUser’)
if(!function_exists('VAB_add_error')){ function VAB_add_error(){ $data=get_transient('erRorUser');//проверяем в базе наличие временной опции if($data&&$data['nonce']){//проверяем ее содержимое add_action('admin_notices','VAB_show_error');}}}//запускаем событие admin_notices add_action('load-user-edit.php','VAB_add_error'); add_action('load-profile.php','VAB_add_error'); if(!function_exists('VAB_show_error')){ function VAB_show_error(){ $data=get_transient('erRorUser');$erRorMessage=''; if($data&&$data['nonce']){$erRorMessage=$data['nonce'];} echo$erRorMessage;}}//выводим на экран содержимое временной опции
Осталось, где-то вывести загруженный файл. Для примера я решил вывести его в комментариях. У каждой темы шаблон комментариев может сильно отличаться. По умолчанию аватары выводятся через функцию вордпресс get_avatar(). Необходимо просто её заменить, либо вывести альтернативу при наличии загруженного пользователем.
$myAvatar=get_the_author_meta('myAvatar',$comment->user_id); echo !empty($myAvatar)?'<img style="width:64px;height:64px;" src="'.get_site_url()."/wp-content/uploads/myAvatar/".$myAvatar.'" />':get_avatar($comment,52); // echo get_avatar($comment,52);
Собственно на этом все…