1
0
Fork 0
mirror of https://github.com/Findus23/plugin-ProfileAvatar.git synced 2024-09-19 15:23:45 +02:00

initial commit

This commit is contained in:
Lukas Winkler 2020-05-20 10:41:04 +02:00
commit 561fd3f134
Signed by: lukas
GPG key ID: 54DE4D798D244853
228 changed files with 2810 additions and 0 deletions

5
CHANGELOG.md Normal file
View file

@ -0,0 +1,5 @@
## Changelog
### 0.1.0
initial release

23
Controller.php Normal file
View file

@ -0,0 +1,23 @@
<?php
namespace Piwik\Plugins\ProfileAvatar;
use Piwik\Common;
use Piwik\Piwik;
class Controller extends \Piwik\Plugin\Controller
{
/**
* Get profile Avatar
*/
public function getProfileAvatar(): void
{
Piwik::checkUserHasSomeViewAccess();
$hash = Common::getRequestVar('hash', "", 'string');
$settings = new UserSettings();
$chosenGenerator = $settings->avatarType->getValue();
$generator = GeneratorCollection::getGeneratorClasses($chosenGenerator, $hash);
$generator->print();
exit();
}
}

45
GeneratorCollection.php Normal file
View file

@ -0,0 +1,45 @@
<?php
namespace Piwik\Plugins\ProfileAvatar;
use Piwik\Plugins\ProfileAvatar\Generators\AvatarBase;
use Piwik\Plugins\ProfileAvatar\Generators\BirdAvatar;
use Piwik\Plugins\ProfileAvatar\Generators\Blockies;
use Piwik\Plugins\ProfileAvatar\Generators\CatAvatar;
use Piwik\Plugins\ProfileAvatar\Generators\Identicon;
use Piwik\Plugins\ProfileAvatar\Generators\MonsterID;
class GeneratorCollection
{
static public $generatorNames = [
"CatAvatar" => "Cat Avatar",
"BirdAvatar" => "Bird Avatar",
"MonsterID" => "MonsterID",
"Identicon" => "Identicon.js",
"Blockies" => "Blockies"
];
static public function getGeneratorClasses(string $name, string $hash): AvatarBase
{
switch ($name) {
case "CatAvatar":
return new CatAvatar($hash);
break;
case "BirdAvatar";
return new BirdAvatar($hash);
break;
case "MonsterID":
return new MonsterID($hash);
break;
case "Identicon":
return new Identicon($hash);
break;
case "Blockies":
return new Blockies($hash);
break;
default:
throw new \Exception("invalid Generator");
}
}
}

13
Generators/AvatarBase.php Normal file
View file

@ -0,0 +1,13 @@
<?php
namespace Piwik\Plugins\ProfileAvatar\Generators;
abstract class AvatarBase
{
abstract function build();
abstract function print();
abstract function asDataURL();
}

23
Generators/BirdAvatar.php Normal file
View file

@ -0,0 +1,23 @@
<?php
namespace Piwik\Plugins\ProfileAvatar\Generators;
/**
* based on cat-avatar-generator by David Revoy
* Artwork license: https://creativecommons.org/licenses/by/4.0/
*/
class BirdAvatar extends MonsterIDBase
{
public $size = 240;
protected $path = "CatAvatar/Bird";
protected $partTemplate = [
'tail' => [1, 9],
'hoop' => [1, 9],
'body' => [1, 9],
'wing' => [1, 9],
'eyes' => [1, 9],
'bec' => [1, 9],
'accessorie' => [1, 20]
];
}

66
Generators/Blockies.php Normal file
View file

@ -0,0 +1,66 @@
<?php
namespace Piwik\Plugins\ProfileAvatar\Generators;
/**
* PHP port of Blockies
* https://github.com/download13/blockies
* by Erin Dachtler, Alex Van de Sande
* MIT license / WTFPL license
*/
class Blockies extends PixelBased
{
protected $size = 100;
protected $singleColor = FALSE;
private $rowscols = 10;
protected function createPatterns(): void
{
srand(hexdec(substr($this->seed, -10)));
$colors = [$this->createColor(), $this->createColor(), $this->createColor()];
$cell = $this->size / $this->rowscols;
for ($j = 0; $j < $this->rowscols; $j++) {
$values = $this->createRow();
$values = array_merge($values, array_reverse($values));
$i = 0;
foreach ($values as $value) {
$this->rectangles[] = [
"x" => $i * $cell,
"y" => $j * $cell,
"w" => $cell,
"h" => $cell,
"color" => $colors[$value]
];
$i += 1;
}
}
srand();
}
private function createColor(): array
{
$h = rand(0, 360) / 360;
$s = rand(40, 100) / 100;
$l = ($this->rand() + $this->rand() + $this->rand() + $this->rand()) * 25 / 100;
return [$h, $s, $l];
}
private function rand(): float
{
return mt_rand() / mt_getrandmax();
}
private function createRow(): array
{
for ($i = 0; $i < $this->rowscols / 2; $i++) {
$row[] = floor($this->rand() * 2.3);
}
return $row;
}
protected function getForegroundColor(): void
{
return;
}
}

18
Generators/CatAvatar.php Normal file
View file

@ -0,0 +1,18 @@
<?php
namespace Piwik\Plugins\ProfileAvatar\Generators;
class CatAvatar extends MonsterIDBase
{
public $size = 240;
protected $path = "CatAvatar/Cat";
protected $partTemplate = [
'body' => [1, 15],
'fur' => [1, 10],
'eyes' => [1, 15],
'mouth' => [1, 10],
'accessorie' => [1, 20]
];
}

75
Generators/Identicon.php Normal file
View file

@ -0,0 +1,75 @@
<?php
namespace Piwik\Plugins\ProfileAvatar\Generators;
/**
* PHP port of https://github.com/stewartlord/identicon.js
* Copyright (c) 2018, Stewart Lord
* BSD 2-Clause
*/
class Identicon extends PixelBased
{
private $margin = 0.08;
private $saturation = 0.7;
private $lightness = 0.5;
protected function createPatterns(): void
{
$baseMargin = floor($this->size * $this->margin);
$cell = floor(($this->size - ($baseMargin * 2)) / 5);
$margin = floor(($this->size - $cell * 5) / 2);
for ($i = 0; $i < 15; $i++) {
$color = hexdec($this->seed[$i]) % 2 ? $this->backgroundColor : $this->getForegroundColor();
if ($i < 5) {
$this->rectangles[] = [
"x" => 2 * $cell + $margin,
"y" => $i * $cell + $margin,
"w" => $cell,
"h" => $cell,
"color" => $color
];
} elseif ($i < 10) {
$this->rectangles[] = [
"x" => 1 * $cell + $margin,
"y" => ($i - 5) * $cell + $margin,
"w" => $cell,
"h" => $cell,
"color" => $color
];
$this->rectangles[] = [
"x" => 3 * $cell + $margin,
"y" => ($i - 5) * $cell + $margin,
"w" => $cell,
"h" => $cell,
"color" => $color
];
} elseif ($i < 15) {
$this->rectangles[] = [
"x" => 0 * $cell + $margin,
"y" => ($i - 10) * $cell + $margin,
"w" => $cell,
"h" => $cell,
"color" => $color
];
$this->rectangles[] = [
"x" => 4 * $cell + $margin,
"y" => ($i - 10) * $cell + $margin,
"w" => $cell,
"h" => $cell,
"color" => $color
];
}
}
}
protected function getForegroundColor(): array
{
$hue = hexdec(substr($this->seed, -7)) / 0xfffffff;
return [$hue * 360, $this->saturation, $this->lightness];
}
}

30
Generators/MonsterID.php Normal file
View file

@ -0,0 +1,30 @@
<?php
namespace Piwik\Plugins\ProfileAvatar\Generators;
/**
* Artwork by Andreas Gohr, code based on work by Andreas Gohr
* https://github.com/splitbrain/monsterID
* licenced under MIT license
*/
class MonsterID extends MonsterIDBase
{
protected $path = "monsterID";
protected $partTemplate = [
'legs' => [1, 5],
'hair' => [1, 5],
'arms' => [1, 5],
'body' => [1, 15],
'eyes' => [1, 15],
'mouth' => [1, 10],
];
protected function applyPartToImage($part, $number): void
{
parent::applyPartToImage($part, $number);
if ($part == 'body') {
$color = imagecolorallocate($this->monster, rand(20, 235), rand(20, 235), rand(20, 235));
imagefill($this->monster, 60, 60, $color);
}
}
}

View file

@ -0,0 +1,116 @@
<?php
namespace Piwik\Plugins\ProfileAvatar\Generators;
/**
* based on code by Andreas Gohr and Anton Smirnov
* both under MIT license
* https://github.com/splitbrain/monsterID
* https://github.com/arokettu/monsterid
*/
class MonsterIDBase extends AvatarBase
{
public $size = 120;
protected $seed;
protected $monster;
protected $path;
protected $partTemplate;
public function __construct($seed = null)
{
$this->seed = hexdec(substr($seed, -10));
}
public function __destruct()
{
if ($this->monster) {
imagedestroy($this->monster);
}
}
public function asDataUrl(): string
{
$this->build();
$output = $this->toBuffer();
return $this->dataURL($output);
}
public function build(): void
{
$this->createImage();
srand($this->seed);
$parts = $this->generateRandomParts();
foreach ($parts as $part => $number) {
$this->applyPartToImage($part, $number);
}
srand();
}
private function createImage(): void
{
// create background
$this->monster = imagecreatetruecolor($this->size, $this->size);
if (!$this->monster) {
throw new \Exception('GD image create failed');
}
$white = imagecolorallocate($this->monster, 255, 255, 255);
imagefill($this->monster, 0, 0, $white);
}
private function generateRandomParts(): array
{
// throw the dice for body parts
foreach ($this->partTemplate as $name => $template) {
list($min, $max) = $template;
$parts[$name] = rand($min, $max);
}
return $parts;
}
protected function applyPartToImage($part, $number): void
{
$file = implode(DIRECTORY_SEPARATOR, array(self::getPartsPath(), "{$part}_{$number}.png"));
$partImage = imagecreatefrompng($file);
if (!$partImage) {
throw new \Exception('Failed to load ' . $file);
}
imagesavealpha($partImage, true);
imagecopy($this->monster, $partImage, 0, 0, 0, 0, $this->size, $this->size);
imagedestroy($partImage);
}
private function getPartsPath(): string
{
return realpath(__DIR__ . '/../images/' . $this->path);
}
public function toBuffer(): string
{
ob_start();
imagepng($this->monster, null, 9);
$buffer = ob_get_clean();
imagedestroy($this->monster);
return $buffer;
}
private function dataURL(string $output): string
{
$base64 = base64_encode($output);
return "data:image/png;base64," . $base64;
}
public function print(): void
{
$this->build();
header('Content-type: image/png');
imagepng($this->monster, null, 9);
imagedestroy($this->monster);
}
}

92
Generators/PixelBased.php Normal file
View file

@ -0,0 +1,92 @@
<?php
namespace Piwik\Plugins\ProfileAvatar\Generators;
/**
* Based on ported code by Erin Dachtler and Stewart Lord
* Copyright (c) 2018, Stewart Lord
* BSD 2-Clause
* MIT license / WTFPL
* https://github.com/stewartlord/identicon.js
* https://github.com/download13/blockies
*/
abstract class PixelBased extends AvatarBase
{
protected $seed;
protected $rectangles = [];
protected $backgroundColor = [0, 0, 0.94];
protected $size = 64;
protected $singleColor = TRUE;
public function __construct($seed = null)
{
$this->seed = $seed;
}
public function asDataURL()
{
$svg = $this->build();
return "data:image/svg+xml," . rawurlencode($svg);
}
public function build()
{
$this->createPatterns();
return $this->createSVG();
}
abstract protected function createPatterns();
protected function createSVG()
{
$bg = $this->toSVGColor($this->backgroundColor);
$stroke = $this->size * 0.005;
$svg = "<svg xmlns='http://www.w3.org/2000/svg' width='$this->size' height='$this->size' style='background: $bg'>";
if ($this->singleColor) {
$fg = $this->toSVGColor($this->getForegroundColor());
$svg .= "<g style='fill: $fg; stroke: $fg' stroke-width='$stroke'>";
} else {
$svg .= "<g stroke-width='$stroke'>";
}
foreach ($this->rectangles as $rectangle) {
$x = $rectangle["x"];
$y = $rectangle["y"];
$w = $rectangle["w"];
$h = $rectangle["h"];
if ($rectangle["color"] == $this->backgroundColor) {
continue;
}
if ($this->singleColor) {
$svg .= "<rect x='$x' y='$y' width='$w' height='$h' />\n";
} else {
$color = $this->toSVGColor($rectangle["color"]);
$svg .= "<rect x='$x' y='$y' width='$w' height='$h' style='fill: $color; stroke: $color' />\n";
}
}
$svg .= "</g></svg>";
return $svg;
}
protected static function toSVGColor(array $color)
{
list($h, $s, $l) = $color;
$h *= 360;
$s *= 100;
$l *= 100;
$h=round($h);
$s=round($s);
$l=round($l);
return "hsl($h, $s%, $l%)";
}
abstract protected function getForegroundColor();
public function print()
{
header('Content-type:image/svg+xml;charset=utf-8');
echo $this->build();
}
}

31
ProfileAvatar.php Normal file
View file

@ -0,0 +1,31 @@
<?php
namespace Piwik\Plugins\ProfileAvatar;
use Piwik\Plugin;
class ProfileAvatar extends Plugin
{
public function registerEvents()
{
return [
'Live.getExtraVisitorDetails' => 'getExtraVisitorDetails'
];
}
public function getExtraVisitorDetails(&$result): void
{
$settings = new UserSettings();
$visitorID = $result["visitorId"];
$hash = hash("sha256", $visitorID);
if ($settings->dataURLs->getValue()) {
$chosenGenerator = $settings->avatarType->getValue();
$generator = GeneratorCollection::getGeneratorClasses($chosenGenerator,$hash);
$result['visitorAvatar'] = $generator->asDataUrl();
} else {
$result['visitorAvatar'] = "?module=ProfileAvatar&action=getProfileAvatar&hash=$hash";
}
}
}

15
README.md Normal file
View file

@ -0,0 +1,15 @@
# Matomo ProfileAvatar Plugin
## Description
Are you tired of always seeing the same placeholder profile picture in the Vistitor Profile?
This plugin creates randomly generated user avatars based on the visitorID inspired by classical identicons:
- Cat Avatar (based on [cat-avatar-generator](https://framagit.org/Deevad/cat-avatar-generator/) by [David Revoy](https://www.davidrevoy.com/))
- Bird Avatar (the same with birds)
- MonsterID (based on [MonsterID](https://www.splitbrain.org/projects/monsterid) by Andreas Gohr)
- Identicon (based on [indenticon.js](https://github.com/stewartlord/identicon.js) by Stewart Lord)
- Blockies (based on [blockies](https://github.com/download13/blockies) by Erin Dachtler)
In the Personal Settings every use can choose which avatar type they want to see.

50
UserSettings.php Normal file
View file

@ -0,0 +1,50 @@
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\ProfileAvatar;
use Piwik\Piwik;
use Piwik\Settings\FieldConfig;
use Piwik\Settings\Setting;
class UserSettings extends \Piwik\Settings\Plugin\UserSettings
{
/** @var Setting */
public $avatarType;
/** @var Setting */
public $dataURLs;
protected $title = "Visitor Profile Avatar";
protected function init()
{
$this->avatarType = $this->createAvatarTypeSetting();
$this->dataURLs = $this->createDataURLsSetting();
}
private function createAvatarTypeSetting():Setting
{
return $this->makeSetting("avatarType", "CatAvatar", FieldConfig::TYPE_STRING, function (FieldConfig $field) {
$field->title = Piwik::translate('ProfileAvatar_AvatarTypeTitle');;
$field->uiControl = FieldConfig::UI_CONTROL_RADIO;
$field->description = Piwik::translate('ProfileAvatar_AvatarTypeDescription');
$field->availableValues = GeneratorCollection::$generatorNames;
});
}
private function createDataURLsSetting():Setting
{
return $this->makeSetting("dataURLs", FALSE, FieldConfig::TYPE_BOOL, function (FieldConfig $field) {
$field->title = Piwik::translate('ProfileAvatar_DataURLsTitle');
$field->uiControl = FieldConfig::UI_CONTROL_CHECKBOX;
$field->description = Piwik::translate('ProfileAvatar_DataURLsDescription');
});
}
}

2
config/config.php Normal file
View file

@ -0,0 +1,2 @@
<?php
return array();

2
config/tracker.php Normal file
View file

@ -0,0 +1,2 @@
<?php
return array();

View file

@ -0,0 +1,10 @@
# Cat-Avatar-Generator by David Revoy
https://framagit.org/Deevad/cat-avatar-generator/
### License
Artwork by David Revoy
https://creativecommons.org/licenses/by/4.0/
https://www.davidrevoy.com/article720/bird-avatar-generator

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,10 @@
# Cat-Avatar-Generator by David Revoy
https://framagit.org/Deevad/cat-avatar-generator/
### License
Artwork by David Revoy
https://creativecommons.org/licenses/by/4.0/
https://www.davidrevoy.com/article591/cat-avatar-generator

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Some files were not shown because too many files have changed in this diff Show more