Skip to content

Commit

Permalink
Add namespaced exceptions and a specific FileNotExistsException (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
ausi authored Mar 18, 2021
1 parent 21fa004 commit 7d0f40e
Show file tree
Hide file tree
Showing 30 changed files with 312 additions and 63 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

* Add namespaced exceptions and a specific `FileNotExistsException`. [#79]

## [1.0.3] (2020-11-20)

Expand Down Expand Up @@ -140,6 +141,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
[0.2.0]: https://github.com/contao/image/compare/0.1.0...0.2.0
[0.1.0]: https://github.com/contao/image/commits/0.1.0

[#79]: https://github.com/contao/image/issues/79
[#74]: https://github.com/contao/image/issues/74
[#71]: https://github.com/contao/image/issues/71
[#70]: https://github.com/contao/image/issues/70
Expand Down
22 changes: 13 additions & 9 deletions src/DeferredImageStorageFilesystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

namespace Contao\Image;

use Contao\Image\Exception\FileNotExistsException;
use Contao\Image\Exception\InvalidArgumentException;
use Contao\Image\Exception\JsonException;
use Contao\Image\Exception\RuntimeException;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
use Webmozart\PathUtil\Path;
Expand Down Expand Up @@ -54,7 +58,7 @@ public function set(string $path, array $value): void
$json = json_encode($value);

if (JSON_ERROR_NONE !== json_last_error()) {
throw new \JsonException(json_last_error_msg());
throw new JsonException(json_last_error_msg());
}

$this->filesystem->dumpFile($this->getConfigPath($path), $json);
Expand Down Expand Up @@ -83,7 +87,7 @@ public function getLocked(string $path, bool $blocking = true): ?array
{
if (isset($this->locks[$path])) {
if ($blocking) {
throw new \RuntimeException(sprintf('Lock for "%s" was already acquired', $path));
throw new RuntimeException(sprintf('Lock for "%s" was already acquired', $path));
}

return null;
Expand All @@ -92,14 +96,14 @@ public function getLocked(string $path, bool $blocking = true): ?array
$configPath = $this->getConfigPath($path);

if (!$handle = @fopen($configPath, 'r+') ?: @fopen($configPath, 'r')) {
throw new \RuntimeException(sprintf('Unable to open file "%s"', $configPath));
throw new FileNotExistsException(sprintf('Unable to open file "%s"', $configPath));
}

if (!flock($handle, LOCK_EX | ($blocking ? 0 : LOCK_NB))) {
fclose($handle);

if ($blocking) {
throw new \RuntimeException(sprintf('Unable to acquire lock for file "%s"', $configPath));
throw new RuntimeException(sprintf('Unable to acquire lock for file "%s"', $configPath));
}

return null;
Expand All @@ -116,7 +120,7 @@ public function getLocked(string $path, bool $blocking = true): ?array
public function releaseLock(string $path): void
{
if (!isset($this->locks[$path])) {
throw new \RuntimeException(sprintf('No acquired lock for "%s" exists', $path));
throw new RuntimeException(sprintf('No acquired lock for "%s" exists', $path));
}

flock($this->locks[$path], LOCK_UN | LOCK_NB);
Expand All @@ -134,7 +138,7 @@ public function delete(string $path): void
$this->filesystem->remove($this->getConfigPath($path));
} catch (IOException $exception) {
if (!isset($this->locks[$path])) {
throw $exception;
throw new RuntimeException($exception->getMessage(), 0, $exception);
}

$this->releaseLock($path);
Expand Down Expand Up @@ -189,7 +193,7 @@ public function current(): string
private function getConfigPath(string $path): string
{
if (preg_match('(^/|/$|//|/\.\.|^\.\.)', $path)) {
throw new \InvalidArgumentException(sprintf('Invalid storage key "%s"', $path));
throw new InvalidArgumentException(sprintf('Invalid storage key "%s"', $path));
}

return $this->cacheDir.'/'.$path.self::PATH_SUFFIX;
Expand All @@ -203,11 +207,11 @@ private function decode(string $contents): array
$content = json_decode($contents, true);

if (JSON_ERROR_NONE !== json_last_error()) {
throw new \JsonException(json_last_error_msg());
throw new JsonException(json_last_error_msg());
}

if (!\is_array($content)) {
throw new \InvalidArgumentException(sprintf('Invalid JSON data: expected array, got "%s"', \gettype($content)));
throw new InvalidArgumentException(sprintf('Invalid JSON data: expected array, got "%s"', \gettype($content)));
}

return $content;
Expand Down
6 changes: 4 additions & 2 deletions src/DeferredResizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

namespace Contao\Image;

use Contao\Image\Exception\InvalidArgumentException;
use Contao\Image\Exception\RuntimeException;
use Imagine\Image\Box;
use Imagine\Image\ImagineInterface;
use Imagine\Image\Point;
Expand Down Expand Up @@ -78,7 +80,7 @@ public function getDeferredImage(string $targetPath, ImagineInterface $imagine):
public function resizeDeferredImage(DeferredImageInterface $image, bool $blocking = true): ?ImageInterface
{
if (!Path::isBasePath($this->cacheDir, $image->getPath())) {
throw new \InvalidArgumentException(sprintf('Path "%s" is not inside cache directory "%s"', $image->getPath(), $this->cacheDir));
throw new InvalidArgumentException(sprintf('Path "%s" is not inside cache directory "%s"', $image->getPath(), $this->cacheDir));
}

$targetPath = Path::makeRelative($image->getPath(), $this->cacheDir);
Expand All @@ -96,7 +98,7 @@ public function resizeDeferredImage(DeferredImageInterface $image, bool $blockin

if (null === $config) {
if ($blocking) {
throw new \RuntimeException(sprintf('Unable to acquire lock for "%s"', $targetPath));
throw new RuntimeException(sprintf('Unable to acquire lock for "%s"', $targetPath));
}

return null;
Expand Down
17 changes: 17 additions & 0 deletions src/Exception/CoordinatesOutOfBoundsException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/

namespace Contao\Image\Exception;

class CoordinatesOutOfBoundsException extends InvalidArgumentException
{
}
20 changes: 20 additions & 0 deletions src/Exception/ExceptionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/

namespace Contao\Image\Exception;

/**
* Exception interface for all exceptions thrown by this library.
*/
interface ExceptionInterface extends \Throwable
{
}
17 changes: 17 additions & 0 deletions src/Exception/FileNotExistsException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/

namespace Contao\Image\Exception;

class FileNotExistsException extends InvalidArgumentException
{
}
17 changes: 17 additions & 0 deletions src/Exception/InvalidArgumentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/

namespace Contao\Image\Exception;

class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
17 changes: 17 additions & 0 deletions src/Exception/JsonException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/

namespace Contao\Image\Exception;

class JsonException extends \JsonException implements ExceptionInterface
{
}
17 changes: 17 additions & 0 deletions src/Exception/RuntimeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/

namespace Contao\Image\Exception;

class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
8 changes: 5 additions & 3 deletions src/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

namespace Contao\Image;

use Contao\Image\Exception\FileNotExistsException;
use Contao\Image\Exception\InvalidArgumentException;
use Contao\ImagineSvg\Image as SvgImage;
use Contao\ImagineSvg\Imagine as SvgImagine;
use DOMDocument;
Expand Down Expand Up @@ -58,11 +60,11 @@ public function __construct(string $path, ImagineInterface $imagine, Filesystem
}

if (!$filesystem->exists($path)) {
throw new \InvalidArgumentException($path.' does not exist');
throw new FileNotExistsException($path.' does not exist');
}

if (is_dir($path)) {
throw new \InvalidArgumentException($path.' is a directory');
throw new FileNotExistsException($path.' is a directory');
}

$this->path = $path;
Expand Down Expand Up @@ -91,7 +93,7 @@ public function getPath(): string
public function getUrl(string $rootDir, string $prefix = ''): string
{
if (!Path::isBasePath($rootDir, $this->path)) {
throw new \InvalidArgumentException(sprintf('Path "%s" is not inside root directory "%s"', $this->path, $rootDir));
throw new InvalidArgumentException(sprintf('Path "%s" is not inside root directory "%s"', $this->path, $rootDir));
}

$url = Path::makeRelative($this->path, $rootDir);
Expand Down
3 changes: 2 additions & 1 deletion src/ImageDimensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace Contao\Image;

use Contao\Image\Exception\InvalidArgumentException;
use Contao\ImagineSvg\RelativeBoxInterface;
use Contao\ImagineSvg\SvgBox;
use Contao\ImagineSvg\UndefinedBoxInterface;
Expand Down Expand Up @@ -56,7 +57,7 @@ class ImageDimensions
public function __construct(BoxInterface $size, bool $relative = null, bool $undefined = null, int $orientation = self::ORIENTATION_NORMAL)
{
if ($orientation < 1 || $orientation > 8) {
throw new \InvalidArgumentException('Orientation must be one of the ImageDimensions::ORIENTATION_* constants');
throw new InvalidArgumentException('Orientation must be one of the ImageDimensions::ORIENTATION_* constants');
}

if (null === $relative) {
Expand Down
8 changes: 5 additions & 3 deletions src/ImportantPart.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

namespace Contao\Image;

use Contao\Image\Exception\CoordinatesOutOfBoundsException;

class ImportantPart
{
/**
Expand Down Expand Up @@ -42,20 +44,20 @@ class ImportantPart
public function __construct(float $x = 0, float $y = 0, float $width = 1, float $height = 1)
{
if ($x < 0 || $x > 1 || $y < 0 || $y > 1 || $width < 0 || $width > 1 || $height < 0 || $height > 1) {
throw new \InvalidArgumentException('X, Y, width and height must be a float between 0 and 1');
throw new CoordinatesOutOfBoundsException('X, Y, width and height must be a float between 0 and 1');
}

if ($x + $width > 1) {
if ($x + $width - 1 > self::ROUNDING_ERROR_THRESHOLD) {
throw new \InvalidArgumentException('The X coordinate plus the width must not be greater than 1');
throw new CoordinatesOutOfBoundsException('The X coordinate plus the width must not be greater than 1');
}

$width = 1 - $x;
}

if ($y + $height > 1) {
if ($y + $height - 1 > self::ROUNDING_ERROR_THRESHOLD) {
throw new \InvalidArgumentException('The Y coordinate plus the height must not be greater than 1');
throw new CoordinatesOutOfBoundsException('The Y coordinate plus the height must not be greater than 1');
}

$height = 1 - $y;
Expand Down
14 changes: 8 additions & 6 deletions src/Picture.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

namespace Contao\Image;

use Contao\Image\Exception\InvalidArgumentException;

class Picture implements PictureInterface
{
/**
Expand Down Expand Up @@ -44,7 +46,7 @@ public function getImg(string $rootDir = null, string $prefix = ''): array
{
if (null === $rootDir) {
if ('' !== $prefix) {
throw new \InvalidArgumentException(sprintf('Prefix must no be specified if rootDir is null, given "%s"', $prefix));
throw new InvalidArgumentException(sprintf('Prefix must no be specified if rootDir is null, given "%s"', $prefix));
}

return $this->img;
Expand All @@ -60,7 +62,7 @@ public function getSources(string $rootDir = null, string $prefix = ''): array
{
if (null === $rootDir) {
if ('' !== $prefix) {
throw new \InvalidArgumentException(sprintf('Prefix must no be specified if rootDir is null, given "%s"', $prefix));
throw new InvalidArgumentException(sprintf('Prefix must no be specified if rootDir is null, given "%s"', $prefix));
}

return $this->sources;
Expand Down Expand Up @@ -104,11 +106,11 @@ static function (array $src) use ($rootDir, $prefix) {
private function validateSrcAttribute(array $img): void
{
if (!isset($img['src'])) {
throw new \InvalidArgumentException('Missing src attribute');
throw new InvalidArgumentException('Missing src attribute');
}

if (!$img['src'] instanceof ImageInterface) {
throw new \InvalidArgumentException('Src must be of type ImageInterface');
throw new InvalidArgumentException('Src must be of type ImageInterface');
}
}

Expand All @@ -118,12 +120,12 @@ private function validateSrcAttribute(array $img): void
private function validateSrcsetAttribute(array $img): void
{
if (!isset($img['srcset'])) {
throw new \InvalidArgumentException('Missing srcset attribute');
throw new InvalidArgumentException('Missing srcset attribute');
}

foreach ($img['srcset'] as $src) {
if (!$src[0] instanceof ImageInterface) {
throw new \InvalidArgumentException('Srcsets must be of type ImageInterface');
throw new InvalidArgumentException('Srcsets must be of type ImageInterface');
}
}
}
Expand Down
Loading

0 comments on commit 7d0f40e

Please sign in to comment.