mujma: ENHANCEMENT: Added garbage collection (merged from gsoc branch, r40463, r42790, r41070)

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@42958 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Andrew O'Neil 2007-10-02 21:34:57 +00:00
parent ab88be37fe
commit 6aed530816
4 changed files with 182 additions and 10 deletions

View File

@ -236,7 +236,7 @@ HTML;
$fileList->setFolder($record); $fileList->setFolder($record);
$fileList->setPopupCaption("View/Edit Asset"); $fileList->setPopupCaption("View/Edit Asset");
if($record) { if($record) {
$nameField = ($id != "root") ? new TextField("Name", "Folder Name") : new HiddenField("Name"); $nameField = ($id != "root") ? new TextField("Name", "Folder Name") : new HiddenField("Name");
if( $record->userCanEdit() ) { if( $record->userCanEdit() ) {
$deleteButton = new InlineFormAction('deletemarked',_t('AssetAdmin.DELSELECTED','Delete selected files'), 'delete'); $deleteButton = new InlineFormAction('deletemarked',_t('AssetAdmin.DELSELECTED','Delete selected files'), 'delete');
@ -265,8 +265,21 @@ HTML;
new LiteralField("UploadIframe", new LiteralField("UploadIframe",
$this->getUploadIframe() $this->getUploadIframe()
) )
) ),
), new Tab("Unused files",
new LiteralField("UnusedAssets",
"<div id=\"UnusedAssets\"><p>Unused files</p>"
),
$this->getAssetList(),
new LiteralField("UnusedThumbnails",
"</div>
<div id=\"UnusedThumbnails\">
<p>Unused thumbnails</p>
<a id=\"UnusedThumbnails\" href=\"#\">Delete unused thumbnails</a>
</div>"
)
)
),
new HiddenField("ID") new HiddenField("ID")
); );
@ -668,4 +681,136 @@ JS;
return parent::save($urlParams, $form); return parent::save($urlParams, $form);
} }
/**
* #################################
* Garbage collection.
* #################################
*/
/**
* Removes all unused thumbnails, and echos status message to user.
*
* @returns null
*/
public function deleteUnusedThumbnails() {
foreach($this->getUnusedThumbnailsArray() as $file) {
unlink("../assets/" . $file);
}
echo "statusMessage('All unused thumbnails has been deleted','good')";
}
/**
* Looks for files used in system and create where clause which contains all ID's of files.
*
* @returns String where clause which will work as filter.
*/
private function getUsedFilesList() {
$result = DB::query("SELECT DISTINCT FileID FROM SiteTree_ImageTracking");
$usedFiles = array();
$where = "";
if($result->numRecords() > 0) {
while($nextResult = $result->next()){
$where .= $nextResult['FileID'] . ',';
}
}
$classes = ClassInfo::subclassesFor('SiteTree');
foreach($classes as $className) {
$sng = singleton($className);
$objects = DataObject::get($className);
if($objects !== NULL) {
foreach($sng->has_one() as $fieldName => $joinClass) {
if($joinClass == 'Image' || $joinClass == 'File') {
foreach($objects as $object) {
if($object->$fieldName != NULL) $usedFiles[] = $object->$fieldName;
}
} elseif($joinClass == 'Folder') {
/*foreach($objects as $object) {
var_dump($object->$fieldName);
}*/
}
}
}
}
foreach($usedFiles as $file) {
$where .= $file->ID . ',';
}
if($where == "") return "(ClassName = 'File' OR ClassName = 'Image')";
$where = substr($where,0,strlen($where)-1);
$where = "ID NOT IN (" . $where . ") AND (ClassName = 'File' OR ClassName = 'Image')";
return $where;
}
/**
* Creates table for displaying unused files.
*
* @returns AssetTableField
*/
private function getAssetList() {
$where = $this->getUsedFilesList();
$assetList = new AssetTableField(
$this,
"AssetList",
"File",
array("Title" => "Title", "LinkedURL" => "Filename"),
"",
$where
);
$assetList->setPopupCaption("View Asset");
$assetList->setPermissions(array("show","delete"));
$assetList->Markable = false;
return $assetList;
}
/**
* Creates array containg all unused thumbnails.
* Array is created in three steps:
* 1.Scan assets folder and retrieve all thumbnails
* 2.Scan all HTMLField in system and retrieve thumbnails from them.
* 3.Count difference between two sets (array_diff)
*
* @returns Array
*/
private function getUnusedThumbnailsArray() {
$allThumbnails = array();
$dirIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('../assets'));
foreach ($dirIterator as $file) {
if($file->isFile()) {
if(strpos($file->getPathname(),"_resampled") !== false) {
$pathInfo = pathinfo($file->getPathname());
if(in_array(strtolower($pathInfo['extension']),array('jpeg','jpg','jpe','png','gif'))) {
$path = str_replace('\\','/',$file->getPathname());
$allThumbnails[] = substr($path,strpos($path,'/assets/')+8);
}
}
}
}
$classes = ClassInfo::subclassesFor('SiteTree');
$usedThumbnails = array();
foreach($classes as $className) {
$sng = singleton($className);
$objects = DataObject::get($className);
if($objects !== NULL) {
foreach($objects as $object) {
foreach($sng->db() as $fieldName => $fieldType) {
if($fieldType == 'HTMLText') {
$url1 = HTTP::findByTagAndAttribute($object->$fieldName,array("img" => "src"));
if($url1 != NULL) $usedThumbnails[] = substr($url1[0],strpos($url1[0],'/assets/')+8);
if($object->latestPublished > 0) {
$object = Versioned::get_latest_version($className, $object->ID);
$url2 = HTTP::findByTagAndAttribute($object->$fieldName,array("img" => "src"));
if($url2 != NULL) $usedThumbnails[] = substr($url2[0],strpos($url2[0],'/assets/')+8);
}
}
}
}
}
}
return array_diff($allThumbnails,$usedThumbnails);
}
} }

View File

@ -5,6 +5,11 @@ class AssetTableField extends ComplexTableField {
protected $template = "AssetTableField"; protected $template = "AssetTableField";
protected $permissions = array(
"edit",
"delete",
//"export",
);
function __construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter = "", $sourceSort = "", $sourceJoin = "") { function __construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter = "", $sourceSort = "", $sourceJoin = "") {
parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin); parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin);
@ -25,7 +30,7 @@ class AssetTableField extends ComplexTableField {
} }
function sourceID() { function sourceID() {
return $this->folder->ID; if($this->folder) return $this->folder->ID;
} }
function DetailForm() { function DetailForm() {

View File

@ -471,3 +471,18 @@ appendLoader(function () {
$('deletepage_options').onsubmit = deletefolder.form_submit; $('deletepage_options').onsubmit = deletefolder.form_submit;
} }
}); });
Behaviour.register({
'#UnusedThumbnails': {
onclick : function(event) {
Event.stop(event);
var options = {
method: 'get',
onSuccess: function(t) {
eval(t.responseText);
}
};
new Ajax.Request('admin/assets/deleteUnusedThumbnails',options);
}
}
});

View File

@ -18,10 +18,17 @@
<% control Fields %> <% control Fields %>
<td>$Value</td> <td>$Value</td>
<% end_control %> <% end_control %>
<td width="18"> <% if Can(show) %>
<a class="popuplink editlink" href="$EditLink" target="_blank" title="Edit asset"><img src="cms/images/edit.gif" alt="edit" /></a> <td width="18">
</td> <a class="popuplink showlink" href="$ShowLink" target="_blank" title="Show asset"><img src="cms/images/show.png" alt="show" /></a>
<% if Can(delete) %> </td>
<% end_if %>
<% if Can(edit) %>
<td width="18">
<a class="popuplink editlink" href="$EditLink" target="_blank" title="Edit asset"><img src="cms/images/edit.gif" alt="edit" /></a>
</td>
<% end_if %>
<% if Can(delete) %>
<td width="18"> <td width="18">
<a class="deletelink" href="admin/assets/removefile/$ID" title="Delete this file"><img src="cms/images/delete.gif" alt="delete" title="<% _t('DELFILE','Delete this file') %>" /></a> <a class="deletelink" href="admin/assets/removefile/$ID" title="Delete this file"><img src="cms/images/delete.gif" alt="delete" title="<% _t('DELFILE','Delete this file') %>" /></a>
</td> </td>