Added generic avatar using the user's initials
authorAlexander Ebert <ebert@woltlab.com>
Fri, 17 Mar 2017 13:32:31 +0000 (14:32 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 17 Mar 2017 13:32:39 +0000 (14:32 +0100)
See #2213

com.woltlab.wcf/option.xml
constants.php
wcfsetup/install/files/images/avatars/generateAvatar.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/user/UserProfile.class.php
wcfsetup/install/files/lib/data/user/avatar/DefaultAvatar.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 87f1686938d55c6d181058d864134f25ba7660ca..956d83f72f4b7d9ff5549ef54a40e90ab5318d3d 100644 (file)
@@ -1173,6 +1173,13 @@ Pinterest</defaultvalue>
                        <!-- /user.3rdPartyAuth -->
                        
                        <!-- user.avatar -->
+                       <option name="avatar_default_type">
+                               <categoryname>user.avatar</categoryname>
+                               <optiontype>select</optiontype>
+                               <defaultvalue>initials</defaultvalue>
+                               <selectoptions>initials:wcf.acp.option.avatar_default_type.initials
+silhouette:wcf.acp.option.avatar_default_type.silhouette</selectoptions>
+                       </option>
                        <option name="gravatar_default_type">
                                <categoryname>user.avatar</categoryname>
                                <optiontype>select</optiontype>
index baa0978c23ec587a7086a5d79505e2fe66fc6691..40e64a874e90ee44b1abbf79f7b9565dd73462d1 100644 (file)
@@ -218,3 +218,4 @@ define('ARTICLE_SORT_ORDER', 'DESC');
 define('USE_PAGE_TITLE_ON_LANDING_PAGE', 1);
 define('OG_IMAGE', '');
 define('HEAD_CODE', '');
+define('AVATAR_DEFAULT_TYPE', 'initials');
diff --git a/wcfsetup/install/files/images/avatars/generateAvatar.php b/wcfsetup/install/files/images/avatars/generateAvatar.php
new file mode 100644 (file)
index 0000000..dd43779
--- /dev/null
@@ -0,0 +1,4 @@
+<?php
+if (empty($_GET['username'])) {
+       
+}
\ No newline at end of file
index b67084bb38f1e001b9fd3f64b786919f974ccfc7..1e2d9fc868a05e3397c2943d8c1d377c28be3553 100644 (file)
@@ -269,7 +269,7 @@ class UserProfile extends DatabaseObjectDecorator implements ITitledLinkObject {
                        
                        // use default avatar
                        if ($this->avatar === null) {
-                               $this->avatar = new DefaultAvatar();
+                               $this->avatar = new DefaultAvatar($this->userID ? $this->username : '');
                        }
                }
                
index 6b5eaac2338475c136a25f536a5a61b02b72ff8c..9acd6c30e480bb934f85673b5395e530d4316afe 100644 (file)
@@ -18,11 +18,57 @@ class DefaultAvatar implements IUserAvatar {
         */
        public $size = UserAvatar::AVATAR_SIZE;
        
+       /**
+        * content of the `src` attribute
+        * @var string
+        */
+       protected $src = '';
+       
+       /**
+        * DefaultAvatar constructor.
+        * 
+        * @param       string          $username       username for use with the 'initials' avatar type
+        */
+       public function __construct($username = '') {
+               if (defined('AVATAR_DEFAULT_TYPE') && AVATAR_DEFAULT_TYPE === 'initials' && !empty($username)) {
+                       $words = explode(' ', $username);
+                       $count = count($words);
+                       if ($count > 1) {
+                               // combine the first character of each the first and the last word
+                               $text = mb_strtoupper(mb_substr($words[0], 0, 1) . mb_substr($words[$count - 1], 0, 1));
+                       }
+                       else {
+                               // use the first two characters
+                               $text = mb_strtoupper(mb_substr($username, 0, 2));
+                       }
+                       
+                       $backgroundColor = substr(sha1($username), 0, 6);
+                       
+                       $perceptiveLuminance = $this->getPerceptiveLuminance(
+                               hexdec($backgroundColor[0] . $backgroundColor[1]),
+                               hexdec($backgroundColor[2] . $backgroundColor[3]),
+                               hexdec($backgroundColor[4] . $backgroundColor[5])
+                       );
+                       
+                       $textColor = ($perceptiveLuminance < 0.3) ? '000' : 'fff';
+                       
+                       // the <path> is basically a shorter version of a <rect>
+                       $svg = <<<SVG
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#{$backgroundColor}" d="M0 0h16v16H0z"/><text x="8" y="8" fill="#{$textColor}" text-anchor="middle" alignment-baseline="central" font-family="Arial" font-size="7">{$text}</text></svg>
+SVG;
+                       
+                       $this->src = "data:image/svg+xml;base64," . base64_encode($svg);
+               }
+               else {
+                       $this->src = WCF::getPath().'images/avatars/avatar-default.svg';
+               }
+       }
+       
        /**
         * @inheritDoc
         */
        public function getURL($size = null) {
-               return WCF::getPath().'images/avatars/avatar-default.svg';
+               return $this->src;
        }
        
        /**
@@ -61,4 +107,16 @@ class DefaultAvatar implements IUserAvatar {
        public function getCropImageTag($size = null) {
                return '';
        }
+       
+       /**
+        * Returns the perceived luminance of the given color.
+        * 
+        * @param       integer         $r
+        * @param       integer         $g
+        * @param       integer         $b
+        * @return      float           luminance expressed in a float in the range of 0 and 1
+        */
+       protected function getPerceptiveLuminance($r, $g, $b) {
+               return 1 - (0.299 * $r + 0.587 * $g + 0.114 * $b) / 255;
+       }
 }
index 8961afabc70d3baa5bc5370fb0fb96b41e604624..02a105bc19ab5009ef27276c6943ff2b6a3e4da0 100644 (file)
@@ -1255,6 +1255,9 @@ GmbH=Gesellschaft mit beschränkter Haftung]]></item>
                <item name="wcf.acp.option.use_page_title_on_landing_page"><![CDATA[Titel der Seite als Überschrift auf Startseite anzeigen]]></item>
                <item name="wcf.acp.option.head_code"><![CDATA[Head-Code]]></item>
                <item name="wcf.acp.option.head_code.description"><![CDATA[Der hier angegebene Code wird im Head-Tag jeder Seite ausgegeben. Der Head-Code eignet sich z.B. sehr gut für die Einbindung von zusätzlichen Meta-Tags.]]></item>
+               <item name="wcf.acp.option.avatar_default_type"><![CDATA[Standard Avatar-Typ]]></item>
+               <item name="wcf.acp.option.avatar_default_type.initials"><![CDATA[Initialen]]></item>
+               <item name="wcf.acp.option.avatar_default_type.silhouette"><![CDATA[Silhouette]]></item>
        </category>
        
        <category name="wcf.acp.package">
index 507f92b50e43ab148f6dadd18fa2803c961b79f2..d5aad08461104d77c89f94e2ff0b4c0efbcca78d 100644 (file)
@@ -1258,6 +1258,9 @@ Examples for medium ID detection:
                <item name="wcf.acp.option.use_page_title_on_landing_page"><![CDATA[Use page title on landing page]]></item>
                <item name="wcf.acp.option.head_code"><![CDATA[Head Code]]></item>
                <item name="wcf.acp.option.head_code.description"><![CDATA[The entered code will be appended to the head tag of your site. You can use it to add additional meta tags.]]></item>
+               <item name="wcf.acp.option.avatar_default_type"><![CDATA[Default Avatar Type]]></item>
+               <item name="wcf.acp.option.avatar_default_type.initials"><![CDATA[Initials]]></item>
+               <item name="wcf.acp.option.avatar_default_type.silhouette"><![CDATA[Silhouette]]></item>
        </category>
        
        <category name="wcf.acp.package">