Articles: finish admin refactor, uploads hardening, and attachment sorting (0.262)

This commit is contained in:
2026-02-13 09:00:24 +01:00
parent e984548516
commit 3e1f417ef3
31 changed files with 1951 additions and 1512 deletions

View File

@@ -3,7 +3,8 @@ class ImageManipulator
{
protected int $width;
protected int $height;
protected \GdImage $image;
/** @var resource|\GdImage */
protected $image;
protected ?string $file = null;
/**
@@ -37,7 +38,7 @@ class ImageManipulator
throw new InvalidArgumentException("Image file $file is not readable");
}
if (isset($this->image) && $this->image instanceof \GdImage) {
if (isset($this->image) && $this->isValidImageResource($this->image)) {
imagedestroy($this->image);
}
@@ -66,7 +67,7 @@ class ImageManipulator
throw new InvalidArgumentException("Image type $type not supported");
}
if (!$this->image instanceof \GdImage) {
if (!$this->isValidImageResource($this->image)) {
throw new InvalidArgumentException("Failed to create image from $file");
}
@@ -91,12 +92,12 @@ class ImageManipulator
*/
public function setImageString(string $data): self
{
if (isset($this->image) && $this->image instanceof \GdImage) {
if (isset($this->image) && $this->isValidImageResource($this->image)) {
imagedestroy($this->image);
}
$image = imagecreatefromstring($data);
if (!$image instanceof \GdImage) {
if (!$this->isValidImageResource($image)) {
throw new RuntimeException('Cannot create image from data string');
}
@@ -124,7 +125,7 @@ class ImageManipulator
*/
public function resample(int $width, int $height, bool $constrainProportions = true): self
{
if (!isset($this->image) || !$this->image instanceof \GdImage) {
if (!isset($this->image) || !$this->isValidImageResource($this->image)) {
throw new RuntimeException('No image set');
}
@@ -169,7 +170,7 @@ class ImageManipulator
*/
public function enlargeCanvas(int $width, int $height, array $rgb = [], ?int $xpos = null, ?int $ypos = null): self
{
if (!isset($this->image) || !$this->image instanceof \GdImage) {
if (!isset($this->image) || !$this->isValidImageResource($this->image)) {
throw new RuntimeException('No image set');
}
@@ -177,7 +178,7 @@ class ImageManipulator
$height = max($height, $this->height);
$temp = imagecreatetruecolor($width, $height);
if (!$temp instanceof \GdImage) {
if (!$this->isValidImageResource($temp)) {
throw new RuntimeException('Failed to create a new image for enlarging canvas');
}
@@ -233,7 +234,7 @@ class ImageManipulator
*/
public function crop($x1, int $y1 = 0, int $x2 = 0, int $y2 = 0): self
{
if (!isset($this->image) || !$this->image instanceof \GdImage) {
if (!isset($this->image) || !$this->isValidImageResource($this->image)) {
throw new RuntimeException('No image set');
}
@@ -257,7 +258,7 @@ class ImageManipulator
}
$temp = imagecreatetruecolor($cropWidth, $cropHeight);
if (!$temp instanceof \GdImage) {
if (!$this->isValidImageResource($temp)) {
throw new RuntimeException('Failed to create a new image for cropping');
}
@@ -286,17 +287,17 @@ class ImageManipulator
/**
* Replace current image resource with a new one
*
* @param \GdImage $res New image resource
* @param resource|\GdImage $res New image resource
* @return self
* @throws UnexpectedValueException
*/
protected function _replace(\GdImage $res): self
protected function _replace($res): self
{
if (!$res instanceof \GdImage) {
if (!$this->isValidImageResource($res)) {
throw new UnexpectedValueException('Invalid image resource');
}
if (isset($this->image) && $this->image instanceof \GdImage) {
if (isset($this->image) && $this->isValidImageResource($this->image)) {
imagedestroy($this->image);
}
@@ -386,9 +387,9 @@ class ImageManipulator
/**
* Returns the GD image resource
*
* @return \GdImage
* @return resource|\GdImage
*/
public function getResource(): \GdImage
public function getResource()
{
return $this->image;
}
@@ -418,8 +419,22 @@ class ImageManipulator
*/
public function __destruct()
{
if (isset($this->image) && $this->image instanceof \GdImage) {
if (isset($this->image) && $this->isValidImageResource($this->image)) {
imagedestroy($this->image);
}
}
/**
* Compatibility helper for PHP 7.4 (resource) and PHP 8+ (GdImage).
*
* @param mixed $image
*/
private function isValidImageResource($image): bool
{
if (is_resource($image)) {
return true;
}
return class_exists('GdImage', false) && $image instanceof \GdImage;
}
}