diff --git a/assets/default/css/theme.css b/assets/default/css/theme.css index abe2829c1eacbb7e06454311c51046987eef5109..4b880e8c3ceaf57e5adb2575e835a0a2a9ff2872 100644 --- a/assets/default/css/theme.css +++ b/assets/default/css/theme.css @@ -1067,6 +1067,10 @@ table.custom-data .headline { img.avatar { border-radius: inherit; } +.avatar > img.avatar { + width: 100%; + height: 100%; +} .thread-entry .header { padding: 8px 0.9em; border: 1px solid #ccc; diff --git a/avatar.php b/avatar.php new file mode 100644 index 0000000000000000000000000000000000000000..d0dced7de27d45d72642320a112d52c2de2f3ada --- /dev/null +++ b/avatar.php @@ -0,0 +1,36 @@ +<?php +/********************************************************************* + file.php + + File download facilitator for clients + + Peter Rotich <peter@osticket.com> + Jared Hancock <jared@osticket.com> + Copyright (c) 2006-2014 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ +require('client.inc.php'); + +if (!isset($_GET['uid']) || !isset($_GET['mode'])) + Http::response(400, '`uid` and `mode` parameters are required'); + +require_once INCLUDE_DIR . 'class.avatar.php'; + +try { + $ra = new RandomAvatar($_GET['mode']); + $avatar = $ra->makeAvatar($_GET['uid']); + + Http::response(200, false, 'image/png', false); + Http::cacheable($_GET['uid'], false, 86400); + imagepng($avatar, null, 1); + imagedestroy($avatar); + exit; +} +catch (InvalidArgumentException $ex) { + Http::response(422, 'No such avatar image set'); +} diff --git a/include/class.avatar.php b/include/class.avatar.php index 7adefad798c989e40d268eebf376cf1b18b55e5c..d46a066e224f1b99b3cf353007fd8c82dd5cd897 100644 --- a/include/class.avatar.php +++ b/include/class.avatar.php @@ -23,12 +23,25 @@ abstract class Avatar { } abstract function getUrl($size); - abstract function __toString(); + + function getImageTag($size=null) { + return '<img class="avatar" alt="'.__('Avatar').'" src="'.$this->getUrl($size).'" />'; + } + + function __toString() { + return $this->getImageTag(); + } } abstract class AvatarSource { static $id; static $name; + var $mode; + + function __construct($mode=null) { + if (isset($mode)) + $this->mode = $mode; + } function getName() { return __(static::$name); @@ -124,12 +137,80 @@ extends Avatar { $url .= "?s=$size&d={$this->d}"; return $url; } +} - function getImageTag($size=null) { - return '<img class="avatar" alt="'.__('Avatar').'" src="'.$this->getUrl($size).'" />'; +class LocalAvatarSource +extends AvatarSource { + static $id = 'local'; + static $name = /* @trans */ 'Built-In'; + var $mode = 'ateam'; + + static function getModes() { + return array( + 'ateam' => __("Oscar's A-Team"), + ); } - function __toString() { - return $this->getImageTag(); + function getAvatar($user) { + return new LocalAvatar($user, $this->mode); + } +} +AvatarSource::register('LocalAvatarSource'); + +class LocalAvatar +extends Avatar { + var $mode; + + function __construct($user, $mode) { + parent::__construct($user); + $this->mode = $mode; + } + + function getUrl($size) { + if (false && ($file = $this->user->getAvatarFile())) + return $file->getDownloadUrl(); + + // Generate a random string of 0-6 chars for the avatar signature + $uid = md5(strtolower($this->user->getEmail())); + return 'avatar.php?'.Http::build_query(array('uid'=>$uid, + 'mode' => $this->mode)); + } + + static function serveRandomAvatar($uid, $mode) { + } +} + +class RandomAvatar { + var $mode; + + static $sprites = array( + 'ateam' => array( + 'file' => 'images/avatar-sprite-ateam.png', + 'grid' => 96, + ), + ); + + function __construct($mode) { + $this->mode = $mode; + } + + function makeAvatar($uid) { + $sprite = self::$sprites[$this->mode]; + $source = imagecreatefrompng(ROOT_DIR . $sprite['file']); + $grid = $sprite['grid']; + $avatar = imagecreatetruecolor($grid, $grid); + $width = imagesx($source) / $grid; + $height = imagesy($source) / $grid; + + // Start with a white matte + $white = imagecolorallocate($avatar, 255, 255, 255); + imagefill($avatar, 0, 0, $white); + + for ($i=0, $k=$height-1; $i<$k; $i++) { + $idx = hexdec($uid[$i]) % $width; + imagecopy($avatar, $source, 0, 0, $idx*$grid, $i*$grid, $grid, $grid); + } + + return $avatar; } } diff --git a/include/class.http.php b/include/class.http.php index 5e14ee932bb2acbd013b348083a4176a13fc42cb..2fd09a8d70f7aa37041bd8b57597216024cc5cc7 100644 --- a/include/class.http.php +++ b/include/class.http.php @@ -37,10 +37,15 @@ class Http { header('HTTP/1.1 '.Http::header_code_verbose($code)); header('Status: '.Http::header_code_verbose($code)."\r\n"); header("Connection: Close\r\n"); - header("Content-Type: $contentType; charset=$charset\r\n"); - header('Content-Length: '.strlen($content)."\r\n\r\n"); - print $content; - exit; + $ct = "Content-Type: $contentType"; + if ($charset) + $ct .= "; charset=$charset"; + header($ct); + if ($content) { + header('Content-Length: '.strlen($content)."\r\n\r\n"); + print $content; + exit; + } } function redirect($url,$delay=0,$msg='') {