From cba836c2c792f3589c124257f92b941189e062f9 Mon Sep 17 00:00:00 2001
From: Andrew Short <andrewjshort@gmail.com>
Date: Sun, 6 Dec 2009 20:47:05 +1100
Subject: [PATCH] FEATURE: Added VersionedImageExtension to automatically
 regenerate cached/resampled images when a file version is changed.

---
 _config.php                      |  3 +-
 code/VersionedImageExtension.php | 70 ++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100755 code/VersionedImageExtension.php

diff --git a/_config.php b/_config.php
index c010ef6..00585df 100755
--- a/_config.php
+++ b/_config.php
@@ -3,4 +3,5 @@
  * @package silverstripe-versionedfiles
  */
 
-Object::add_extension('File', 'VersionedFileExtension');
\ No newline at end of file
+Object::add_extension('File',  'VersionedFileExtension');
+Object::add_extension('Image', 'VersionedImageExtension');
\ No newline at end of file
diff --git a/code/VersionedImageExtension.php b/code/VersionedImageExtension.php
new file mode 100755
index 0000000..c6fd412
--- /dev/null
+++ b/code/VersionedImageExtension.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * An extension to automatically regenerate all cached/resampled images when an image version is changed.
+ *
+ * @package silverstripe-versionedfiles
+ */
+class VersionedImageExtension extends DataObjectDecorator {
+
+	/**
+	 * Regenerates all cached images if the version number has been changed.
+	 */
+	public function onBeforeWrite() {
+		if(!$this->owner->isChanged('CurrentVersionID')) return;
+
+		$base      = $this->owner->ParentID ? $this->owner->Parent()->getFullPath() : ASSETS_PATH . '/';
+		$resampled = "{$base}_resampled";
+
+		if(!is_dir($resampled)) return;
+
+		$files    = scandir($resampled);
+		$iterator = new ArrayIterator($files);
+		$filter   = new RegexIterator (
+			$iterator,
+			sprintf("/(?<method>[a-zA-Z]+)(?<arguments>[0-9]*)-%s/", preg_quote($this->owner->Name)),
+			RegexIterator::GET_MATCH
+		);
+
+		// grab each resampled image and regenerate it
+		foreach($filter as $cachedImage) {
+			$path      = "$resampled/{$cachedImage[0]}";
+			$size      = getimagesize($path);
+			$method    = $cachedImage['method'];
+			$arguments = $cachedImage['arguments'];
+
+			unlink($path);
+
+			// Determine the arguments used to generate an image, and regenerate it. Different methods need different
+			// ways of determining the original arguments used.
+			switch(strtolower($method)) {
+				case 'resizedimage':
+				case 'setsize':
+				case 'paddedimage':
+				case 'croppedimage':
+					$this->owner->$method($size[0], $size[1]);
+					break;
+
+				case 'setwidth':
+					$this->owner->$method($size[0]);
+					break;
+
+				case 'setheight':
+					$this->owner->$method($size[1]);
+					break;
+
+				case 'setratiosize':
+					if(strpos($arguments, $size[0]) === 0) {
+						$this->owner->$method($size[0], substr($arguments, strlen($size[0])));
+					} else {
+						$this->owner->$method($size[1], substr($arguments, 0, strlen($size[0]) * -1));
+					}
+					break;
+
+				default:
+					$this->owner->$method($arguments);
+					break;
+			}
+		}
+	}
+
+}
\ No newline at end of file
-- 
GitLab