mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
This is a fixed version for RegenerateCachedImagesTask (former FlushGeneratedImagesTask) such that it regenerates images instead of silently removing them and breaking existing pages
The pull request also contains some enhancements and fixes to the corresponding testcases. Fixes #318
This commit is contained in:
parent
91477617e6
commit
8908a6bcd7
@ -298,6 +298,8 @@ class Image extends File {
|
||||
$cached = new Image_Cached($cacheFile);
|
||||
// Pass through the title so the templates can use it
|
||||
$cached->Title = $this->Title;
|
||||
$cached->ParentID = $this->ParentID;
|
||||
$cached->Parent = $this->Parent();
|
||||
return $cached;
|
||||
}
|
||||
}
|
||||
@ -312,7 +314,7 @@ class Image extends File {
|
||||
public function cacheFilename($format, $arg1 = null, $arg2 = null) {
|
||||
$folder = $this->ParentID ? $this->Parent()->Filename : ASSETS_DIR . "/";
|
||||
|
||||
$format = $format.$arg1.$arg2;
|
||||
$format = $format.$arg1.'x'.$arg2;
|
||||
|
||||
return $folder . "_resampled/$format-" . $this->Name;
|
||||
}
|
||||
@ -369,14 +371,11 @@ class Image extends File {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all of the formatted cached images for this image.
|
||||
*
|
||||
* @return int The number of formatted images deleted
|
||||
* Generate a list of images that were generated from this image
|
||||
*/
|
||||
public function deleteFormattedImages() {
|
||||
if(!$this->Filename) return 0;
|
||||
private function getGeneratedImages() {
|
||||
$generatedImages = array();
|
||||
|
||||
$numDeleted = 0;
|
||||
$methodNames = $this->allMethodNames(true);
|
||||
$cachedFiles = array();
|
||||
|
||||
@ -404,16 +403,52 @@ class Image extends File {
|
||||
}
|
||||
// All generate functions may appear any number of times in the image cache name.
|
||||
$generateFuncs = implode('|', $generateFuncs);
|
||||
$pattern = "/^(({$generateFuncs})\d+\-)+" . preg_quote($this->Name) . "$/i";
|
||||
$pattern = "/^((?P<Generator>{$generateFuncs})(?P<Arg1>\d*)x(?P<Arg2>\d*)\-)+" . preg_quote($this->Name) . "$/i";
|
||||
|
||||
foreach($cachedFiles as $cfile) {
|
||||
if(preg_match($pattern, $cfile)) {
|
||||
if(preg_match($pattern, $cfile, $matches)) {
|
||||
if(Director::fileExists($cacheDir . $cfile)) {
|
||||
unlink($cacheDir . $cfile);
|
||||
$generatedImages[] = array ( 'FileName' => $cacheDir . $cfile, 'Generator' => $matches['Generator'],
|
||||
'Arg1' => $matches['Arg1'], 'Arg2' => $matches['Arg2'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $generatedImages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate all of the formatted cached images for this image.
|
||||
*
|
||||
* @return int The number of formatted images regenerated
|
||||
*/
|
||||
public function regenerateFormattedImages() {
|
||||
if(!$this->Filename) return 0;
|
||||
|
||||
$numGenerated = 0;
|
||||
$generatedImages = $this->getGeneratedImages();
|
||||
foreach($generatedImages as $singleImage) {
|
||||
$this->generateFormattedImage($singleImage['Generator'], $singleImage['Arg1'],
|
||||
$singleImage['Arg2']);
|
||||
}
|
||||
|
||||
return $numGenerated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all of the formatted cached images for this image.
|
||||
*
|
||||
* @return int The number of formatted images deleted
|
||||
*/
|
||||
public function deleteFormattedImages() {
|
||||
if(!$this->Filename) return 0;
|
||||
|
||||
$numDeleted = 0;
|
||||
$generatedImages = $this->getGeneratedImages();
|
||||
foreach($generatedImages as $singleImage) {
|
||||
unlink($singleImage['FileName']);
|
||||
$numDeleted++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $numDeleted;
|
||||
}
|
||||
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Remove all cached/generated images that have been created as the result of a manipulation method being called on a
|
||||
* {@link Image} object
|
||||
*
|
||||
* @package framework
|
||||
* @subpackage filesystem
|
||||
*/
|
||||
class FlushGeneratedImagesTask extends BuildTask {
|
||||
|
||||
protected $title = 'Flush Generated Images Task';
|
||||
|
||||
protected $description = 'Remove all cached/generated images created as the result of an image manipulation';
|
||||
|
||||
/**
|
||||
* Check that the user has appropriate permissions to execute this task
|
||||
*/
|
||||
public function init() {
|
||||
if(!Director::is_cli() && !Director::isDev() && !Permission::check('ADMIN')) {
|
||||
return Security::permissionFailure();
|
||||
}
|
||||
|
||||
parent::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually clear out all the images
|
||||
*/
|
||||
public function run($request) {
|
||||
$processedImages = 0;
|
||||
$removedItems = 0;
|
||||
|
||||
if($images = DataObject::get('Image')) foreach($images as $image) {
|
||||
if($deleted = $image->deleteFormattedImages()) {
|
||||
$removedItems += $deleted;
|
||||
}
|
||||
|
||||
$processedImages++;
|
||||
}
|
||||
|
||||
echo "Removed $removedItems generated images from $processedImages Image objects stored in the Database.";
|
||||
}
|
||||
|
||||
}
|
44
tasks/RegenerateCachedImagesTask.php
Normal file
44
tasks/RegenerateCachedImagesTask.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Regenerate all cached images that have been created as the result of a manipulation method being called on a
|
||||
* {@link Image} object
|
||||
*
|
||||
* @package framework
|
||||
* @subpackage filesystem
|
||||
*/
|
||||
class RegenerateCachedImagesTask extends BuildTask {
|
||||
|
||||
protected $title = 'Regenerate Cached Images Task';
|
||||
|
||||
protected $description = 'Regenerate all cached images created as the result of an image manipulation';
|
||||
|
||||
/**
|
||||
* Check that the user has appropriate permissions to execute this task
|
||||
*/
|
||||
public function init() {
|
||||
if(!Director::is_cli() && !Director::isDev() && !Permission::check('ADMIN')) {
|
||||
return Security::permissionFailure();
|
||||
}
|
||||
|
||||
parent::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually regenerate all the images
|
||||
*/
|
||||
public function run($request) {
|
||||
$processedImages = 0;
|
||||
$regeneratedImages = 0;
|
||||
|
||||
if($images = DataObject::get('Image')) foreach($images as $image) {
|
||||
if($generated = $image->regenerateFormattedImages()) {
|
||||
$regeneratedImages += $generated;
|
||||
}
|
||||
|
||||
$processedImages++;
|
||||
}
|
||||
|
||||
echo "Regenerated $regeneratedImages cached images from $processedImages Image objects stored in the Database.";
|
||||
}
|
||||
|
||||
}
|
@ -41,7 +41,7 @@ class HtmlEditorFieldTest extends FunctionalTest {
|
||||
$obj = new HtmlEditorFieldTest_Object();
|
||||
$editor = new HtmlEditorField('Content');
|
||||
|
||||
$editor->setValue('<img src="assets/example.jpg" />');
|
||||
$editor->setValue('<img src="assets/HTMLEditorFieldTest_example.jpg" />');
|
||||
$editor->saveInto($obj);
|
||||
|
||||
$parser = new CSSContentParser($obj->Content);
|
||||
@ -49,13 +49,47 @@ class HtmlEditorFieldTest extends FunctionalTest {
|
||||
$this->assertEquals('', (string)$xml[0]['alt'], 'Alt tags are added by default.');
|
||||
$this->assertEquals('', (string)$xml[0]['title'], 'Title tags are added by default.');
|
||||
|
||||
$editor->setValue('<img src="assets/example.jpg" alt="foo" title="bar" />');
|
||||
$editor->setValue('<img src="assets/HTMLEditorFieldTest_example.jpg" alt="foo" title="bar" />');
|
||||
$editor->saveInto($obj);
|
||||
|
||||
$parser = new CSSContentParser($obj->Content);
|
||||
$xml = $parser->getByXpath('//img');
|
||||
$this->assertEquals('foo', (string)$xml[0]['alt'], 'Alt tags are preserved.');
|
||||
$this->assertEquals('bar', (string)$xml[0]['title'], 'Title tags are preserved.');
|
||||
$this->assertEquals(false, $obj->HasBrokenFile, 'Referenced image file exists.');
|
||||
}
|
||||
|
||||
public function testResizedImageInsertion() {
|
||||
$obj = new HtmlEditorFieldTest_Object();
|
||||
$editor = new HtmlEditorField('Content');
|
||||
|
||||
/*
|
||||
* Following stuff is neccessary to
|
||||
* a) use the proper filename for the image we are referencing
|
||||
* b) not confuse the "existing" filesystem by our test
|
||||
*/
|
||||
$imageFile = $this->objFromFixture('Image', 'example_image');
|
||||
$imageFile->Filename = FRAMEWORK_DIR . '/' . $imageFile->Filename;
|
||||
$origUpdateFilesystem = Config::inst()->get('File', 'update_filesystem');
|
||||
Config::inst()->update('File', 'update_filesystem', false);
|
||||
$imageFile->write();
|
||||
Config::inst()->update('File', 'update_filesystem', $origUpdateFilesystem);
|
||||
/*
|
||||
* End of test bet setting
|
||||
*/
|
||||
|
||||
$editor->setValue('<img src="assets/HTMLEditorFieldTest_example.jpg" width="10" height="20" />');
|
||||
$editor->saveInto($obj);
|
||||
|
||||
$parser = new CSSContentParser($obj->Content);
|
||||
$xml = $parser->getByXpath('//img');
|
||||
$this->assertEquals('', (string)$xml[0]['alt'], 'Alt tags are added by default.');
|
||||
$this->assertEquals('', (string)$xml[0]['title'], 'Title tags are added by default.');
|
||||
$this->assertEquals(10, (int)$xml[0]['width'], 'Width tag of resized image is set.');
|
||||
$this->assertEquals(20, (int)$xml[0]['height'], 'Height tag of resized image is set.');
|
||||
$this->assertEquals('assets/_resampled/resizedimage10x20-HTMLEditorFieldTest_example.jpg', (string)$xml[0]['src'], 'Correct URL of resized image is set.');
|
||||
$this->assertTrue(file_exists('assets/_resampled/resizedimage10x20-HTMLEditorFieldTest_example.jpg'), 'File for resized image exists');
|
||||
$this->assertEquals(false, $obj->HasBrokenFile, 'Referenced image file exists.');
|
||||
}
|
||||
|
||||
public function testMultiLineSaving() {
|
||||
@ -112,6 +146,7 @@ class HtmlEditorFieldTest_DummyMediaFormFieldExtension extends Extension impleme
|
||||
class HtmlEditorFieldTest_Object extends DataObject implements TestOnly {
|
||||
private static $db = array(
|
||||
'Title' => 'Varchar',
|
||||
'Content' => 'HTMLText'
|
||||
'Content' => 'HTMLText',
|
||||
'HasBrokenFile' => 'Boolean'
|
||||
);
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ File:
|
||||
|
||||
Image:
|
||||
example_image:
|
||||
Name: example.jpg
|
||||
Filename: folder/subfolder/example.jpg
|
||||
Name: HTMLEditorFieldTest_example.jpg
|
||||
Filename: tests/forms/images/HTMLEditorFieldTest_example.jpg
|
||||
|
||||
HtmlEditorFieldTest_Object:
|
||||
home:
|
||||
|
BIN
tests/forms/images/HTMLEditorFieldTest_example.jpg
Normal file
BIN
tests/forms/images/HTMLEditorFieldTest_example.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.9 KiB |
@ -50,6 +50,9 @@ class ImageTest extends SapphireTest {
|
||||
if($folder && file_exists(BASE_PATH."/$folder->Filename")) {
|
||||
Filesystem::removeFolder(BASE_PATH."/$folder->Filename");
|
||||
}
|
||||
if($folder && file_exists(BASE_PATH."/".$folder->Filename."_resampled")) {
|
||||
Filesystem::removeFolder(BASE_PATH."/".$folder->Filename."_resampled");
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
@ -102,8 +105,9 @@ class ImageTest extends SapphireTest {
|
||||
$image = $this->objFromFixture('Image', 'imageWithMetacharacters');
|
||||
$image_generated = $image->SetWidth(200);
|
||||
$p = $image_generated->getFullPath();
|
||||
$this->assertTrue(file_exists($p));
|
||||
$image->deleteFormattedImages();
|
||||
$this->assertFalse(file_exists($p));
|
||||
$this->assertTrue(file_exists($p), 'Resized image exists after creation call');
|
||||
$numDeleted = $image->deleteFormattedImages();
|
||||
$this->assertEquals(1, $numDeleted, 'Expected one image to be deleted, but deleted ' . $numDeleted . ' images');
|
||||
$this->assertFalse(file_exists($p), 'Resized image not existing after deletion call');
|
||||
}
|
||||
}
|
||||
|
@ -14,5 +14,5 @@ Image:
|
||||
Parent: =>Folder.folder1
|
||||
imageWithMetacharacters:
|
||||
Title: This is a/an image Title
|
||||
Filename: assets/ImageTest/test_image).png
|
||||
Filename: assets/ImageTest/test_image.png
|
||||
Parent: =>Folder.folder1
|
||||
|
Loading…
Reference in New Issue
Block a user