From 2eeae084ff1643f7051717fecd47b7b106b4071b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 16 Feb 2022 16:55:07 +0200 Subject: [PATCH] Added readFile() and readStream() methods for MediaCollectionInterface --- .../Interfaces/MediaCollectionInterface.php | 15 ++++ .../Grav/Common/Page/Medium/AbstractMedia.php | 53 +++++++++++- .../Grav/Common/Page/Medium/LocalMedia.php | 82 +++++++++---------- 3 files changed, 105 insertions(+), 45 deletions(-) diff --git a/system/src/Grav/Common/Media/Interfaces/MediaCollectionInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaCollectionInterface.php index de9e78683..a971e0fae 100644 --- a/system/src/Grav/Common/Media/Interfaces/MediaCollectionInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/MediaCollectionInterface.php @@ -12,6 +12,7 @@ namespace Grav\Common\Media\Interfaces; use Grav\Common\Data\Blueprint; use Grav\Common\Page\Medium\ImageFile; use Grav\Common\Page\Medium\Medium; +use RuntimeException; /** * Class implements media collection interface. @@ -113,4 +114,18 @@ interface MediaCollectionInterface extends \Grav\Framework\Media\Interfaces\Medi * @return ImageFile */ public function getImageFileObject(MediaObjectInterface $mediaObject): ImageFile; + + /** + * @param string $filepath + * @return string + * @throws RuntimeException + */ + public function readFile(string $filepath): string; + + /** + * @param string $filepath + * @return resource + * @throws RuntimeException + */ + public function readStream(string $filepath); } diff --git a/system/src/Grav/Common/Page/Medium/AbstractMedia.php b/system/src/Grav/Common/Page/Medium/AbstractMedia.php index 82be81075..5196b185a 100644 --- a/system/src/Grav/Common/Page/Medium/AbstractMedia.php +++ b/system/src/Grav/Common/Page/Medium/AbstractMedia.php @@ -28,6 +28,8 @@ use RocketTheme\Toolbox\ArrayTraits\Export; use RocketTheme\Toolbox\ArrayTraits\ExportInterface; use RocketTheme\Toolbox\ArrayTraits\Iterator; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; +use RuntimeException; +use function count; use function in_array; use function is_array; @@ -59,6 +61,8 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac /** @var array|null */ protected $media_order; /** @var array */ + protected $config = []; + /** @var array */ protected $standard_exif = ['FileSize', 'MimeType', 'height', 'width']; /** @var int */ protected $indexTimeout = 0; @@ -275,7 +279,7 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac { $version = $data['version'] ?? null; if ($version !== static::VERSION) { - throw new \RuntimeException('Cannot unserialize: version mismatch'); + throw new RuntimeException('Cannot unserialize: version mismatch'); } $this->index = $data['index']; @@ -289,6 +293,20 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac } } + /** + * @param string $filepath + * @return string + * @throws RuntimeException + */ + abstract public function readFile(string $filepath): string; + + /** + * @param string $filepath + * @return resource + * @throws RuntimeException + */ + abstract public function readStream(string $filepath); + /** * Order the media based on the page's media_order * @@ -331,6 +349,37 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac */ abstract protected function readImageSize(string $filepath): array; + /** + * @param string $filepath + * @return array + */ + protected function readVectorSize(string $filepath): array + { + // Make sure that getting image size is supported. + if (\extension_loaded('simplexml')) { + $data = $this->readFile($filepath); + $xml = @simplexml_load_string($data); + $attr = $xml ? $xml->attributes() : null; + if ($attr instanceof \SimpleXMLElement) { + // Get the size from svg image. + if ($attr->width > 0 && $attr->height > 0) { + $width = $attr->width; + $height = $attr->height; + } elseif ($attr->viewBox && 4 === count($size = explode(' ', (string)$attr->viewBox))) { + [,$width,$height,] = $size; + } + + if (isset($width, $height)) { + return ['width' => (int)$width, 'height' => (int)$height, 'mime' => 'image/svg+xml']; + } + } + + throw new RuntimeException(sprintf('Cannot read image size from %s', $filepath)); + } + + return []; + } + /** * Load file listing from the filesystem. * @@ -380,7 +429,7 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac } elseif ($type === 'vector') { $info += $this->readVectorSize($filepath); } - } catch (\RuntimeException $e) { + } catch (RuntimeException $e) { // TODO: Maybe we want to handle this..? } } diff --git a/system/src/Grav/Common/Page/Medium/LocalMedia.php b/system/src/Grav/Common/Page/Medium/LocalMedia.php index 62a490de6..9ffb43338 100644 --- a/system/src/Grav/Common/Page/Medium/LocalMedia.php +++ b/system/src/Grav/Common/Page/Medium/LocalMedia.php @@ -18,7 +18,6 @@ use Grav\Framework\File\Formatter\JsonFormatter; use Grav\Framework\File\JsonFile; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use RuntimeException; -use function count; use function is_array; /** @@ -115,9 +114,41 @@ abstract class LocalMedia extends AbstractMedia */ public function getImageFileObject(MediaObjectInterface $mediaObject): ImageFile { - $path = $mediaObject->get('filepath'); + $filepath = $mediaObject->get('filepath'); - return ImageFile::open($path); + return ImageFile::open($filepath); + } + + /** + * @param string $filepath + * @return string + * @throws RuntimeException + */ + public function readFile(string $filepath): string + { + error_clear_last(); + $contents = @file_get_contents($filepath); + if (false === $contents) { + throw new RuntimeException(error_get_last()['message'] ?? ''); + } + + return $contents; + } + + /** + * @param string $filepath + * @return resource + * @throws RuntimeException + */ + public function readStream(string $filepath) + { + error_clear_last(); + $contents = @fopen($filepath, 'rb'); + if (false === $contents) { + throw new RuntimeException(error_get_last()['message'] ?? ''); + } + + return $contents; } /** @@ -127,16 +158,7 @@ abstract class LocalMedia extends AbstractMedia */ protected function fileExists(string $filename, string $destination): bool { - return file_exists("{$destination}/{$filename}"); - } - - /** - * @param string $filepath - * @return string - */ - protected function readFileContents(string $filepath): string - { - return file_get_contents($filepath); + return is_file("{$destination}/{$filename}"); } /** @@ -145,9 +167,10 @@ abstract class LocalMedia extends AbstractMedia */ protected function readImageSize(string $filepath): array { - $info = getimagesize($filepath); - if (!$info) { - throw new RuntimeException('Cannot read image size'); + error_clear_last(); + $info = @getimagesize($filepath); + if (false === $info) { + throw new RuntimeException(error_get_last()['message'] ?? ''); } $info = [ @@ -170,33 +193,6 @@ abstract class LocalMedia extends AbstractMedia return $info; } - protected function readVectorSize(string $filepath): array - { - // Make sure that getting image size is supported. - if (\extension_loaded('simplexml')) { - $data = $this->readFileContents($filepath); - $xml = simplexml_load_string($data); - $attr = $xml ? $xml->attributes() : null; - if ($attr instanceof \SimpleXMLElement) { - // Get the size from svg image. - if ($attr->width > 0 && $attr->height > 0) { - $width = $attr->width; - $height = $attr->height; - } elseif ($attr->viewBox && 4 === count($size = explode(' ', (string)$attr->viewBox))) { - [,$width,$height,] = $size; - } - - if ($width && $height) { - return ['width' => (int)$width, 'height' => (int)$height, 'mime' => 'image/svg+xml']; - } - } - - throw new RuntimeException('Cannot read image size'); - } - - return []; - } - /** * Load file listing from the filesystem. *