-
-
Notifications
You must be signed in to change notification settings - Fork 46
Closed
Description
New language relevant PR in upstream repo: joomla/joomla-cms#38805 Here are the upstream changes:
Click to expand the diff!
diff --git a/administrator/language/en-GB/plg_filesystem_local.ini b/administrator/language/en-GB/plg_filesystem_local.ini
index c7b40cb9e941..86fe8999570e 100644
--- a/administrator/language/en-GB/plg_filesystem_local.ini
+++ b/administrator/language/en-GB/plg_filesystem_local.ini
@@ -5,6 +5,7 @@
PLG_FILESYSTEM_LOCAL="FileSystem - Local"
PLG_FILESYSTEM_LOCAL_DEFAULT_NAME="Local"
-PLG_FILESYSTEM_LOCAL_DIRECTORIES_DIRECTORY_LABEL="Select directories"
+PLG_FILESYSTEM_LOCAL_DIRECTORIES_DIRECTORY_LABEL="Select Directories"
+PLG_FILESYSTEM_LOCAL_DIRECTORIES_DIRECTORY_THUMBNAILS_LABEL="Create Thumbnails"
PLG_FILESYSTEM_LOCAL_DIRECTORIES_LABEL="Directories"
PLG_FILESYSTEM_LOCAL_XML_DESCRIPTION="Filesystem plugin to define one or multiple local directories to store your media files."
diff --git a/libraries/src/Image/Image.php b/libraries/src/Image/Image.php
index 32b01a766b1e..688ba83b02a5 100644
--- a/libraries/src/Image/Image.php
+++ b/libraries/src/Image/Image.php
@@ -305,17 +305,18 @@ public function generateThumbs($thumbSizes, $creationMethod = self::SCALE_INSIDE
/**
* Method to create thumbnails from the current image and save them to disk. It allows creation by resizing or cropping the original image.
*
- * @param mixed $thumbSizes string or array of strings. Example: $thumbSizes = array('150x75','250x150');
- * @param integer $creationMethod 1-3 resize $scaleMethod | 4 create cropping
- * @param string $thumbsFolder destination thumbs folder. null generates a thumbs folder in the image folder
+ * @param mixed $thumbSizes string or array of strings. Example: $thumbSizes = ['150x75','250x150'];
+ * @param integer $creationMethod 1-3 resize $scaleMethod | 4 create cropping
+ * @param string $thumbsFolder destination thumbs folder. null generates a thumbs folder in the image folder
+ * @param boolean $useOriginalName Shall we use the original image name? Defaults is false, {filename}_{width}x{height}.{ext}
*
* @return array
*
- * @since 2.5.0
+ * @since __DEPLOY_VERSION__
* @throws \LogicException
* @throws \InvalidArgumentException
*/
- public function createThumbs($thumbSizes, $creationMethod = self::SCALE_INSIDE, $thumbsFolder = null)
+ public function createThumbnails($thumbSizes, $creationMethod = self::SCALE_INSIDE, $thumbsFolder = null, $useOriginalName = false)
{
// Make sure the resource handle is valid.
if (!$this->isLoaded()) {
@@ -349,8 +350,13 @@ public function createThumbs($thumbSizes, $creationMethod = self::SCALE_INSIDE,
$thumbWidth = $thumb->getWidth();
$thumbHeight = $thumb->getHeight();
- // Generate thumb name
- $thumbFileName = $filename . '_' . $thumbWidth . 'x' . $thumbHeight . '.' . $fileExtension;
+ if ($useOriginalName) {
+ // Generate thumb name
+ $thumbFileName = $filename . '.' . $fileExtension;
+ } else {
+ // Generate thumb name
+ $thumbFileName = $filename . '_' . $thumbWidth . 'x' . $thumbHeight . '.' . $fileExtension;
+ }
// Save thumb file to disk
$thumbFileName = $thumbsFolder . '/' . $thumbFileName;
@@ -366,6 +372,26 @@ public function createThumbs($thumbSizes, $creationMethod = self::SCALE_INSIDE,
return $thumbsCreated;
}
+ /**
+ * Method to create thumbnails from the current image and save them to disk. It allows creation by resizing or cropping the original image.
+ *
+ * @param mixed $thumbSizes string or array of strings. Example: $thumbSizes = ['150x75','250x150'];
+ * @param integer $creationMethod 1-3 resize $scaleMethod | 4 create cropping
+ * @param string $thumbsFolder destination thumbs folder. null generates a thumbs folder in the image folder
+ *
+ * @return array
+ *
+ * @since 2.5.0
+ * @throws \LogicException
+ * @throws \InvalidArgumentException
+ *
+ * @deprecated 6.0 Use \Joomla\CMS\Image\createThumbnails instead
+ */
+ public function createThumbs($thumbSizes, $creationMethod = self::SCALE_INSIDE, $thumbsFolder = null)
+ {
+ return $this->createThumbnails($thumbSizes, $creationMethod, $thumbsFolder, false);
+ }
+
/**
* Method to crop the current image.
*
diff --git a/plugins/filesystem/local/local.php b/plugins/filesystem/local/local.php
index d23ab606b4e1..5f2df57e2131 100644
--- a/plugins/filesystem/local/local.php
+++ b/plugins/filesystem/local/local.php
@@ -84,7 +84,7 @@ public function getDisplayName()
public function getAdapters()
{
$adapters = [];
- $directories = $this->params->get('directories', '[{"directory": "images"}]');
+ $directories = $this->params->get('directories', '[{"directory": "images", "thumbs": 0}]');
// Do a check if default settings are not saved by user
// If not initialize them manually
@@ -97,9 +97,15 @@ public function getAdapters()
$directoryPath = JPATH_ROOT . '/' . $directoryEntity->directory;
$directoryPath = rtrim($directoryPath) . '/';
+ if (!isset($directoryEntity->thumbs)) {
+ $directoryEntity->thumbs = 0;
+ }
+
$adapter = new \Joomla\Plugin\Filesystem\Local\Adapter\LocalAdapter(
$directoryPath,
- $directoryEntity->directory
+ $directoryEntity->directory,
+ $directoryEntity->thumbs,
+ [200, 200]
);
$adapters[$adapter->getAdapterName()] = $adapter;
diff --git a/plugins/filesystem/local/local.xml b/plugins/filesystem/local/local.xml
index 8f93dc5bc9e2..bcb9a676767f 100644
--- a/plugins/filesystem/local/local.xml
+++ b/plugins/filesystem/local/local.xml
@@ -44,6 +44,17 @@
hide_none="true"
validate="options"
/>
+ <field
+ name="thumbs"
+ type="radio"
+ label="PLG_FILESYSTEM_LOCAL_DIRECTORIES_DIRECTORY_THUMBNAILS_LABEL"
+ layout="joomla.form.field.radio.switcher"
+ default="0"
+ filter="integer"
+ >
+ <option value="0">JNO</option>
+ <option value="1">JYES</option>
+ </field>
</form>
</field>
</fieldset>
diff --git a/plugins/filesystem/local/src/Adapter/LocalAdapter.php b/plugins/filesystem/local/src/Adapter/LocalAdapter.php
index e9f43f0a1711..ec000af50a53 100644
--- a/plugins/filesystem/local/src/Adapter/LocalAdapter.php
+++ b/plugins/filesystem/local/src/Adapter/LocalAdapter.php
@@ -55,22 +55,52 @@ class LocalAdapter implements AdapterInterface
*/
private $filePath = null;
+ /**
+ * Should the adapter create a thumbnail for the image?
+ *
+ * @var boolean
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ private $thumbnails = false;
+
+ /**
+ * Thumbnail dimensions in pixels, [0] = width, [1] = height
+ *
+ * @var array
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ private $thumbnailSize = [200, 200];
+
/**
* The absolute root path in the local file system.
*
- * @param string $rootPath The root path
- * @param string $filePath The file path of media folder
+ * @param string $rootPath The root path
+ * @param string $filePath The file path of media folder
+ * @param boolean $thumbnails The thumbnails option
+ * @param array $thumbnailSize The thumbnail dimensions in pixels
*
* @since 4.0.0
*/
- public function __construct(string $rootPath, string $filePath)
+ public function __construct(string $rootPath, string $filePath, bool $thumbnails = false, array $thumbnailSize = [200, 200])
{
if (!file_exists($rootPath)) {
throw new \InvalidArgumentException(Text::_('COM_MEDIA_ERROR_MISSING_DIR'));
}
- $this->rootPath = Path::clean(realpath($rootPath), '/');
- $this->filePath = $filePath;
+ $this->rootPath = Path::clean(realpath($rootPath), '/');
+ $this->filePath = $filePath;
+ $this->thumbnails = $thumbnails;
+ $this->thumbnailSize = $thumbnailSize;
+
+ if ($this->thumbnails) {
+ $dir = JPATH_ROOT . '/media/cache/com_media/thumbs/' . $this->filePath;
+
+ if (!is_dir($dir)) {
+ Folder::create($dir);
+ }
+ }
}
/**
@@ -221,14 +251,24 @@ public function createFolder(string $name, string $path): string
*/
public function createFile(string $name, string $path, $data): string
{
- $name = $this->getSafeName($name);
-
+ $name = $this->getSafeName($name);
$localPath = $this->getLocalPath($path . '/' . $name);
$this->checkContent($localPath, $data);
File::write($localPath, $data);
+ if ($this->thumbnails && MediaHelper::isImage(pathinfo($localPath)['basename'])) {
+ $thumbnailPaths = $this->getLocalThumbnailPaths($localPath);
+
+ if (empty($thumbnailPaths)) {
+ return $name;
+ }
+
+ // Create the thumbnail
+ $this->createThumbnail($localPath, $thumbnailPaths['fs']);
+ }
+
return $name;
}
@@ -255,6 +295,17 @@ public function updateFile(string $name, string $path, $data)
$this->checkContent($localPath, $data);
File::write($localPath, $data);
+
+ if ($this->thumbnails && MediaHelper::isImage(pathinfo($localPath)['basename'])) {
+ $thumbnailPaths = $this->getLocalThumbnailPaths($localPath);
+
+ if (empty($thumbnailPaths['fs'])) {
+ return;
+ }
+
+ // Create the thumbnail
+ $this->createThumbnail($localPath, $thumbnailPaths['fs']);
+ }
}
/**
@@ -269,13 +320,18 @@ public function updateFile(string $name, string $path, $data)
*/
public function delete(string $path)
{
- $localPath = $this->getLocalPath($path);
+ $localPath = $this->getLocalPath($path);
+ $thumbnailPaths = $this->getLocalThumbnailPaths($localPath);
if (is_file($localPath)) {
if (!File::exists($localPath)) {
throw new FileNotFoundException();
}
+ if ($this->thumbnails && !empty($thumbnailPaths['fs']) && is_file($thumbnailPaths['fs'])) {
+ File::delete($thumbnailPaths['fs']);
+ }
+
$success = File::delete($localPath);
} else {
if (!Folder::exists($localPath)) {
@@ -283,6 +339,10 @@ public function delete(string $path)
}
$success = Folder::delete($localPath);
+
+ if ($this->thumbnails && !empty($thumbnailPaths['fs']) && is_dir($thumbnailPaths['fs'])) {
+ Folder::delete($thumbnailPaths['fs']);
+ }
}
if (!$success) {
@@ -303,7 +363,7 @@ public function delete(string $path)
* - mime_type: The mime type
* - width: The width, when available
* - height: The height, when available
- * - thumb_path The thumbnail path of file, when available
+ * - thumb_path: The thumbnail path of file, when available
*
* @param string $path The folder
*
@@ -351,8 +411,7 @@ private function getPathInformation(string $path): \stdClass
$obj->width = $props->width;
$obj->height = $props->height;
- // @todo : Change this path to an actual thumbnail path
- $obj->thumb_path = $this->getUrl($obj->path);
+ $obj->thumb_path = $this->thumbnails ? $this->getThumbnail($path) : $this->getUrl($obj->path);
} catch (UnparsableImageException $e) {
// Ignore the exception - it's an image that we don't know how to parse right now
}
@@ -689,7 +748,7 @@ private function rglob(string $pattern, int $flags = 0): array
{
$files = glob($pattern, $flags);
- foreach (glob(\dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
+ foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
$files = array_merge($files, $this->rglob($dir . '/' . $this->getFileName($pattern), $flags));
}
@@ -763,7 +822,7 @@ private function checkContent(string $localPath, string $mediaContent)
$helper = new MediaHelper();
// @todo find a better way to check the input, by not writing the file to the disk
- $tmpFile = Path::clean(\dirname($localPath) . '/' . uniqid() . '.' . File::getExt($name));
+ $tmpFile = Path::clean(dirname($localPath) . '/' . uniqid() . '.' . File::getExt($name));
if (!File::write($tmpFile, $mediaContent)) {
throw new \Exception(Text::_('JLIB_MEDIA_ERROR_UPLOAD_INPUT'), 500);
@@ -819,4 +878,89 @@ private function getLocalPath(string $path): string
throw new InvalidPathException($e->getMessage());
}
}
+
+ /**
+ * Returns the local filesystem thumbnail path for the given path.
+ *
+ * Throws an InvalidPathException if the path is invalid.
+ *
+ * @param string $path The path
+ *
+ * @return array
+ *
+ * @since __DEPLOY_VERSION__
+ * @throws InvalidPathException
+ */
+ private function getLocalThumbnailPaths(string $path): array
+ {
+ $rootPath = str_replace(['\\', '/'], '/', $this->rootPath);
+ $path = str_replace(['\\', '/'], '/', $path);
+
+ try {
+ $fs = Path::check(str_replace($rootPath, JPATH_ROOT . '/media/cache/com_media/thumbs/' . $this->filePath, $path));
+ $url = str_replace($rootPath, 'media/cache/com_media/thumbs/' . $this->filePath, $path);
+
+ return [
+ 'fs' => $fs,
+ 'url' => $url,
+ ];
+ } catch (\Exception $e) {
+ throw new InvalidPathException($e->getMessage());
+ }
+ }
+
+ /**
+ * Returns the path for the thumbnail of the given image.
+ * If the thumbnail does not exist, it will be created.
+ *
+ * @param string $path The path of the image
+ *
+ * @return string
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ private function getThumbnail(string $path): string
+ {
+ $thumbnailPaths = $this->getLocalThumbnailPaths($path);
+
+ if (empty($thumbnailPaths['fs'])) {
+ return $this->getUrl($path);
+ }
+
+ $dir = dirname($thumbnailPaths['fs']);
+
+ if (!is_dir($dir)) {
+ Folder::create($dir);
+ }
+
+ // Create the thumbnail
+ if (!is_file($thumbnailPaths['fs']) && !$this->createThumbnail($path, $thumbnailPaths['fs'])) {
+ return $this->getUrl($path);
+ }
+
+ return Uri::root() . $this->getEncodedPath($thumbnailPaths['url']);
+ }
+
+ /**
+ * Create a thumbnail of the given image.
+ *
+ * @param string $path The path of the image
+ * @param string $thumbnailPath The path of the thumbnail
+ *
+ * @return boolean
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ private function createThumbnail(string $path, string $thumbnailPath): bool
+ {
+ $image = new Image($path);
+
+ try {
+ $image->createThumbnails([$this->thumbnailSize[0] . 'x' . $this->thumbnailSize[1]], $image::SCALE_INSIDE, dirname($thumbnailPath), true);
+ } catch (\Exception $e) {
+ return false;
+ }
+
+ return true;
+ }
}