Песочница →
Добавление аватара к пользователю в Joomla 1.7
Эта статья посвящена разбору стандартного компонента Joomla 1.7 com_users
Буквально недавно столкнулся с одной из маленьких проблем.
Делал сайт на Joomla 1.7, но в момент, когда сайт почти был закончен,
потребовалось поставить пользователю аватар.
Не найдя решения для стандартного компонента ( не для CB или JoomSocial ) в интернете, я решил разобраться в его работе.
Первым делом, посмотрим в БД, чтобы разобраться, как храняться данные о пользователе.
Внутри БД мы увидим 3 таблицы связанные с пользователями.
Нас будет интересовать одна: jos_users (jos_ — это префикс таблиц, у каждого свой).
Увидев, что таблица пользователей имеет вполне себе стандартную простую структуру полей, добавим поле avatar к этой таблице с типом текст ( нет особого смысла хранить всю картинку в БД, мы будем хранить там ссылку на файл, который будет лежать на сервере ).
Как известно, в Joomla 1.7 поля для форм задаются в xml файлах, которые находятся в папке com_users\models\forms найдем там форму информации пользователя, этот файл называется: profile.xml
Добавим поле ввода аватара
<field name="avatar" type="file" id="avatar"
description="COM_USERS_PROFILE_AVATAR_DESC"
label="COM_USERS_PROFILE_AVATAR_LABEL"
message="COM_USERS_PROFILE_AVATAR_MESSAGE"
required="false"
size="30"
/>
Ниже константы, которые находятся в общих языковых файлах.
Там устанавливается описание, label и всплывающая подсказка
description="COM_USERS_PROFILE_AVATAR_DESC"
label="COM_USERS_PROFILE_AVATAR_LABEL"
message="COM_USERS_PROFILE_AVATAR_MESSAGE"
Это поле только лишь добавит его в форму.
Дальше необходимо из формы закачать этот файл на сервер и записать ссылку в БД.
Сохранением данных занимается модель, но,
она работает не с массивом $_POST и $_FILES, а с переменной $data,
которую принимает как аргумент.
Следует, что необходимо добавить массив $_FILES к переменной $data.
Для этого идем в контроллер, отвечающий за это.
Путь к файлу:
com_users\controllers\profile.php
Внутри функции public function save()
ищем присвоение ПОСТ данных в переменную, выглядит это так:
$data = JRequest::getVar('jform', array(), 'post', 'array');
Следующей строкой добавляем:
$data['avatar']=$_FILES;
Теперь переходим в модель.
Путь к файлу: com_users\models\profile.php
В нем, мы для начала добавим одну функцию перед функцией save():
private function checkAvatar($avatar,&$data)
{
/*Если поле осталось пустое, то ставить картинку по умолчанию*/
if(strlen(trim($avatar))==1)
$data['avatar'] = '/images/avatars/no_avatar.gif';
else
unset($data['avatar']);//чтобы не затирался аватар при изменении
}
Смысл функции станет понятен ниже.
Теперь изменим функцию save(), добавив обработку поля $data['avatar']
$db = JFactory::getDBO(); // подключаемся к базе
$query = "SELECT `avatar` FROM `#__users` WHERE `id`='".$user->get('id')."' LIMIT 1;"; // Создаем запрос
$db->setQuery( $query);// выполняем запрос
$avatar=$db->loadResult();
//Uploading avatar to server
if(strlen(trim($data['avatar']["jform"]['size']['name']))==1){
$this->checkAvatar($avatar,$data);
}
else {
$avatar_path='';
if($data['avatar']["jform"]['size']['avatar'] > 1024*3*1024)
{
echo "Размер файла превышает 3МБ";
$this->checkAvatar($avatar,$data);
}
else if(is_uploaded_file($data['avatar']['jform']['tmp_name']['avatar']))
{
$avatar_path="/images/avatars/".$data['avatar']['jform']['name']['avatar'];
unlink($data['avatar']['jform']['tmp_name']['avatar']);//удаление файла с таким же именем
move_uploaded_file($data['avatar']['jform']['tmp_name']['avatar'],JPATH_ROOT.$avatar_path);
$data['avatar']='http://www.site_name.net'.$avatar_path;
} else {
echo "Ошибка загрузки файла на сервер";
$this->checkAvatar($avatar,$data);
}
}
Вместо echo вы можете послать исключение, либо ошибку.
Также можно добавить валидацию расширений, разрешений, для этого есть
масса php уроков.
Суть функций предельно проста, смотрим в файлах аватар, если имя файла не пустое, тогда сравниваем размер с максимально допустимым, если всё хорошо, то файл загружается на сервер, затем перемещается в папку $avatar_path с исходным именем.
Вариант простого создания уникальных аватарок, который я придумал, состоит в том, что мы сохраняем картинку с именем, которое будет, к примеру логин.jpg, логины ведь у нас в БД уникальны.
Всё, на сервер загрузили, и в БД запишется:
$data['avatar']='http://www.site_name.net'.$avatar_path;
Главную часть мы выполнили, осталось всё красиво вывести.
Для начала выведем аватар там, где и добавляем, т.е. в форме изменения
информации пользователя.
В контроллере, внутри функции public function edit(),
ищем такой блок (в стандарте стоит в начале функции):
$app = JFactory::getApplication();
$user = JFactory::getUser();
$loginUserId = (int) $user->get('id');
// Get the previous user id (if any) and the current user id.
$previousId = (int) $app->getUserState('com_users.edit.profile.id');
$userId = (int) JRequest::getInt('user_id', null, '', 'array');
Т.к. тип мы указали файл в xml файле, то стандартное API джумлы для получения полей:
$user->get('avatar');
в данном случае нам не подойдет.Поэтому используем прямое подключение к базе:
$db = JFactory::getDBO(); // подключаемся к базе
$query = "SELECT `avatar` FROM `#__users` WHERE `id`='".$user->get('id')."' LIMIT 1;"; // Создаем запрос
$db->setQuery( $query);// выполняем запрос
$avatar=$db->loadResult();
Этот код вставляем после найденного выше блока. Таким образом, мы сделали переменную с путём к файлу картинки.
Далее идем в представление (вид)
Путь к файлу: /public_html/components/com_users/views/profile/tmpl/edit.php
Здесь проделываем почти то же самое, только еще и отображаем картинку.
Ниже строки:
$lang->load( 'plg_user_profile', JPATH_ADMINISTRATOR );
вставляем код:
$app = JFactory::getApplication();
$user = JFactory::getUser();
$db = JFactory::getDBO(); // подключаемся к базе
$query = "SELECT `avatar` FROM `#__users` WHERE `id`='".$user->get('id')."' LIMIT 1;"; // Создаем запрос
$db->setQuery( $query);// выполняем запрос
$avatar=$db->loadResult();
Затем, там, где мы хотим увидеть аватар, вставляем код:
<div class="profile-edit<?php echo $this->pageclass_sfx?>">
<?php if ($this->params->get('show_page_heading')) : ?>
<?php echo $this->escape($this->params->get('page_heading')); ?>
<?php endif; ?>
<div class="img-avatar">
<img src="<?= $avatar;?>" style="width:100px;height:100px;" />
</div>
Смотрите не вставьте в цикл. Я вставлял сразу перед тэгом form.
Всё, теперь мы можем увидеть наш аватар при изменении профиля.
Осталось отобразить его в профиле.
Путь к файлу: /public_html/components/com_users/views/profile/tmpl/edit.php
Ниже строки:
jimport('joomla.user.helper');
Определяем наш путь к аватарке.
$user = JFactory::getUser();
$db = JFactory::getDBO(); // подключаемся к базе
$query = "SELECT `avatar` FROM `#__users` WHERE `id`='".$user->get('id')."' LIMIT 1;"; // Создаем запрос
$db->setQuery( $query);// выполняем запрос
$avatar=$db->loadResult();
Далее, по аналогии с остальными полями, вставляем код:
<dt>
<?php echo JText::_('COM_USERS_PROFILE_AVATAR_LABEL'); ?>
</dt>
<dd>
<img src="<?php echo $avatar; ?>" style="width:100px;height:100px;"/>
</dd>
там, где хотим видеть картинку.
Затем редактируем языковые файлы и всё.
Готово.
31.01.2012 18:44+0400