Как в OTRS показывать аватарки или пишем свой gravatar.com

Только для готовых решений! Пожалуйста, не используйте для вопросов и обсуждений!

Модератор: ykolesnikov

Ответить
vvv476
OTRS Новобранец
Сообщения: 2
Зарегистрирован: 04 дек 2019, 16:51
Поблагодарили: 1 раз

Как в OTRS показывать аватарки или пишем свой gravatar.com

Сообщение vvv476 » 05 дек 2019, 16:32

Есть внутренний портал и на нем лежат фотки сотрудников. Захотелось показывать их в OTRS в качестве аватарок.
Писать свой модуль показалось сложной задачей, поэтому было решено подстроиться под существующий, основанный на работе с сайтом gravatar.com.

Что использовалось:
LAMP - Ubuntu, Apache, MySQL, PHP
OTRS 6.0.25

Сначала создадим свой gravatar.com. Этот сайт принимает в качестве параметра хэш от почтового адреса и отдает соответствующую квадратную фотку. Параметром 's' можно регулировать размер картинки.

1. Настройка Apache

Объясним Apache как он должен обрабатывать запрос вида http://site.local/avatar/205e460b479e2e ... 8d50?s=200

Добавим модуль Rewrite

Код: Выделить всё

a2enmod rewrite
В файле конфигурации, где описывается корень сайта, добавим следующие строчки:

Код: Выделить всё

<Directory /var/www/html>

	...ваша текущая конфигурация...

	RewriteEngine on
	RewriteRule ^avatar/(.*)$ /avatar.php?a=$1 [L,QSA]

	<Files "avatar.php">
		AuthType None
		Require all granted
	</Files>

</Directory>

<Location /avatar/>
	AuthType None
	Require all granted
</Location>
Теперь все запросы по адресу site.local/avatar/... будут передаваться вместе с параметрами скрипту avatar.php, лежащему в корне сайта. Это необязательно, но у меня для этого скрипта отключена аутентификация. Так что обратиться к нему сможет любой пользователь сайта.

2. Таблица avatar

Создадим в MySQL в базе данных 'db' таблицу 'avatar':

Код: Выделить всё

CREATE TABLE `avatar` (
  `id` int(11) NOT NULL,
  `hash` varchar(32) NOT NULL,
  `mail` varchar(64) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Добавим индексы

Код: Выделить всё

ALTER TABLE `avatar`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `hash` (`hash`);
Для чего нужна таблица. У меня все фотки пользователей лежат в '/var/www/html/img/' в формате usr_$id.jpg, где $id - некоторое число.
Так как запросы к gravatar.com в качестве идентификатора содержат в себе только хэш от почтового адреса, то нам надо по этому хэшу найти id нужного пользователя. А вот если нужного хэша нет, то тогда мы обратимся к актуальному источнику всех почтовых адресов пользователей и их ID. У меня этим источником является еще одна таблица 'users'. И если мы найдем такую запись, мы добавим ее в таблицу 'avatar'.
Таким образом в следующий раз искать по всем записям уже не придется. Поле 'mail' в нашей таблице необязательно и служит для наглядного отображения тех, чьи аватарки уже были запрошены.Если у вас статический и небольшой список сотрудников можно один раз заполнить таблицу вот такой SQL-командой для каждого:

Код: Выделить всё

INSERT INTO avatar (id,hash,mail) VALUES (2,MD5(LOWER('otrs@site.local')),'otrs@site.local')
3. Файл avatar.php

Принимает запрос вида site.local/avatar.php?a=205e460b479e2e5b48aec07710c08d50?s=200 где
a - MD5 хэш от email
s - требуемый размер квадратной картинки ( по умолчанию 80 )
В результате скрипт отдает фотку формата jpeg

Код: Выделить всё

<?php
# Подключимся к MySQL
$mysql_link = mysqli_connect('localhost','user','password','db');
if(mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); }
mysqli_query($mysql_link,"SET NAMES utf8");

# Разберем входные параметры
if ( !isset($_GET['a']) ) { exit(); }
$hash = $_GET['a'];
$size = 80;
if ( isset($_GET['s']) )
{
 $size = (int)$_GET['s'];
}

# Попробуем найти ID пользователя по хэшу
$id = 0;
$query = "SELECT id FROM avatar WHERE hash = ?";
$stmt = mysqli_prepare($mysql_link, $query) or die(mysqli_error($mysql_link));
mysqli_stmt_bind_param($stmt, "s", $hash);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt,$id);
mysqli_stmt_fetch($stmt);
mysqli_stmt_close($stmt);

# Если не нашли, то поищем в основном источнике, у всех у кого есть email
if ( !$id )
{
 $query = "SELECT user_id,mail FROM users WHERE mail IS NOT NULL";
 $stmt = mysqli_prepare($mysql_link, $query) or die(mysqli_error($mysql_link));
 mysqli_stmt_execute($stmt);
 mysqli_stmt_bind_result($stmt,$user_id,$mail);
 while (mysqli_stmt_fetch($stmt)) 
 {  
# Вычисляем хэш
  $h = md5( strtolower( $mail ) );
# Если это наш, то прекращаем поиск
  if ( $h === $hash )
  {
   $id = $user_id;
   break;
  }
 }
 mysqli_stmt_close($stmt);

# Если хэш был найден, то запишем его в нашу таблицу
 if( $id > 0 )
 {
  $query = "INSERT INTO avatar (id,hash,mail) VALUES (?,?,?)";
  $stmt = mysqli_prepare($mysql_link, $query) or die(mysqli_error($mysql_link));
  mysqli_stmt_bind_param($stmt, "iss", $id,$hash,$mail);
  mysqli_stmt_execute($stmt);
  mysqli_stmt_close($stmt);
 }
}

# id - это число, но если оно не было найдено ранее, то пусть будет 0
$id = (int)$id;

# Путь к фоткам
$img_dir = "/var/www/html/img/";
$imgname = $img_dir."usr_$id.jpg";
$img = @imagecreatefromjpeg($imgname);

# Преобразуем исходную фотку к квадрату требуемого размера и отдадим браузеру
   
$width = imagesx( $img );
$height = imagesy( $img );

if ( $width >= $height )
{
 $src_w = $height;
 $src_h = $height; 
 $src_x = ( $width - $height ) / 2 ;
 $src_y = 0;
}
else
{
 $src_w = $width;
 $src_h = $width; 
 $src_x = 0;
 $src_y = ( $height - $width ) / 2 ;
}
$tmp_img = imagecreatetruecolor( $size, $size );                          
imagecopyresized( $tmp_img, $img, 0, 0, $src_x, $src_y, $size, $size, $src_w, $src_h );

header('Content-Type: image/jpeg');
imagejpeg($tmp_img);
imagedestroy($img);
imagedestroy($tmp_img);
?>
4. Настройка OTRS

Поиском были найдены в OTRS все файлы где имеются ссылки на gravatar.com. После отсеивания тестов, трасляторов и прочего осталось 3 файла.

Сохраним их оригиналы

Код: Выделить всё

cp -p --parents /usr/share/otrs/Kernel/Output/HTML/Preferences/Avatar.pm    /home/user/otrs/Avatar
cp -p --parents /usr/share/otrs/Kernel/Output/HTML/TicketZoom/Agent/Base.pm /home/user/otrs/Avatar
cp -p --parents /usr/share/otrs/Kernel/Output/HTML/Layout.pm                /home/user/otrs/Avatar
Надо заменить в этих файлах все упоминания 'gravatar.com' на 'site.local'.
Это можно сделать вручную, а можно скриптом, что бы после обновления версии было удобно быстро все поправить.

Поместим полные имена файлов в avatar.lst

Код: Выделить всё

/usr/share/otrs/Kernel/Output/HTML/Preferences/Avatar.pm
/usr/share/otrs/Kernel/Output/HTML/TicketZoom/Agent/Base.pm
/usr/share/otrs/Kernel/Output/HTML/Layout.pm
Создадим файл avatar-patch.pl
Скрипт найдет в этих 3-х файлах все вхождения 'gravatar.com', заменит их на 'site.local'.
Создаст новые файлы с существующими правами и владением. Старые переименует рядом с раширением .bak

Код: Выделить всё

#!/usr/bin/perl

open(LIST,"avatar.lst");
while(<LIST>)
{
 chomp;
 my $file = $_;
 my $mode = (stat($file))[2];
 my $uid =  (stat($file))[4];
 my $gid =  (stat($file))[5];

 $owner = getpwuid($uid); 
 $group = getgrgid($gid); 
 $mode = sprintf "%04o", $mode & 07777;

 print "$file $mode $owner:$group\nLines:";
 open(F,$file);
 my $out_file = $file.'.fix';
 open(O,'>'.$out_file);
 $c = 1;
 while(<F>)
 {
  if (/www\.gravatar\.com/) { print $c.' '; }
  s/www\.gravatar\.com/site.local/g;
  print O ;
  $c++;
 }
 close O;
 chmod oct($mode),$out_file;
 chown $uid,$gid,,$out_file;
 $back_file = $file.'.bak';
 rename $file,$back_file;
 rename $out_file,$file;
 print "\n";
}
close LIST;
Запустим avatar-patch.pl

Если нужно все восстановить, то нам поможет файл avatar-restore

Код: Выделить всё

mv -f /usr/share/otrs/Kernel/Output/HTML/Preferences/Avatar.pm.bak    /usr/share/otrs/Kernel/Output/HTML/Preferences/Avatar.pm
mv -f /usr/share/otrs/Kernel/Output/HTML/TicketZoom/Agent/Base.pm.bak /usr/share/otrs/Kernel/Output/HTML/TicketZoom/Agent/Base.pm
mv -f /usr/share/otrs/Kernel/Output/HTML/Layout.pm.bak                /usr/share/otrs/Kernel/Output/HTML/Layout.pm
5. Перезапустим Apache

Код: Выделить всё

service apache2 restart
Все.

alexus
OTRS Гуру
Сообщения: 5069
Зарегистрирован: 20 сен 2010, 18:17
Откуда: Москва
Благодарил (а): 74 раза
Поблагодарили: 70 раз

Re: Как в OTRS показывать аватарки или пишем свой gravatar.com

Сообщение alexus » 05 дек 2019, 16:56

Отличный мануал, надо будет попробовать. Но есть одно важное "НО" - не надо править оригинальные файлы
vvv476 писал(а):
05 дек 2019, 16:32
4. Настройка OTRS

Поиском были найдены в OTRS все файлы где имеются ссылки на gravatar.com. После отсеивания тестов, трасляторов и прочего осталось 3 файла.

Сохраним их оригиналы
КОД: ВЫДЕЛИТЬ ВСЁ
cp -p --parents /usr/share/otrs/Kernel/Output/HTML/Preferences/Avatar.pm /home/user/otrs/Avatar
cp -p --parents /usr/share/otrs/Kernel/Output/HTML/TicketZoom/Agent/Base.pm /home/user/otrs/Avatar
cp -p --parents /usr/share/otrs/Kernel/Output/HTML/Layout.pm /home/user/otrs/Avatar
Надо заменить в этих файлах все упоминания 'gravatar.com' на 'site.local'.
Надо их скопировать в /otrs/Custom/Kernel/Output/HTML/* - и там уже и править.
С уважением,
Алексей Юсов

Prod: OTRS CE ITSM 6.0.28 on CentOS 7 Apache 2.4 MariaDB 10.4.13 + Radiant Customer Portal

Radiant System OTRS Intergrator RU
Группа OTRS Community в Teleram
Хотите внедрить OTRS? Спросите меня как!

vvv476
OTRS Новобранец
Сообщения: 2
Зарегистрирован: 04 дек 2019, 16:51
Поблагодарили: 1 раз

Re: Как в OTRS показывать аватарки или пишем свой gravatar.com

Сообщение vvv476 » 05 дек 2019, 17:02

6. Замечания

6.1 Положите в '/var/www/html/img/' файл usr_0.jpg - это будет картинка по умолчанию для тех, чей аватар не найден.

6.2 Если зайти в Редактирование агента -> Редактировать персональные настройки этого агента -> Профиль пользователя,
то в секции настроек "Аватар" вы увидите свою картинку, а не фотку редактируемого Агента.

Что бы это исправить надо в '/usr/share/otrs/Kernel/Output/HTML/Preferences/Avatar.pm' изменить код:

Код: Выделить всё

    if ( $AvatarEngine eq 'Gravatar' && $Self->{UserEmail} ) {
        $Return->{Avatar} = '//site.local/avatar/' . md5_hex( lc $Self->{UserEmail} ) . '?s=45&d=mp';
на этот:

Код: Выделить всё

    if ( $AvatarEngine eq 'Gravatar' )
    {
	my %CurrentUserData = $Kernel::OM->Get('Kernel::System::User')->GetUserData( UserID => $Self->{UserID} );
	my $CurrentUserEmail = $CurrentUserData{UserEmail};
        if ( $CurrentUserEmail ) {
	    $Return->{Avatar} = '//site.local/avatar/' . md5_hex( lc $CurrentUserEmail ) . '?s=45&d=mp';
	}
    }

Ответить