Profile picture frontend + backend
This commit is contained in:
57
Core/API/Parameter/FloatType.class.php
Normal file
57
Core/API/Parameter/FloatType.class.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Core\API\Parameter;
|
||||
|
||||
class FloatType extends Parameter {
|
||||
|
||||
public float $minValue;
|
||||
public float $maxValue;
|
||||
public function __construct(string $name, float $minValue = PHP_FLOAT_MIN, float $maxValue = PHP_FLOAT_MAX,
|
||||
bool $optional = FALSE, ?float $defaultValue = NULL, ?array $choices = NULL) {
|
||||
$this->minValue = $minValue;
|
||||
$this->maxValue = $maxValue;
|
||||
parent::__construct($name, Parameter::TYPE_FLOAT, $optional, $defaultValue, $choices);
|
||||
}
|
||||
|
||||
public function parseParam($value): bool {
|
||||
if (!parent::parseParam($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->value = $value;
|
||||
if ($this->value < $this->minValue || $this->value > $this->maxValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getTypeName(): string {
|
||||
$typeName = parent::getTypeName();
|
||||
$hasMin = $this->minValue > PHP_FLOAT_MIN;
|
||||
$hasMax = $this->maxValue < PHP_FLOAT_MAX;
|
||||
|
||||
if ($hasMin || $hasMax) {
|
||||
if ($hasMin && $hasMax) {
|
||||
$typeName .= " ($this->minValue - $this->maxValue)";
|
||||
} else if ($hasMin) {
|
||||
$typeName .= " (> $this->minValue)";
|
||||
} else if ($hasMax) {
|
||||
$typeName .= " (< $this->maxValue)";
|
||||
}
|
||||
}
|
||||
|
||||
return $typeName;
|
||||
}
|
||||
|
||||
public function toString(): string {
|
||||
$typeName = $this->getTypeName();
|
||||
$str = "$typeName $this->name";
|
||||
$defaultValue = (is_null($this->value) ? 'NULL' : $this->value);
|
||||
if ($this->optional) {
|
||||
$str = "[$str = $defaultValue]";
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
@@ -121,6 +121,8 @@ namespace Core\API {
|
||||
namespace Core\API\User {
|
||||
|
||||
use Core\API\Parameter\ArrayType;
|
||||
use Core\API\Parameter\FloatType;
|
||||
use Core\API\Parameter\IntegerType;
|
||||
use Core\API\Parameter\Parameter;
|
||||
use Core\API\Parameter\StringType;
|
||||
use Core\API\Template\Render;
|
||||
@@ -1311,10 +1313,15 @@ namespace Core\API\User {
|
||||
}
|
||||
|
||||
class UploadPicture extends UserAPI {
|
||||
|
||||
const MIN_SIZE = 150;
|
||||
const MAX_SIZE = 800;
|
||||
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
// TODO: we should optimize the process here, we need an offset and size parameter to get a quadratic crop of the uploaded image
|
||||
parent::__construct($context, $externalCall, [
|
||||
"scale" => new Parameter("scale", Parameter::TYPE_FLOAT, true, NULL),
|
||||
"x" => new FloatType("x", 0, PHP_FLOAT_MAX, true, NULL),
|
||||
"y" => new FloatType("y", 0, PHP_FLOAT_MAX, true, NULL),
|
||||
"size" => new FloatType("size", self::MIN_SIZE, self::MAX_SIZE, true, NULL),
|
||||
]);
|
||||
$this->loginRequired = true;
|
||||
$this->forbidMethod("GET");
|
||||
@@ -1325,64 +1332,31 @@ namespace Core\API\User {
|
||||
*/
|
||||
protected function onTransform(\Imagick $im, $uploadDir): bool|string {
|
||||
|
||||
$minSize = 75;
|
||||
$maxSize = 500;
|
||||
|
||||
$width = $im->getImageWidth();
|
||||
$height = $im->getImageHeight();
|
||||
$doResize = false;
|
||||
$maxPossibleSize = min($width, $height);
|
||||
|
||||
if ($width < $minSize || $height < $minSize) {
|
||||
if ($width < $height) {
|
||||
$newWidth = $minSize;
|
||||
$newHeight = intval(($minSize / $width) * $height);
|
||||
} else {
|
||||
$newHeight = $minSize;
|
||||
$newWidth = intval(($minSize / $height) * $width);
|
||||
}
|
||||
$cropX = $this->getParam("x");
|
||||
$cropY = $this->getParam("y");
|
||||
$cropSize = $this->getParam("size") ?? $maxPossibleSize;
|
||||
|
||||
$doResize = true;
|
||||
} else if ($width > $maxSize || $height > $maxSize) {
|
||||
if ($width > $height) {
|
||||
$newWidth = $maxSize;
|
||||
$newHeight = intval($height * ($maxSize / $width));
|
||||
} else {
|
||||
$newHeight = $maxSize;
|
||||
$newWidth = intval($width * ($maxSize / $height));
|
||||
}
|
||||
|
||||
$doResize = true;
|
||||
} else {
|
||||
$newWidth = $width;
|
||||
$newHeight = $height;
|
||||
if ($maxPossibleSize < self::MIN_SIZE) {
|
||||
return $this->createError("Image must be at least " . self::MIN_SIZE . "x" . self::MIN_SIZE);
|
||||
} else if ($cropSize > self::MAX_SIZE) {
|
||||
return $this->createError("Crop must be at most " . self::MAX_SIZE . "x" . self::MAX_SIZE);
|
||||
} else if ($cropSize > $maxPossibleSize) {
|
||||
return $this->createError("Invalid crop size");
|
||||
}
|
||||
|
||||
if ($width < $minSize || $height < $minSize) {
|
||||
return $this->createError("Error processing image. Bad dimensions.");
|
||||
if ($cropX === null) {
|
||||
$cropX = ($width > $height) ? ($width - $height) / 2 : 0;
|
||||
}
|
||||
|
||||
if ($doResize) {
|
||||
$width = $newWidth;
|
||||
$height = $newHeight;
|
||||
$im->resizeImage($width, $height, \Imagick::FILTER_SINC, 1);
|
||||
}
|
||||
|
||||
$size = $this->getParam("size");
|
||||
if (is_null($size)) {
|
||||
$size = min($width, $height);
|
||||
}
|
||||
|
||||
$offset = [$this->getParam("offsetX"), $this->getParam("offsetY")];
|
||||
if ($size < $minSize or $size > $maxSize) {
|
||||
return $this->createError("Invalid size. Must be in range of $minSize-$maxSize.");
|
||||
}/* else if ($offset[0] < 0 || $offset[1] < 0 || $offset[0]+$size > $width || $offset[1]+$size > $height) {
|
||||
return $this->createError("Offsets out of bounds.");
|
||||
}*/
|
||||
|
||||
if ($offset[0] !== 0 || $offset[1] !== 0 || $size !== $width || $size !== $height) {
|
||||
$im->cropImage($size, $size, $offset[0], $offset[1]);
|
||||
if ($cropY === null) {
|
||||
$cropY = ($height > $width) ? ($height - $width) / 2 : 0;
|
||||
}
|
||||
|
||||
$im->cropImage($cropSize, $cropSize, $cropX, $cropY);
|
||||
$fileName = uuidv4() . ".jpg";
|
||||
$im->writeImage("$uploadDir/$fileName");
|
||||
$im->destroy();
|
||||
|
||||
Reference in New Issue
Block a user