Skip to content
Snippets Groups Projects
Commit 9ae449f9 authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms
Browse files

use webp for avatars and convert current avatars, fixes #3183

Closes #3183

Merge request !2326
parent d375c513
Branches
No related tags found
No related merge requests found
Showing
with 448 additions and 423 deletions
......@@ -31,10 +31,10 @@ public/pictures/banner/*.gif
public/pictures/banner/*.jpeg
public/pictures/banner/*.jpg
public/pictures/banner/*.png
public/pictures/course/[0-9a-f]*.png
public/pictures/institute/[0-9a-f]*.png
public/pictures/stock-images/*
public/pictures/user/[0-9a-f]*.png
public/pictures/course/*/*.webp
public/pictures/institute/*/*.webp
public/pictures/user/*/*.webp
public/plugins_packages/*
tests/_log
......
......@@ -29,13 +29,13 @@ class AvatarController extends AuthenticatedController
PageLayout::setTitle(_('Profilbild ändern'));
$has_perm = $GLOBALS['perm']->have_profile_perm('user', $id);
$class = 'Avatar';
$class = Avatar::class;
$this->cancel_link = $this->url_for('profile', ['username' => User::find($id)->username]);
} else if ($type == 'institute') {
PageLayout::setTitle(Context::getHeaderLine() . ' - ' . _('Einrichtungsbild ändern'));
$has_perm = $GLOBALS['perm']->have_studip_perm('admin', $id);
$class = 'InstituteAvatar';
$class = InstituteAvatar::class;
$this->cancel_link = $this->url_for('institute/basicdata/index', ['cid' => $id]);
} else {
PageLayout::setTitle(Context::getHeaderLine() . ' - ' . _('Veranstaltungsbild ändern'));
......@@ -44,10 +44,10 @@ class AvatarController extends AuthenticatedController
$sem = Seminar::getInstance($id);
$studygroup_mode = $sem->getSemClass()->offsetget('studygroup_mode');
if ($studygroup_mode) {
$class = 'StudygroupAvatar';
$class = StudygroupAvatar::class;
$this->cancel_link = $this->url_for('course/studygroup/edit?cid=' . $id);
} else {
$class = 'CourseAvatar';
$class = CourseAvatar::class;
$this->cancel_link = $this->url_for('course/management?cid=' . $id);
}
}
......@@ -56,20 +56,17 @@ class AvatarController extends AuthenticatedController
throw new AccessDeniedException(_('Sie haben keine Berechtigung, das Bild zu ändern.'));
}
if ($type == 'user') {
if ($type === 'user') {
Navigation::activateItem('/profile/index');
} else if ($type == 'institute') {
} else if ($type === 'institute') {
Navigation::activateItem('/admin/institute/details');
} else {
Navigation::activateItem('/course/admin/avatar');
}
$this->customized = false;
$avatar = $class::getAvatar($id);
$this->avatar = $avatar->getURL($class::NORMAL);
if ($avatar->is_customized()) {
$this->customized = true;
}
$this->customized = $avatar->is_customized();
$this->type = $type;
$this->id = $id;
......@@ -88,21 +85,21 @@ class AvatarController extends AuthenticatedController
// Check for permission to save a new avatar.
if ($type == 'user') {
$has_perm = $GLOBALS['perm']->have_profile_perm('user', $id);
$class = 'Avatar';
$class = Avatar::class;
$redirect = 'profile?username=' . User::find($id)->username;
} else if ($type == 'institute') {
$has_perm = $GLOBALS['perm']->have_studip_perm('admin', $id);
$class = 'InstituteAvatar';
$class = InstituteAvatar::class;
$redirect = 'institute/basicdata/index';
} else {
$has_perm = $GLOBALS['perm']->have_studip_perm('tutor', $id);
$sem = Seminar::getInstance($id);
$studygroup_mode = $sem->getSemClass()->offsetget('studygroup_mode');
if ($studygroup_mode) {
$class = 'StudygroupAvatar';
$class = StudygroupAvatar::class;
$redirect = 'course/studygroup/edit/?cid=' . $id;
} else {
$class = 'CourseAvatar';
$class = CourseAvatar::class;
$redirect = 'course/management';
}
}
......
......@@ -298,7 +298,7 @@ class PrivacyController extends AuthenticatedController
$avatar = Avatar::getAvatar($user_id);
if ($avatar->is_customized()) {
$zip->addFile($avatar->getCustomAvatarPath('normal'), $user_id . '.png');
$zip->addFile($avatar->getCustomAvatarPath('normal'), $user_id . '.webp');
}
foreach (FileRef::findByUser_id($user_id) as $fileref) {
......
......@@ -26,7 +26,7 @@ class User extends \RESTAPI\RouteMap
'avatar_small' => $avatar->getURL(\Avatar::SMALL),
'avatar_medium' => $avatar->getURL(\Avatar::MEDIUM),
'avatar_normal' => $avatar->getURL(\Avatar::NORMAL),
'avatar_original' => $avatar->getURL(\Avatar::ORIGINAL)
'avatar_original' => $avatar->getURL(\Avatar::NORMAL)
];
}
......@@ -118,7 +118,7 @@ class User extends \RESTAPI\RouteMap
'avatar_small' => $avatar->getURL(\Avatar::SMALL),
'avatar_medium' => $avatar->getURL(\Avatar::MEDIUM),
'avatar_normal' => $avatar->getURL(\Avatar::NORMAL),
'avatar_original' => $avatar->getURL(\Avatar::ORIGINAL),
'avatar_original' => $avatar->getURL(\Avatar::NORMAL),
'phone' => $get_field('privatnr', 'private_phone'),
'homepage' => $get_field('Home', 'homepage'),
'privadr' => strip_tags($get_field('privadr', 'privadr')),
......
......@@ -36,8 +36,8 @@
</label>
<label class="file-upload">
<?= _('Bild hochladen (PNG, JPG, GIF)') ?>
<input type="file" name="avatar" accept=".jpg,.png,.jpeg,.gif">
<?= _('Bild hochladen (PNG, JPG, GIF, WebP)') ?>
<input type="file" name="avatar" accept=".jpg,.png,.jpeg,.gif,.webp">
</label>
<label>
......
<?php
/**
* @var AvatarController $controller
* @var string $type
* @var string $id
* @var string $avatar
* @var bool $customized
* @var string $cancel_link
*/
?>
<form class="default settings-avatar" enctype="multipart/form-data"
action="<?= $controller->url_for('avatar/upload', $type, $id) ?>" method="post">
action="<?= $controller->link_for('avatar/upload', $type, $id) ?>" method="post">
<fieldset>
<legend>
<?= $type == 'user' ? _('Profilbild bearbeiten und zuschneiden') :
......@@ -8,20 +18,20 @@
</legend>
<div class="form-group">
<div id="avatar-preview">
<img class="avatar-normal" id="new-avatar" src="<?= $avatar ?>"
<img class="avatar-normal" id="new-avatar" src="<?= htmlReady($avatar) ?>"
data-message-too-small="<?= _('Das Bild ist kleiner als 250 x 250 Pixel. Wollen Sie wirklich fortfahren?') ?>">
</div>
<label class="file-upload">
<?= _('Wählen Sie ein Bild von Ihrer Festplatte aus.') ?>
<input type="file" id="avatar-upload" accept="image/gif,image/png,image/jpeg"
<input type="file" id="avatar-upload" accept="image/gif,image/png,image/jpeg,image/webp"
capture="camera"
data-max-size="<?= Avatar::MAX_FILE_SIZE ?>"
data-message-too-large="<?= _('Die hochgeladene Datei ist zu groß. Bitte wählen Sie ein anderes Bild.') ?>">
<p class="form-text">
<?= sprintf(
_('Die Bilddatei darf max. %s groß sein, es sind nur Dateien mit den Endungen .jpg, .png oder .gif erlaubt!'),
_('Die Bilddatei darf max. %s groß sein, es sind nur Dateien mit den Endungen .jpg, .png, .gif und .webp erlaubt!'),
relsize(Avatar::MAX_FILE_SIZE)
) ?>
</p>
......
<?php
final class ConvertAvatarsToWebp extends Migration
{
const SIZES = [
'small' => [
'default' => [25 * 2, 25 * 2],
'license' => [60 * 2, 20 * 2],
],
'medium' => [
'default' => [100 * 2, 100 * 2],
'license' => [120 * 2, 40 * 2],
],
'normal' => [
'default' => [250 * 2, 250 * 2],
'license' => [300 * 2, 100 * 2],
],
];
protected function up()
{
foreach (['user', 'course', 'institute', 'licenses'] as $type) {
$source_directory = $GLOBALS['DYNAMIC_CONTENT_PATH'] . '/' . $type;
// Convert original images
$iterator = new RegexIterator(
new FilesystemIterator($source_directory),
'/_original\.png$/i'
);
foreach ($iterator as $file) {
$this->convert($file, $type);
}
// Convert leftover images
$iterator = new RegexIterator(
new FilesystemIterator($source_directory),
'/_normal\.png$/i'
);
foreach ($iterator as $file) {
$this->convert($file, $type);
}
}
}
private function convert(
SplFileInfo $input_file,
string $type
): void {
$input_image = imagecreatefromstring(file_get_contents($input_file->getPathname()));
if ($input_image === false) {
unlink($input_file->getPathname());
return;
}
$user_id = explode('_', $input_file->getBasename('.png'))[0];
$output_path = $input_file->getPath();
if ($type !== 'licenses') {
$output_path .= '/' . substr($user_id, 0, 2);
}
if (!is_dir($output_path)) {
mkdir($output_path);
}
imagepalettetotruecolor($input_image);
imagealphablending($input_image, false);
imagesavealpha($input_image, true);
$image_width = imagesx($input_image);
$image_height = imagesy($input_image);
foreach (array_keys(self::SIZES) as $size) {
[$width, $height] = self::SIZES[$size][$type] ?? self::SIZES[$size]['default'];
$output_file = "{$output_path}/{$user_id}_{$size}.webp";
$factor = min($width / $image_width, $height / $image_height);
$resized_width = round($image_width * $factor);
$resized_height = round($image_height * $factor);
$xpos = intval($width - $resized_width) >> 1;
$ypos = intval($height - $resized_height) >> 1;
$output_image = $this->createNewImage($width, $height);
imagecopyresampled(
$output_image, $input_image,
$xpos, $ypos,
0, 0,
$resized_width, $resized_height,
$image_width, $image_height
);
imagewebp($output_image, $output_file, 90);
imagedestroy($output_image);
}
imagedestroy($input_image);
unlink($input_file->getPath() . '/' . $user_id . '_original.png');
foreach (array_keys(self::SIZES) as $size) {
unlink($input_file->getPath() . '/' . $user_id . '_' . $size . '.png');
unlink($input_file->getPath() . '/' . $user_id . '_' . $size . '@2x.png');
}
}
private function createNewImage(int $width, int $height)
{
$image = imagecreatetruecolor($width, $height);
imagealphablending($image, false);
imagesavealpha($image, false); // Otherwise, WebP won't store the alpha information
$transparent_color = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $transparent_color);
return $image;
}
}
......@@ -61,8 +61,9 @@ if (isset($_SERVER['SERVER_NAME'])) {
$ABSOLUTE_URI_STUDIP .= $CANONICAL_RELATIVE_PATH_STUDIP;
}
// default ASSETS_URL, customize if required
// default ASSETS_URL and ASSETS_PATH, customize if required
$GLOBALS['ASSETS_URL'] = $ABSOLUTE_URI_STUDIP . 'assets/';
$GLOBALS['ASSETS_PATH'] = $ABSOLUTE_PATH_STUDIP . 'assets/';
require __DIR__ . '/classes/StudipFileloader.php';
......@@ -107,6 +108,7 @@ require_once 'lib/visual.inc.php';
// set assets url
Assets::set_assets_url($GLOBALS['ASSETS_URL']);
Assets::set_assets_path($GLOBALS['ASSETS_PATH']);
// globale template factory anlegen
require_once 'vendor/flexi/lib/flexi.php';
......
......@@ -41,8 +41,20 @@ class Assets
/**
* @ignore
*/
private static $assets_url, $dynamic, $counter_cache;
private static $assets_url;
private static $assets_path;
private static $dynamic;
private static $counter_cache;
/**
* This method sets the URL to your assets.
*
* @param string $path the path to the assets
*/
public static function set_assets_path(string $path): void
{
self::$assets_path = $path;
}
/**
* This method sets the URL to your assets.
......@@ -51,14 +63,13 @@ class Assets
*
* @return void
*/
static function set_assets_url($url)
public static function set_assets_url($url)
{
Assets::$assets_url = $url;
Assets::$counter_cache = NULL;
Assets::$dynamic = mb_strpos($url, '%d') !== FALSE;
self::$assets_url = $url;
self::$counter_cache = NULL;
self::$dynamic = mb_strpos($url, '%d') !== FALSE;
}
/**
* This class method is an accessor to the URL "prefix" for all things "asset"
* Prepend the return value of this method to the relative path of the wanted
......@@ -104,23 +115,31 @@ class Assets
*
* @return string the URL "prefix"
*/
static function url($to = '')
public static function url($to = '')
{
if (!Assets::$dynamic)
return Assets::$assets_url . $to;
if (!self::$dynamic) {
return self::$assets_url . $to;
}
# dynamic ASSETS_URL
return sprintf(Assets::$assets_url,
return sprintf(self::$assets_url,
$to == ''
? Assets::$counter_cache++ % Assets::NUMBER_OF_ALIASES
? self::$counter_cache++ % self::NUMBER_OF_ALIASES
# alternative implementation
# : hexdec(mb_substr(sha1($to),-1)) & 3)
: ord($to[1]) & (Assets::NUMBER_OF_ALIASES - 1))
: ord($to[1]) & (self::NUMBER_OF_ALIASES - 1))
. $to;
}
/**
* This class method is an accessor to the path "prefix" for all things "asset"
*/
public static function path($to = ''): string
{
return self::$assets_path . $to;
}
/**
* Returns an image tag using options as html attributes on the
* tag, but with these special cases:
......@@ -137,7 +156,7 @@ class Assets
* Do not use this to render icons. Use the more appropiate class
* Icon for this.
*/
static function img($source, $opt = [])
public static function img($source, $opt = [])
{
if (!$source) {
return '';
......@@ -145,9 +164,9 @@ class Assets
$size = $opt['size'] ?? null;
$opt = Assets::parse_attributes($opt);
$opt = self::parse_attributes($opt);
$opt['src'] = Assets::image_path($source);
$opt['src'] = self::image_path($source);
if (!isset($opt['alt'])) {
$opt['alt'] = ucfirst(current(explode('.', basename($opt['src']))));
......@@ -161,7 +180,7 @@ class Assets
unset($opt['size']);
}
return Assets::tag('img', $opt);
return self::tag('img', $opt);
}
......@@ -179,7 +198,7 @@ class Assets
* Do not use this to render icons. Use the more appropiate class
* Icon for this.
*/
static function input($source, $opt = [])
public static function input($source, $opt = [])
{
if (!$source) {
......@@ -190,9 +209,9 @@ class Assets
$size = $opt['size'];
$opt = Assets::parse_attributes($opt);
$opt = self::parse_attributes($opt);
$opt['src'] = Assets::image_path($source);
$opt['src'] = self::image_path($source);
$opt['type'] = 'image';
if (isset($size) && !isset($opt['width'])) {
......@@ -200,7 +219,7 @@ class Assets
unset($opt['size']);
}
return Assets::tag('input', $opt);
return self::tag('input', $opt);
}
/**
......@@ -223,9 +242,9 @@ class Assets
* scripts, as we would like to always generate the complete <image> oder
* <input> tag. Please use Assets::img or Assets::input instead.
*/
static function image_path($source, $respect_retina = false)
public static function image_path($source, $respect_retina = false)
{
$path = Assets::compute_public_path($source, 'images', 'png');
$path = self::compute_public_path($source, 'images', 'png');
return $path;
}
......@@ -242,12 +261,12 @@ class Assets
* <script src="/js/common.javascript"></script>
* <script src="/elsewhere/cools.js"></script>
*/
static function script($atLeastOneArgument)
public static function script($atLeastOneArgument)
{
$html = '';
foreach (func_get_args() as $source) {
$source = Assets::javascript_path($source);
$html .= Assets::content_tag('script', '',
$source = self::javascript_path($source);
$html .= self::content_tag('script', '',
['src' => $source]);
$html .= "\n";
}
......@@ -263,9 +282,9 @@ class Assets
*
* Assets::javascript_path('ajax') => /javascripts/ajax.js
*/
static function javascript_path($source)
public static function javascript_path($source)
{
return Assets::compute_public_path($source, 'javascripts', 'js');
return self::compute_public_path($source, 'javascripts', 'js');
}
......@@ -284,7 +303,7 @@ class Assets
* <link href="/stylesheets/random.styles" media="screen" rel="stylesheet">
* <link href="/css/stylish.css" media="screen" rel="stylesheet">
*/
static function stylesheet($atLeastOneArgument)
public static function stylesheet($atLeastOneArgument)
{
$sources = func_get_args();
$sourceOptions = (func_num_args() > 1 &&
......@@ -294,12 +313,12 @@ class Assets
$html = '';
foreach ($sources as $source) {
$source = Assets::stylesheet_path($source);
$source = self::stylesheet_path($source);
$opt = array_merge(['rel' => 'stylesheet',
'media' => 'screen',
'href' => $source],
$sourceOptions);
$html .= Assets::tag('link', $opt) . "\n";
$html .= self::tag('link', $opt) . "\n";
}
return $html;
......@@ -313,9 +332,9 @@ class Assets
*
* stylesheet_path('style') => /stylesheets/style.css
*/
static function stylesheet_path($source)
public static function stylesheet_path($source)
{
return Assets::compute_public_path($source, 'stylesheets', 'css');
return self::compute_public_path($source, 'stylesheets', 'css');
}
......@@ -341,7 +360,7 @@ class Assets
$source = "$dir/$source";
# consider asset host
$source = Assets::url(ltrim($source, '/'));
$source = self::url(ltrim($source, '/'));
}
return $source;
......@@ -373,15 +392,17 @@ class Assets
/**
* Helper function for content tags.
*
* @param name tag name
* @param content tag content
* @param options tag options
* @param string $name tag name
* @param string $content tag content
* @param array $options tag options
*
* @return type <description>
* @return string
*/
private static function content_tag($name, $content = '', $options = [])
{
if (!$name) return '';
if (!$name) {
return '';
}
return '<' . $name . ' ' . arrayToHtmlAttributes($options) . '>' .
$content .
'</' . $name . '>';
......
This diff is collapsed.
<?php
# Lifter010: TODO
/*
* Copyright (C) 2009 - Marcus Lunzenauer (mlunzena@uos)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
/**
* This class represents the avatar of a course.
*
* @package studip
* @subpackage lib
*
* @author Marcus Lunzenauer (mlunzena@uos)
* @copyright (c) Authors
* @license GPL2 or any later version
* @since 1.10
*/
class CourseAvatar extends Avatar
{
/**
* Returns an avatar object of the appropriate class.
*
* @param string the course's id
*
* @return mixed the course's avatar.
*/
static function getAvatar($id)
{
return new CourseAvatar($id);
}
/**
* Returns an avatar object for "nobody".
*
* @return mixed the course's avatar.
*/
static function getNobody()
{
return new CourseAvatar('nobody');
}
/**
* Returns the URL to the courses' avatars.
*
* @return string the URL to the avatars
*/
function getAvatarDirectoryUrl()
{
return $GLOBALS['DYNAMIC_CONTENT_URL'] . "/course";
}
/**
* Returns the file system path to the courses' avatars
*
* @return string the file system path to the avatars
*/
function getAvatarDirectoryPath()
{
return $GLOBALS['DYNAMIC_CONTENT_PATH'] . "/course";
}
public const AVATAR_TYPE = 'course';
/**
* Returns the CSS class to use for this avatar image.
......@@ -74,15 +18,16 @@ class CourseAvatar extends Avatar
*
* @return string CSS class to use for the avatar
*/
protected function getCssClass($size) {
return sprintf('course-avatar-%s course-%s', $size, $this->user_id);
protected function getCssClass($size)
{
return "course-avatar-{$size} course-{$this->user_id}";
}
/**
* Return the default title of the avatar.
* @return string the default title
*/
function getDefaultTitle()
public function getDefaultTitle()
{
return Seminar::GetInstance($this->user_id)->name;
}
......@@ -91,7 +36,8 @@ class CourseAvatar extends Avatar
* Return if avatar is visible to the current user.
* @return boolean: true if visible
*/
protected function checkAvatarVisibility() {
protected function checkAvatarVisibility()
{
//no special conditions for visibility of course-avatars yet
return true;
}
......
<?php
# Lifter010: TODO
/*
* Copyright (C) 2009 - Marcus Lunzenauer (mlunzena@uos)
* André Noack <noack@data-quest.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
/**
* This class represents the avatar of a institute.
*
* @package studip
* @subpackage lib
*
* @author André Noack <noack@data-quest.de>
* @author Marcus Lunzenauer <mlunzena@uos>
* @copyright (c) Authors
* @license GPL2 or any later version
* @since 1.10
*/
class InstituteAvatar extends CourseAvatar
{
public const AVATAR_TYPE = 'institute';
/**
* Returns an avatar object of the appropriate class.
*
* @param string the course's id
*
* @return mixed the course's avatar.
*/
static function getAvatar($id)
{
return new InstituteAvatar($id);
}
/**
* Returns an avatar object for "nobody".
*
* @return mixed the course's avatar.
*/
static function getNobody()
{
return new InstituteAvatar('nobody');
}
/**
* Returns the URL to the institute' avatars.
* Returns the CSS class to use for this avatar image.
*
* @return string the URL to the avatars
* @param string $size one of the constants Avatar::(NORMAL|MEDIUM|SMALL)
* @return string CSS class to use for the avatar
*/
function getAvatarDirectoryUrl()
protected function getCssClass($size)
{
return $GLOBALS['DYNAMIC_CONTENT_URL'] . "/institute";
}
/**
* Returns the file system path to the institute' avatars
*
* @return string the file system path to the avatars
*/
function getAvatarDirectoryPath()
{
return $GLOBALS['DYNAMIC_CONTENT_PATH'] . "/institute";
return "institute-avatar-{$size} institute-{$this->user_id}";
}
/**
* Return the default title of the avatar.
* @return string the default title
*/
function getDefaultTitle()
public function getDefaultTitle()
{
$institute = Institute::find($this->user_id);
return $institute
? $institute->name
: Avatar::NOBODY;
return $institute ? (string) $institute->name : self::NOBODY;
}
/**
* Return if avatar is visible to the current user.
* @return boolean: true if visible
*/
protected function checkAvatarVisibility() {
protected function checkAvatarVisibility()
{
//no special conditions for visibility of course-avatars yet
return true;
}
......
......@@ -109,7 +109,7 @@ class User extends SchemaProvider
'small' => $avatar->getURL(\Avatar::SMALL),
'medium' => $avatar->getURL(\Avatar::MEDIUM),
'normal' => $avatar->getURL(\Avatar::NORMAL),
'original' => $avatar->getURL(\Avatar::ORIGINAL),
'original' => $avatar->getURL(\Avatar::NORMAL),
],
];
}
......
......@@ -15,69 +15,31 @@
*/
class LicenseAvatar extends Avatar
{
/**
* Returns an avatar object of the appropriate class.
*
* @param string the course's id
*
* @return mixed the course's avatar.
*/
public static function getAvatar($id)
{
return new self($id);
}
/**
* Returns an avatar object for "nobody".
*
* @return mixed the course's avatar.
*/
public static function getNobody()
{
return new self('nobody');
}
/**
* Returns the URL to the courses' avatars.
*
* @return string the URL to the avatars
*/
public function getAvatarDirectoryUrl()
{
return $GLOBALS['DYNAMIC_CONTENT_URL'] . "/licenses";
}
/**
* Returns the file system path to the courses' avatars
*
* @return string the file system path to the avatars
*/
public function getAvatarDirectoryPath()
{
return $GLOBALS['DYNAMIC_CONTENT_PATH'] . "/licenses";
}
public const AVATAR_TYPE = 'licenses';
protected const CREATE_CHUNKED_FOLDERS = false;
public function getImageTag($size = Avatar::MEDIUM, $opt = [])
{
if (!$this->is_customized()) {
return "";
} else {
return parent::getImageTag($size, $opt);
}
return parent::getImageTag($size, $opt);
}
/**
* Returns the CSS class to use for this avatar image.
*
* @param string one of the constants Avatar::(NORMAL|MEDIUM|SMALL)
*
* @param string $size one of the constants Avatar::(NORMAL|MEDIUM|SMALL)
* @return string CSS class to use for the avatar
*/
protected function getCssClass($size)
{
return sprintf('license-avatar-%s license-%s', $size, $this->user_id);
return sprintf(
'license-avatar-%s license-%s',
$size,
$this->user_id
);
}
/**
......@@ -101,7 +63,7 @@ class LicenseAvatar extends Avatar
/**
* Return the dimension of a size
*
* @param string the dimension of a size
* @param string $size the dimension of a size
* @return array a tupel of integers [width, height]
*/
public static function getDimension($size)
......
<?php
# Lifter010: TODO
/*
* Copyright (C) 2009 - Marcus Lunzenauer (mlunzena@uos)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
/**
* This class represents the avatar of a course.
*
* @package studip
* @subpackage lib
*
* @author Marcus Lunzenauer (mlunzena@uos), Till Glöggler (tgloeggl@uos)
* @license GPL2 or any later version
* @copyright (c) Authors
* @since 1.10
*/
class StudygroupAvatar extends CourseAvatar
{
/**
* Returns an avatar object of the appropriate class.
*
* @param string the studygroup's id
*
* @return mixed the studygroup's avatar.
*/
static function getAvatar($course_id)
{
return new StudygroupAvatar($course_id);
}
/**
* Returns an avatar object for "nobody".
*
* @return mixed the studygroup's avatar.
* This constant holds the username and ID of the "studygroup" avatar.
*/
static function getNobody()
{
return new StudygroupAvatar('studygroup');
}
protected const NOBODY = 'studygroup';
}
......@@ -1161,10 +1161,7 @@ class User extends AuthUserMd5 implements Range, PrivacyObject
$new_avatar = Avatar::getAvatar($new_id);
if ($old_avatar->is_customized()) {
if (!$new_avatar->is_customized()) {
$avatar_file = $old_avatar->getFilename(Avatar::ORIGINAL);
if (!file_exists($avatar_file)) {
$avatar_file = $old_avatar->getFilename(Avatar::NORMAL);
}
$new_avatar->createFrom($avatar_file);
}
$old_avatar->reset();
......
......@@ -349,7 +349,6 @@ class Seminar_Auth
$this->auth["uname"] = Request::get('loginname'); // This provides access for "loginform.ihtml"
$this->auth["jscript"] = Request::get('resolution') != "";
$this->auth['devicePixelRatio'] = Request::float('device_pixel_ratio');
$check_auth = StudipAuthAbstract::CheckAuthentication(Request::get('loginname'), Request::get('password'));
......
public/assets/images/avatars/course/nobody_medium.webp

3.28 KiB

public/assets/images/avatars/course/nobody_normal.webp

8.52 KiB

public/assets/images/avatars/course/nobody_small.webp

892 B

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment