summaryrefslogtreecommitdiff
path: root/app/User/Avatar/LetterAvatarProvider.php
diff options
context:
space:
mode:
Diffstat (limited to 'app/User/Avatar/LetterAvatarProvider.php')
-rw-r--r--app/User/Avatar/LetterAvatarProvider.php169
1 files changed, 169 insertions, 0 deletions
diff --git a/app/User/Avatar/LetterAvatarProvider.php b/app/User/Avatar/LetterAvatarProvider.php
new file mode 100644
index 00000000..81c4586d
--- /dev/null
+++ b/app/User/Avatar/LetterAvatarProvider.php
@@ -0,0 +1,169 @@
+<?php
+
+namespace Kanboard\User\Avatar;
+
+use Kanboard\Core\Base;
+use Kanboard\Core\User\Avatar\AvatarProviderInterface;
+
+/**
+ * Letter Avatar Provider
+ *
+ * The color hash algorithm is backported from the Javascript library color-hash
+ * Source: https://github.com/zenozeng/color-hash
+ * Author: Zeno Zeng (MIT License)
+ *
+ * @package avatar
+ * @author Frederic Guillot
+ */
+class LetterAvatarProvider extends Base implements AvatarProviderInterface
+{
+ protected $lightness = array(0.35, 0.5, 0.65);
+ protected $saturation = array(0.35, 0.5, 0.65);
+
+ /**
+ * Render avatar html
+ *
+ * @access public
+ * @param array $user
+ * @param int $size
+ */
+ public function render(array $user, $size)
+ {
+ $initials = $this->helper->user->getInitials($user['name'] ?: $user['username']);
+ $rgb = $this->getBackgroundColor($initials);
+
+ return sprintf(
+ '<div class="avatar-letter" style="background-color: rgb(%d, %d, %d)" title="%s">%s</div>',
+ $rgb[0],
+ $rgb[1],
+ $rgb[2],
+ $this->helper->text->e($user['name'] ?: $user['username']),
+ $initials
+ );
+ }
+
+ /**
+ * Determine if the provider is active
+ *
+ * @access public
+ * @param array $user
+ * @return boolean
+ */
+ public function isActive(array $user)
+ {
+ return true;
+ }
+
+ /**
+ * Get background color based on a string
+ *
+ * @param string $str
+ * @return array
+ */
+ public function getBackgroundColor($str)
+ {
+ $hsl = $this->getHSL($str);
+ return $this->getRGB($hsl[0], $hsl[1], $hsl[2]);
+ }
+
+ /**
+ * Convert HSL to RGB
+ *
+ * @access protected
+ * @param integer $hue Hue ∈ [0, 360)
+ * @param integer $saturation Saturation ∈ [0, 1]
+ * @param integer $lightness Lightness ∈ [0, 1]
+ * @return array
+ */
+ protected function getRGB($hue, $saturation, $lightness)
+ {
+ $hue /= 360;
+ $q = $lightness < 0.5 ? $lightness * (1 + $saturation) : $lightness + $saturation - $lightness * $saturation;
+ $p = 2 * $lightness - $q;
+
+ return array_map(function ($color) use ($q, $p) {
+ if ($color < 0) {
+ $color++;
+ }
+
+ if ($color > 1) {
+ $color--;
+ }
+
+ if ($color < 1/6) {
+ $color = $p + ($q - $p) * 6 * $color;
+ } else if ($color < 0.5) {
+ $color = $q;
+ } else if ($color < 2/3) {
+ $color = $p + ($q - $p) * 6 * (2/3 - $color);
+ } else {
+ $color = $p;
+ }
+
+ return round($color * 255);
+ }, array($hue + 1/3, $hue, $hue - 1/3));
+ }
+
+ /**
+ * Returns the hash in [h, s, l].
+ * Note that H ∈ [0, 360); S ∈ [0, 1]; L ∈ [0, 1];
+ *
+ * @access protected
+ * @param string $str
+ * @return int[]
+ */
+ protected function getHSL($str)
+ {
+ $hash = $this->hash($str);
+ $hue = $hash % 359;
+
+ $hash = intval($hash / 360);
+ $saturation = $this->saturation[$hash % count($this->saturation)];
+
+ $hash = intval($hash / count($this->saturation));
+ $lightness = $this->lightness[$hash % count($this->lightness)];
+
+ return array($hue, $saturation, $lightness);
+ }
+
+ /**
+ * BKDR Hash (modified version)
+ *
+ * @access protected
+ * @param string $str
+ * @return integer
+ */
+ protected function hash($str)
+ {
+ $seed = 131;
+ $seed2 = 137;
+ $hash = 0;
+
+ // Make hash more sensitive for short string like 'a', 'b', 'c'
+ $str .= 'x';
+ $max = intval(9007199254740991 / $seed2);
+
+ for ($i = 0, $ilen = mb_strlen($str); $i < $ilen; $i++) {
+ if ($hash > $max) {
+ $hash = intval($hash / $seed2);
+ }
+
+ $hash = $hash * $seed + $this->getCharCode($str[$i]);
+ }
+
+ return $hash;
+ }
+
+ /**
+ * Backport of Javascript function charCodeAt()
+ *
+ * @access protected
+ * @param string $c
+ * @return integer
+ */
+ protected function getCharCode($c)
+ {
+ list(, $ord) = unpack('N', mb_convert_encoding($c, 'UCS-4BE', 'UTF-8'));
+ return $ord;
+ }
+}