2007-07-19 12:40:05 +02:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* AssetAdmin is the 'file store' section of the CMS.
|
|
|
|
* It provides an interface for maniupating the File and Folder objects in the system.
|
2008-04-06 10:20:13 +02:00
|
|
|
*
|
2008-02-25 03:10:37 +01:00
|
|
|
* @package cms
|
|
|
|
* @subpackage assets
|
2007-07-19 12:40:05 +02:00
|
|
|
*/
|
|
|
|
class AssetAdmin extends LeftAndMain {
|
2008-04-06 10:20:13 +02:00
|
|
|
|
2008-11-02 22:27:55 +01:00
|
|
|
static $url_segment = 'assets';
|
|
|
|
|
|
|
|
static $url_rule = '/$Action/$ID';
|
|
|
|
|
|
|
|
static $menu_title = 'Files & Images';
|
|
|
|
|
2008-12-04 23:38:58 +01:00
|
|
|
public static $tree_class = 'File';
|
2008-04-06 10:20:13 +02:00
|
|
|
|
|
|
|
/**
|
2008-10-02 02:34:41 +02:00
|
|
|
* @see Upload->allowedMaxFileSize
|
2008-04-06 10:20:13 +02:00
|
|
|
* @var int
|
|
|
|
*/
|
|
|
|
public static $allowed_max_file_size;
|
|
|
|
|
|
|
|
/**
|
2008-10-02 02:34:41 +02:00
|
|
|
* @see Upload->allowedExtensions
|
2008-04-06 10:20:13 +02:00
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
public static $allowed_extensions = array();
|
2008-02-25 03:10:37 +01:00
|
|
|
|
2009-08-11 03:08:29 +02:00
|
|
|
/**
|
|
|
|
* If this is true, then restrictions set in $allowed_max_file_size and
|
|
|
|
* $allowed_extensions will be applied to users with admin privileges as
|
|
|
|
* well.
|
|
|
|
*/
|
|
|
|
public static $apply_restrictions_to_admin = false;
|
|
|
|
|
2008-02-25 03:10:37 +01:00
|
|
|
static $allowed_actions = array(
|
|
|
|
'addfolder',
|
|
|
|
'deletefolder',
|
|
|
|
'deletemarked',
|
2009-01-06 03:18:33 +01:00
|
|
|
'DeleteItemsForm',
|
2008-02-25 03:10:37 +01:00
|
|
|
'deleteUnusedThumbnails',
|
|
|
|
'doUpload',
|
|
|
|
'getfile',
|
|
|
|
'getsubtree',
|
|
|
|
'movemarked',
|
|
|
|
'removefile',
|
|
|
|
'save',
|
|
|
|
'savefile',
|
|
|
|
'uploadiframe',
|
2008-08-09 07:57:44 +02:00
|
|
|
'UploadForm',
|
2008-05-24 07:19:42 +02:00
|
|
|
'deleteUnusedThumbnails' => 'ADMIN'
|
2008-02-25 03:10:37 +01:00
|
|
|
);
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return fake-ID "root" if no ID is found (needed to upload files into the root-folder)
|
|
|
|
*/
|
|
|
|
public function currentPageID() {
|
|
|
|
if(isset($_REQUEST['ID']) && is_numeric($_REQUEST['ID'])) {
|
|
|
|
return $_REQUEST['ID'];
|
|
|
|
} elseif (is_numeric($this->urlParams['ID'])) {
|
|
|
|
return $this->urlParams['ID'];
|
|
|
|
} elseif(is_numeric(Session::get("{$this->class}.currentPage"))) {
|
|
|
|
return Session::get("{$this->class}.currentPage");
|
|
|
|
} else {
|
|
|
|
return "root";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set up the controller, in particular, re-sync the File database with the assets folder./
|
|
|
|
*/
|
|
|
|
function init() {
|
|
|
|
parent::init();
|
2007-10-29 03:10:59 +01:00
|
|
|
|
ENHANCEMENT Introduced constants for system paths like /sapphire in preparation for a more flexible directory reorganisation. Instead of hardcoding your path, please use the following constants: BASE_PATH, BASE_URL, SAPPHIRE_DIR, SAPPHIRE_PATH, CMS_DIR, CMS_PATH, THIRDPARTY_DIR, THIRDPARTY_PATH, ASSETS_DIR, ASSETS_PATH, THEMES_DIR, THEMES_PATH
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@63154 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-09-27 18:02:38 +02:00
|
|
|
if(!file_exists(ASSETS_PATH)) {
|
|
|
|
mkdir(ASSETS_PATH);
|
2007-10-29 03:10:59 +01:00
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
// needed for MemberTableField (Requirements not determined before Ajax-Call)
|
ENHANCEMENT Introduced constants for system paths like /sapphire in preparation for a more flexible directory reorganisation. Instead of hardcoding your path, please use the following constants: BASE_PATH, BASE_URL, SAPPHIRE_DIR, SAPPHIRE_PATH, CMS_DIR, CMS_PATH, THIRDPARTY_DIR, THIRDPARTY_PATH, ASSETS_DIR, ASSETS_PATH, THEMES_DIR, THEMES_PATH
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@63154 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-09-27 18:02:38 +02:00
|
|
|
Requirements::css(THIRDPARTY_DIR . "/greybox/greybox.css");
|
|
|
|
Requirements::css(SAPPHIRE_DIR . "/css/ComplexTableField.css");
|
|
|
|
|
|
|
|
Requirements::javascript(CMS_DIR . "/javascript/AssetAdmin.js");
|
|
|
|
|
|
|
|
Requirements::javascript(CMS_DIR . "/javascript/CMSMain_upload.js");
|
|
|
|
Requirements::javascript(CMS_DIR . "/javascript/Upload.js");
|
|
|
|
Requirements::javascript(THIRDPARTY_DIR . "/SWFUpload/SWFUpload.js");
|
2007-07-19 12:40:05 +02:00
|
|
|
|
ENHANCEMENT Introduced constants for system paths like /sapphire in preparation for a more flexible directory reorganisation. Instead of hardcoding your path, please use the following constants: BASE_PATH, BASE_URL, SAPPHIRE_DIR, SAPPHIRE_PATH, CMS_DIR, CMS_PATH, THIRDPARTY_DIR, THIRDPARTY_PATH, ASSETS_DIR, ASSETS_PATH, THEMES_DIR, THEMES_PATH
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@63154 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-09-27 18:02:38 +02:00
|
|
|
Requirements::javascript(THIRDPARTY_DIR . "/greybox/AmiJS.js");
|
|
|
|
Requirements::javascript(THIRDPARTY_DIR . "/greybox/greybox.js");
|
|
|
|
Requirements::css(THIRDPARTY_DIR . "/greybox/greybox.css");
|
2007-09-27 22:56:55 +02:00
|
|
|
|
ENHANCEMENT Introduced constants for system paths like /sapphire in preparation for a more flexible directory reorganisation. Instead of hardcoding your path, please use the following constants: BASE_PATH, BASE_URL, SAPPHIRE_DIR, SAPPHIRE_PATH, CMS_DIR, CMS_PATH, THIRDPARTY_DIR, THIRDPARTY_PATH, ASSETS_DIR, ASSETS_PATH, THEMES_DIR, THEMES_PATH
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@63154 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-09-27 18:02:38 +02:00
|
|
|
Requirements::css(CMS_DIR . "/css/AssetAdmin.css");
|
2008-11-22 04:47:56 +01:00
|
|
|
|
|
|
|
Requirements::customScript(<<<JS
|
|
|
|
_TREE_ICONS = {};
|
|
|
|
_TREE_ICONS['Folder'] = {
|
|
|
|
fileIcon: 'jsparty/tree/images/page-closedfolder.gif',
|
|
|
|
openFolderIcon: 'jsparty/tree/images/page-openfolder.gif',
|
|
|
|
closedFolderIcon: 'jsparty/tree/images/page-closedfolder.gif'
|
|
|
|
};
|
|
|
|
JS
|
|
|
|
);
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Show the content of the upload iframe. The form is specified by a template.
|
|
|
|
*/
|
|
|
|
function uploadiframe() {
|
|
|
|
Requirements::clear();
|
|
|
|
|
ENHANCEMENT Introduced constants for system paths like /sapphire in preparation for a more flexible directory reorganisation. Instead of hardcoding your path, please use the following constants: BASE_PATH, BASE_URL, SAPPHIRE_DIR, SAPPHIRE_PATH, CMS_DIR, CMS_PATH, THIRDPARTY_DIR, THIRDPARTY_PATH, ASSETS_DIR, ASSETS_PATH, THEMES_DIR, THEMES_PATH
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@63154 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-09-27 18:02:38 +02:00
|
|
|
Requirements::javascript(THIRDPARTY_DIR . "/prototype.js");
|
|
|
|
Requirements::javascript(THIRDPARTY_DIR . "/loader.js");
|
|
|
|
Requirements::javascript(THIRDPARTY_DIR . "/behaviour.js");
|
|
|
|
Requirements::javascript(THIRDPARTY_DIR . "/prototype_improvements.js");
|
|
|
|
Requirements::javascript(THIRDPARTY_DIR . "/layout_helpers.js");
|
|
|
|
Requirements::javascript(CMS_DIR . "/javascript/LeftAndMain.js");
|
|
|
|
Requirements::javascript(THIRDPARTY_DIR . "/multifile/multifile.js");
|
|
|
|
Requirements::css(THIRDPARTY_DIR . "/multifile/multifile.css");
|
|
|
|
Requirements::css(CMS_DIR . "/css/typography.css");
|
|
|
|
Requirements::css(CMS_DIR . "/css/layout.css");
|
|
|
|
Requirements::css(CMS_DIR . "/css/cms_left.css");
|
|
|
|
Requirements::css(CMS_DIR . "/css/cms_right.css");
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
if(isset($data['ID']) && $data['ID'] != 'root') $folder = DataObject::get_by_id("Folder", $data['ID']);
|
|
|
|
else $folder = singleton('Folder');
|
|
|
|
|
2009-07-02 09:23:29 +02:00
|
|
|
// Don't modify the output of the template, or it will become invalid
|
|
|
|
ContentNegotiator::disable();
|
|
|
|
|
2008-11-07 13:21:41 +01:00
|
|
|
return array( 'CanUpload' => $folder->canEdit());
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the form object shown in the uploadiframe.
|
|
|
|
*/
|
|
|
|
function UploadForm() {
|
2009-01-05 07:17:59 +01:00
|
|
|
// disabled flash upload javascript (CMSMain_upload()) below,
|
|
|
|
// see r54952 (originally committed in r42014)
|
2008-04-26 08:39:23 +02:00
|
|
|
$form = new Form($this,'UploadForm', new FieldSet(
|
2007-07-19 12:40:05 +02:00
|
|
|
new HiddenField("ID", "", $this->currentPageID()),
|
|
|
|
// needed because the button-action is triggered outside the iframe
|
|
|
|
new HiddenField("action_doUpload", "", "1"),
|
2009-02-03 04:46:15 +01:00
|
|
|
new FileField("Files[0]" , _t('AssetAdmin.CHOOSEFILE','Choose file: ')),
|
2007-07-19 12:40:05 +02:00
|
|
|
new LiteralField('UploadButton',"
|
2009-07-02 09:23:29 +02:00
|
|
|
<input type=\"submit\" value=\"". _t('AssetAdmin.UPLOAD', 'Upload Files Listed Below'). "\" name=\"action_upload\" id=\"Form_UploadForm_action_upload\" class=\"action\" />
|
2007-07-19 12:40:05 +02:00
|
|
|
"),
|
|
|
|
new LiteralField('MultifileCode',"
|
2007-09-16 18:33:05 +02:00
|
|
|
<p>" . _t('AssetAdmin.FILESREADY','Files ready to upload:') ."</p>
|
2009-07-02 09:23:29 +02:00
|
|
|
<div id=\"Form_UploadForm_FilesList\"></div>
|
2007-07-19 12:40:05 +02:00
|
|
|
")
|
|
|
|
), new FieldSet(
|
|
|
|
));
|
2008-04-26 08:39:23 +02:00
|
|
|
|
|
|
|
// Makes ajax easier
|
|
|
|
$form->disableSecurityToken();
|
|
|
|
|
|
|
|
return $form;
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method processes the results of the UploadForm.
|
|
|
|
* It will save the uploaded files to /assets/ and create new File objects as required.
|
|
|
|
*/
|
|
|
|
function doUpload($data, $form) {
|
|
|
|
foreach($data['Files'] as $param => $files) {
|
2007-09-16 03:40:26 +02:00
|
|
|
if(!is_array($files)) $files = array($files);
|
2007-07-19 12:40:05 +02:00
|
|
|
foreach($files as $key => $value) {
|
|
|
|
$processedFiles[$key][$param] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if($data['ID'] && $data['ID'] != 'root') $folder = DataObject::get_by_id("Folder", $data['ID']);
|
|
|
|
else $folder = singleton('Folder');
|
|
|
|
|
2007-08-21 04:32:20 +02:00
|
|
|
$newFiles = array();
|
2007-07-19 12:40:05 +02:00
|
|
|
$fileSizeWarnings = '';
|
2007-08-21 04:32:20 +02:00
|
|
|
$uploadErrors = '';
|
2008-09-01 06:54:48 +02:00
|
|
|
$jsErrors = '';
|
2009-01-05 07:17:59 +01:00
|
|
|
$status = '';
|
|
|
|
$statusMessage = '';
|
2007-08-21 04:32:20 +02:00
|
|
|
|
2008-04-06 10:20:13 +02:00
|
|
|
foreach($processedFiles as $tmpFile) {
|
|
|
|
if($tmpFile['error'] == UPLOAD_ERR_NO_TMP_DIR) {
|
2007-08-21 04:32:20 +02:00
|
|
|
$status = 'bad';
|
2008-02-25 03:10:37 +01:00
|
|
|
$statusMessage = _t('AssetAdmin.NOTEMP', 'There is no temporary folder for uploads. Please set upload_tmp_dir in php.ini.');
|
2007-08-21 04:32:20 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-04-06 10:20:13 +02:00
|
|
|
if($tmpFile['tmp_name']) {
|
2007-08-21 04:32:20 +02:00
|
|
|
// Workaround open_basedir problems
|
|
|
|
if(ini_get("open_basedir")) {
|
2008-04-06 10:20:13 +02:00
|
|
|
$newtmp = TEMP_FOLDER . '/' . $tmpFile['name'];
|
|
|
|
move_uploaded_file($tmpFile['tmp_name'], $newtmp);
|
|
|
|
$tmpFile['tmp_name'] = $newtmp;
|
2007-08-21 04:32:20 +02:00
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
|
2008-04-06 10:20:13 +02:00
|
|
|
// validate files (only if not logged in as admin)
|
2009-08-11 03:08:29 +02:00
|
|
|
if(!self::$apply_restrictions_to_admin && Permission::check('ADMIN')) {
|
2008-04-06 10:20:13 +02:00
|
|
|
$valid = true;
|
2007-07-19 12:40:05 +02:00
|
|
|
} else {
|
2008-04-06 10:20:13 +02:00
|
|
|
$upload = new Upload();
|
|
|
|
$upload->setAllowedExtensions(self::$allowed_extensions);
|
|
|
|
$upload->setAllowedMaxFileSize(self::$allowed_max_file_size);
|
|
|
|
$valid = $upload->validate($tmpFile);
|
|
|
|
if(!$valid) {
|
|
|
|
$errors = $upload->getErrors();
|
|
|
|
if($errors) foreach($errors as $error) {
|
|
|
|
$jsErrors .= "alert('" . Convert::raw2js($error) . "');";
|
|
|
|
}
|
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
2008-04-06 10:20:13 +02:00
|
|
|
|
|
|
|
// move file to given folder
|
|
|
|
if($valid) $newFiles[] = $folder->addUploadToFolder($tmpFile);
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if($newFiles) {
|
|
|
|
$numFiles = sizeof($newFiles);
|
2007-09-16 18:33:05 +02:00
|
|
|
$statusMessage = sprintf(_t('AssetAdmin.UPLOADEDX',"Uploaded %s files"),$numFiles) ;
|
2007-07-19 12:40:05 +02:00
|
|
|
$status = "good";
|
2007-08-21 04:32:20 +02:00
|
|
|
} else if($status != 'bad') {
|
2007-09-16 18:33:05 +02:00
|
|
|
$statusMessage = _t('AssetAdmin.NOTHINGTOUPLOAD','There was nothing to upload');
|
2007-07-19 12:40:05 +02:00
|
|
|
$status = "";
|
|
|
|
}
|
2008-02-25 03:10:37 +01:00
|
|
|
|
|
|
|
$fileIDs = array();
|
|
|
|
$fileNames = array();
|
|
|
|
foreach($newFiles as $newFile) {
|
|
|
|
$fileIDs[] = $newFile;
|
2008-11-24 10:30:41 +01:00
|
|
|
$fileObj = DataObject::get_one('File', "\"File\".\"ID\"=$newFile");
|
2009-04-29 03:44:28 +02:00
|
|
|
// notify file object after uploading
|
|
|
|
if (method_exists($fileObj, 'onAfterUpload')) $fileObj->onAfterUpload();
|
2008-02-25 03:10:37 +01:00
|
|
|
$fileNames[] = $fileObj->Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
$sFileIDs = implode(',', $fileIDs);
|
|
|
|
$sFileNames = implode(',', $fileNames);
|
2008-04-26 08:39:23 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
echo <<<HTML
|
|
|
|
<script type="text/javascript">
|
2008-02-25 03:10:37 +01:00
|
|
|
/* IDs: $sFileIDs */
|
|
|
|
/* Names: $sFileNames */
|
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
var form = parent.document.getElementById('Form_EditForm');
|
|
|
|
form.getPageFromServer(form.elements.ID.value);
|
|
|
|
parent.statusMessage("{$statusMessage}","{$status}");
|
2008-04-06 10:20:13 +02:00
|
|
|
$jsErrors
|
2007-07-19 12:40:05 +02:00
|
|
|
parent.document.getElementById('sitetree').getTreeNodeByIdx( "{$folder->ID}" ).getElementsByTagName('a')[0].className += ' contents';
|
|
|
|
</script>
|
|
|
|
HTML;
|
|
|
|
}
|
2009-04-29 03:44:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Custom currentPage() method to handle opening the 'root' folder
|
|
|
|
*/
|
|
|
|
public function currentPage() {
|
|
|
|
$id = $this->currentPageID();
|
|
|
|
if($id && is_numeric($id)) {
|
|
|
|
return DataObject::get_by_id($this->stat('tree_class'), $id);
|
|
|
|
} else if($id == 'root') {
|
|
|
|
return singleton($this->stat('tree_class'));
|
|
|
|
}
|
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the form that displays the details of a folder, including a file list and fields for editing the folder name.
|
|
|
|
*/
|
|
|
|
function getEditForm($id) {
|
|
|
|
if($id && $id != "root") {
|
|
|
|
$record = DataObject::get_by_id("File", $id);
|
|
|
|
} else {
|
|
|
|
$record = singleton("Folder");
|
|
|
|
}
|
2009-07-02 00:28:06 +02:00
|
|
|
|
2008-02-25 03:10:37 +01:00
|
|
|
if($record) {
|
|
|
|
$fields = $record->getCMSFields();
|
2007-07-19 12:40:05 +02:00
|
|
|
$actions = new FieldSet();
|
|
|
|
|
2007-09-15 22:47:35 +02:00
|
|
|
// Only show save button if not 'assets' folder
|
2008-12-04 23:38:58 +01:00
|
|
|
if($record->canEdit() && $id != 'root') {
|
2007-07-19 12:40:05 +02:00
|
|
|
$actions = new FieldSet(
|
2007-09-16 18:33:05 +02:00
|
|
|
new FormAction('save',_t('AssetAdmin.SAVEFOLDERNAME','Save folder name'))
|
2007-07-19 12:40:05 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$form = new Form($this, "EditForm", $fields, $actions);
|
|
|
|
if($record->ID) {
|
|
|
|
$form->loadDataFrom($record);
|
|
|
|
} else {
|
|
|
|
$form->loadDataFrom(array(
|
|
|
|
"ID" => "root",
|
|
|
|
"URL" => Director::absoluteBaseURL() . 'assets/',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2008-12-04 23:38:58 +01:00
|
|
|
if(!$record->canEdit()) {
|
2007-07-19 12:40:05 +02:00
|
|
|
$form->makeReadonly();
|
2008-12-04 23:38:58 +01:00
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
return $form;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Perform the "move marked" action.
|
2007-09-15 22:47:35 +02:00
|
|
|
* Called and returns in same way as 'save' function
|
2007-07-19 12:40:05 +02:00
|
|
|
*/
|
2007-09-15 22:47:35 +02:00
|
|
|
public function movemarked($urlParams, $form) {
|
2009-02-03 03:50:25 +01:00
|
|
|
if($_REQUEST['DestFolderID'] && (is_numeric($_REQUEST['DestFolderID']) || ($_REQUEST['DestFolderID']) == 'root')) {
|
|
|
|
$destFolderID = ($_REQUEST['DestFolderID'] == 'root') ? 0 : $_REQUEST['DestFolderID'];
|
2007-07-19 12:40:05 +02:00
|
|
|
$fileList = "'" . ereg_replace(' *, *',"','",trim(addslashes($_REQUEST['FileIDs']))) . "'";
|
|
|
|
$numFiles = 0;
|
|
|
|
|
|
|
|
if($fileList != "''") {
|
2008-11-24 10:30:41 +01:00
|
|
|
$files = DataObject::get("File", "\"File\".\"ID\" IN ($fileList)");
|
2007-07-19 12:40:05 +02:00
|
|
|
if($files) {
|
|
|
|
foreach($files as $file) {
|
2007-09-15 22:30:54 +02:00
|
|
|
if($file instanceof Image) {
|
2008-12-04 23:38:58 +01:00
|
|
|
$file->deleteFormattedImages();
|
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
$file->ParentID = $destFolderID;
|
|
|
|
$file->write();
|
|
|
|
$numFiles++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
user_error("No files in $fileList could be found!", E_USER_ERROR);
|
|
|
|
}
|
|
|
|
}
|
2007-09-15 22:47:35 +02:00
|
|
|
|
2007-09-16 18:33:05 +02:00
|
|
|
$message = sprintf(_t('AssetAdmin.MOVEDX','Moved %s files'),$numFiles);
|
2008-12-04 23:38:58 +01:00
|
|
|
|
2007-09-15 22:47:35 +02:00
|
|
|
FormResponse::status_message($message, "good");
|
2009-10-21 06:39:50 +02:00
|
|
|
FormResponse::add("$('Form_EditForm_Files').refresh();");
|
2008-12-04 23:38:58 +01:00
|
|
|
|
2009-10-21 06:35:25 +02:00
|
|
|
return FormResponse::respond();
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Perform the "delete marked" action.
|
2007-09-15 22:47:35 +02:00
|
|
|
* Called and returns in same way as 'save' function
|
2007-07-19 12:40:05 +02:00
|
|
|
*/
|
2007-09-15 22:47:35 +02:00
|
|
|
public function deletemarked($urlParams, $form) {
|
2008-12-04 23:38:58 +01:00
|
|
|
$fileList = "'" . ereg_replace(' *, *',"','",trim(addslashes($_REQUEST['FileIDs']))) . "'";
|
|
|
|
$numFiles = 0;
|
|
|
|
$folderID = 0;
|
|
|
|
$deleteList = '';
|
|
|
|
$brokenPageList = '';
|
|
|
|
|
|
|
|
if($fileList != "''") {
|
|
|
|
$files = DataObject::get("File", "\"File\".\"ID\" IN ($fileList)");
|
|
|
|
if($files) {
|
|
|
|
foreach($files as $file) {
|
|
|
|
if($file instanceof Image) {
|
|
|
|
$file->deleteFormattedImages();
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
2008-12-04 23:38:58 +01:00
|
|
|
if(!$folderID) {
|
|
|
|
$folderID = $file->ParentID;
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
2008-12-04 23:38:58 +01:00
|
|
|
$file->delete();
|
|
|
|
$numFiles++;
|
|
|
|
}
|
|
|
|
if($brokenPages = Notifications::getItems('BrokenLink')) {
|
|
|
|
$brokenPageList = " ". _t('AssetAdmin.NOWBROKEN', 'These pages now have broken links:') . '</ul>';
|
|
|
|
foreach($brokenPages as $brokenPage) {
|
|
|
|
$brokenPageList .= "<li style="font-size: 65%">" . $brokenPage->Breadcrumbs(3, true) . '</li>';
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
2008-12-04 23:38:58 +01:00
|
|
|
$brokenPageList .= '</ul>';
|
|
|
|
Notifications::notifyByEmail("BrokenLink", "Page_BrokenLinkEmail");
|
2007-07-19 12:40:05 +02:00
|
|
|
} else {
|
2008-12-04 23:38:58 +01:00
|
|
|
$brokenPageList = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
$deleteList = '';
|
|
|
|
if($folderID) {
|
|
|
|
$remaining = DB::query("SELECT COUNT(*) FROM \"File\" WHERE \"ParentID\" = $folderID")->value();
|
|
|
|
if(!$remaining) $deleteList .= "Element.removeClassName(\$('sitetree').getTreeNodeByIdx('$folderID').getElementsByTagName('a')[0],'contents');";
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
2008-12-04 23:38:58 +01:00
|
|
|
} else {
|
|
|
|
user_error("No files in $fileList could be found!", E_USER_ERROR);
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
2008-12-04 23:38:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$message = sprintf(_t('AssetAdmin.DELETEDX',"Deleted %s files.%s"),$numFiles,$brokenPageList) ;
|
|
|
|
|
|
|
|
FormResponse::add($deleteList);
|
|
|
|
FormResponse::status_message($message, "good");
|
|
|
|
FormResponse::add("$('Form_EditForm').getPageFromServer($('Form_EditForm_ID').value)");
|
|
|
|
|
|
|
|
return FormResponse::respond();
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the content to be placed in Form_SubForm when editing a file.
|
|
|
|
* Called using ajax.
|
|
|
|
*/
|
|
|
|
public function getfile() {
|
|
|
|
SSViewer::setOption('rewriteHashlinks', false);
|
|
|
|
|
|
|
|
// bdc: only try to return something if user clicked on an object
|
|
|
|
if (is_object($this->getSubForm($this->urlParams['ID']))) {
|
|
|
|
return $this->getSubForm($this->urlParams['ID'])->formHtmlContent();
|
|
|
|
}
|
|
|
|
else return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Action handler for the save button on the file subform.
|
|
|
|
* Saves the file
|
|
|
|
*/
|
|
|
|
public function savefile($data, $form) {
|
|
|
|
$record = DataObject::get_by_id("File", $data['ID']);
|
|
|
|
$form->saveInto($record);
|
|
|
|
$record->write();
|
|
|
|
$title = Convert::raw2js($record->Title);
|
|
|
|
$name = Convert::raw2js($record->Name);
|
2007-09-16 18:33:05 +02:00
|
|
|
$saved = sprintf(_t('AssetAdmin.SAVEDFILE','Saved file %s'),"#$data[ID]");
|
2007-07-19 12:40:05 +02:00
|
|
|
echo <<<JS
|
2007-09-16 18:33:05 +02:00
|
|
|
statusMessage('$saved');
|
2007-07-19 12:40:05 +02:00
|
|
|
$('record-$data[ID]').getElementsByTagName('td')[1].innerHTML = "$title";
|
|
|
|
$('record-$data[ID]').getElementsByTagName('td')[2].innerHTML = "$name";
|
|
|
|
JS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-11-06 23:56:24 +01:00
|
|
|
* Return the entire site tree as a nested UL.
|
|
|
|
* @return string HTML for site tree
|
2008-02-25 03:10:37 +01:00
|
|
|
*/
|
2007-07-19 12:40:05 +02:00
|
|
|
public function SiteTreeAsUL() {
|
|
|
|
$obj = singleton('Folder');
|
2009-03-10 22:59:19 +01:00
|
|
|
$obj->setMarkingFilter('ClassName', ClassInfo::subclassesFor('Folder'));
|
2009-07-02 00:28:06 +02:00
|
|
|
$obj->markPartialTree(30, null, "ChildFolders");
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
if($p = $this->currentPage()) $obj->markToExpose($p);
|
|
|
|
|
|
|
|
// getChildrenAsUL is a flexible and complex way of traversing the tree
|
2008-11-06 23:56:24 +01:00
|
|
|
$siteTreeList = $obj->getChildrenAsUL(
|
|
|
|
'',
|
|
|
|
'"<li id=\"record-$child->ID\" class=\"$child->class" . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
|
2009-07-02 00:28:06 +02:00
|
|
|
'"<a href=\"" . Director::link(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" class=\"" . ($child->hasChildFolders() ? " contents" : "") . "\" >" . $child->TreeTitle() . "</a>" ',
|
2008-11-06 23:56:24 +01:00
|
|
|
$this,
|
2009-07-02 00:28:06 +02:00
|
|
|
true,
|
|
|
|
"ChildFolders"
|
2008-11-06 23:56:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
// Wrap the root if needs be
|
2007-07-19 12:40:05 +02:00
|
|
|
$rootLink = $this->Link() . 'show/root';
|
2009-01-05 07:17:59 +01:00
|
|
|
$baseUrl = Director::absoluteBaseURL() . "assets";
|
2008-11-06 23:56:24 +01:00
|
|
|
if(!isset($rootID)) {
|
2009-01-05 07:17:59 +01:00
|
|
|
$siteTree = "<ul id=\"sitetree\" class=\"tree unformatted\"><li id=\"record-root\" class=\"Root\"><a href=\"$rootLink\"><strong>{$baseUrl}</strong></a>"
|
2008-11-06 23:56:24 +01:00
|
|
|
. $siteTreeList . "</li></ul>";
|
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
return $siteTree;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a subtree of items underneat the given folder.
|
|
|
|
*/
|
|
|
|
public function getsubtree() {
|
2008-11-07 00:47:28 +01:00
|
|
|
$obj = DataObject::get_by_id('Folder', $_REQUEST['ID']);
|
2009-03-10 22:59:19 +01:00
|
|
|
$obj->setMarkingFilter('ClassName', ClassInfo::subclassesFor('Folder'));
|
2007-07-19 12:40:05 +02:00
|
|
|
$obj->markPartialTree();
|
|
|
|
|
2008-11-07 00:47:28 +01:00
|
|
|
$results = $obj->getChildrenAsUL(
|
|
|
|
'',
|
|
|
|
'"<li id=\"record-$child->ID\" class=\"$child->class" . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
|
|
|
|
'"<a href=\"" . Director::link(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" >" . $child->TreeTitle() . "</a>" ',
|
|
|
|
$this,
|
|
|
|
true
|
|
|
|
);
|
2007-07-19 12:40:05 +02:00
|
|
|
|
2008-11-07 00:47:28 +01:00
|
|
|
return substr(trim($results), 4, -5);
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
// Data saving handlers
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a new folder and return its details suitable for ajax.
|
|
|
|
*/
|
|
|
|
public function addfolder() {
|
2009-02-03 04:46:15 +01:00
|
|
|
$parent = ($_REQUEST['ParentID'] && is_numeric($_REQUEST['ParentID'])) ? (int)$_REQUEST['ParentID'] : 0;
|
|
|
|
$name = (isset($_REQUEST['Name'])) ? basename($_REQUEST['Name']) : _t('AssetAdmin.NEWFOLDER',"NewFolder");
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
if($parent) {
|
2008-10-24 03:23:52 +02:00
|
|
|
$parentObj = DataObject::get_by_id('File', $parent);
|
2007-07-19 12:40:05 +02:00
|
|
|
if(!$parentObj || !$parentObj->ID) $parent = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the folder to be created
|
2009-04-29 03:44:28 +02:00
|
|
|
if(isset($parentObj->ID)) $filename = $parentObj->FullPath . $name;
|
|
|
|
else $filename = ASSETS_PATH . '/' . $name;
|
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
// Actually create
|
ENHANCEMENT Introduced constants for system paths like /sapphire in preparation for a more flexible directory reorganisation. Instead of hardcoding your path, please use the following constants: BASE_PATH, BASE_URL, SAPPHIRE_DIR, SAPPHIRE_PATH, CMS_DIR, CMS_PATH, THIRDPARTY_DIR, THIRDPARTY_PATH, ASSETS_DIR, ASSETS_PATH, THEMES_DIR, THEMES_PATH
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@63154 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-09-27 18:02:38 +02:00
|
|
|
if(!file_exists(ASSETS_PATH)) {
|
|
|
|
mkdir(ASSETS_PATH);
|
2007-10-29 03:10:59 +01:00
|
|
|
}
|
2009-10-31 02:25:32 +01:00
|
|
|
|
2009-04-29 03:44:28 +02:00
|
|
|
$p = new Folder();
|
|
|
|
$p->ParentID = $parent;
|
2009-10-31 02:25:32 +01:00
|
|
|
$p->Name = $p->Title = basename($filename);
|
|
|
|
|
|
|
|
// Ensure uniqueness
|
|
|
|
$i = 2;
|
|
|
|
$baseFilename = substr($p->Filename, 0, -1) . '-';
|
|
|
|
while(file_exists($p->FullPath)) {
|
|
|
|
$p->Filename = $baseFilename . $i . '/';
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$p->write();
|
2009-10-31 02:25:32 +01:00
|
|
|
|
|
|
|
mkdir($p->FullPath);
|
|
|
|
chmod($p->FullPath, Filesystem::$file_create_mask);
|
|
|
|
|
2007-11-12 22:47:45 +01:00
|
|
|
if(isset($_REQUEST['returnID'])) {
|
|
|
|
return $p->ID;
|
|
|
|
} else {
|
|
|
|
return $this->returnItemToUser($p);
|
|
|
|
}
|
2009-10-31 02:25:32 +01:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
|
2009-01-06 03:18:33 +01:00
|
|
|
/**
|
|
|
|
* @return Form
|
|
|
|
*/
|
|
|
|
function DeleteItemsForm() {
|
|
|
|
$form = new Form(
|
|
|
|
$this,
|
|
|
|
'DeleteItemsForm',
|
|
|
|
new FieldSet(
|
|
|
|
new LiteralField('SelectedPagesNote',
|
|
|
|
sprintf('<p>%s</p>', _t('AssetAdmin_left.ss.SELECTTODEL','Select the folders that you want to delete and then click the button below'))
|
|
|
|
),
|
|
|
|
new HiddenField('csvIDs')
|
|
|
|
),
|
|
|
|
new FieldSet(
|
|
|
|
new FormAction('deletefolder', _t('AssetAdmin_left.ss.DELFOLDERS','Delete the selected folders'))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
$form->addExtraClass('actionparams');
|
|
|
|
|
|
|
|
return $form;
|
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
/**
|
|
|
|
* Delete a folder
|
|
|
|
*/
|
|
|
|
public function deletefolder() {
|
|
|
|
$script = '';
|
|
|
|
$ids = split(' *, *', $_REQUEST['csvIDs']);
|
2007-09-15 03:01:49 +02:00
|
|
|
$script = '';
|
2008-11-14 01:45:32 +01:00
|
|
|
|
|
|
|
if(!$ids) return false;
|
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
foreach($ids as $id) {
|
2008-12-04 23:38:58 +01:00
|
|
|
if(is_numeric($id)) {
|
|
|
|
$record = DataObject::get_by_id($this->stat('tree_class'), $id);
|
2009-04-29 03:44:28 +02:00
|
|
|
if($record) {
|
|
|
|
$script .= $this->deleteTreeNodeJS($record);
|
|
|
|
$record->delete();
|
|
|
|
$record->destroy();
|
2008-12-04 23:38:58 +01:00
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
}
|
2008-02-25 03:10:37 +01:00
|
|
|
|
|
|
|
$size = sizeof($ids);
|
2008-12-04 23:38:58 +01:00
|
|
|
if($size > 1) {
|
|
|
|
$message = $size.' '._t('AssetAdmin.FOLDERSDELETED', 'folders deleted.');
|
|
|
|
} else {
|
|
|
|
$message = $size.' '._t('AssetAdmin.FOLDERDELETED', 'folder deleted.');
|
|
|
|
}
|
2008-02-25 03:10:37 +01:00
|
|
|
|
2008-11-14 01:45:32 +01:00
|
|
|
if(isset($brokenPageList)) {
|
2008-02-25 03:10:37 +01:00
|
|
|
$message .= ' '._t('AssetAdmin.NOWBROKEN', 'The following pages now have broken links:').'<ul>'.addslashes($brokenPageList).'</ul>'.
|
2008-11-14 01:45:32 +01:00
|
|
|
_t('AssetAdmin.NOWBROKEN2', 'Their owners have been emailed and they will fix up those pages.');
|
|
|
|
}
|
2008-02-25 03:10:37 +01:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$script .= "statusMessage('$message');";
|
|
|
|
echo $script;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function removefile(){
|
2008-12-04 23:38:58 +01:00
|
|
|
if($fileID = $this->urlParams['ID']) {
|
2007-07-19 12:40:05 +02:00
|
|
|
$file = DataObject::get_by_id('File', $fileID);
|
2007-09-15 23:57:11 +02:00
|
|
|
// Delete the temp verions of this file in assets/_resampled
|
|
|
|
if($file instanceof Image) {
|
|
|
|
$file->deleteFormattedImages();
|
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
$file->delete();
|
|
|
|
$file->destroy();
|
|
|
|
|
|
|
|
if(Director::is_ajax()) {
|
|
|
|
echo <<<JS
|
|
|
|
$('Form_EditForm_Files').removeFile($fileID);
|
|
|
|
statusMessage('removed file', 'good');
|
|
|
|
JS;
|
2008-12-04 23:38:58 +01:00
|
|
|
} else {
|
2007-07-19 12:40:05 +02:00
|
|
|
Director::redirectBack();
|
|
|
|
}
|
2008-12-04 23:38:58 +01:00
|
|
|
} else {
|
2007-07-19 12:40:05 +02:00
|
|
|
user_error("AssetAdmin::removefile: Bad parameters: File=$fileID", E_USER_ERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function save($urlParams, $form) {
|
|
|
|
// Don't save the root folder - there's no database record
|
|
|
|
if($_REQUEST['ID'] == 'root') {
|
2008-12-04 23:38:58 +01:00
|
|
|
FormResponse::status_message('Saved', 'good');
|
2007-07-19 12:40:05 +02:00
|
|
|
return FormResponse::respond();
|
|
|
|
}
|
|
|
|
|
|
|
|
$form->dataFieldByName('Title')->value = $form->dataFieldByName('Name')->value;
|
|
|
|
|
|
|
|
return parent::save($urlParams, $form);
|
|
|
|
}
|
2007-10-02 23:34:57 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* #################################
|
|
|
|
* Garbage collection.
|
|
|
|
* #################################
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2009-02-03 04:46:15 +01:00
|
|
|
* Removes all unused thumbnails from the file store
|
|
|
|
* and returns the status of the process to the user.
|
2008-12-04 23:38:58 +01:00
|
|
|
*/
|
2009-02-03 04:46:15 +01:00
|
|
|
public function deleteunusedthumbnails() {
|
|
|
|
$count = 0;
|
|
|
|
$thumbnails = $this->getUnusedThumbnails();
|
|
|
|
|
|
|
|
if($thumbnails) {
|
|
|
|
foreach($thumbnails as $thumbnail) {
|
|
|
|
unlink(ASSETS_PATH . "/" . $thumbnail);
|
|
|
|
$count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$message = sprintf(_t('AssetAdmin.THUMBSDELETED', '%s unused thumbnails have been deleted'), $count);
|
|
|
|
FormResponse::status_message($message, 'good');
|
|
|
|
echo FormResponse::respond();
|
2007-10-02 23:34:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-12-04 23:38:58 +01:00
|
|
|
* Creates array containg all unused thumbnails.
|
|
|
|
*
|
|
|
|
* Array is created in three steps:
|
2009-02-03 04:46:15 +01:00
|
|
|
* 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)
|
2008-12-04 23:38:58 +01:00
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2009-02-03 04:46:15 +01:00
|
|
|
private function getUnusedThumbnails() {
|
2008-12-04 23:38:58 +01:00
|
|
|
$allThumbnails = array();
|
|
|
|
$usedThumbnails = array();
|
|
|
|
$dirIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(ASSETS_PATH));
|
2009-02-03 04:46:15 +01:00
|
|
|
$classes = ClassInfo::subclassesFor('SiteTree');
|
2008-12-04 23:38:58 +01:00
|
|
|
|
2009-02-03 04:46:15 +01:00
|
|
|
if($dirIterator) {
|
|
|
|
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);
|
|
|
|
}
|
2008-12-04 23:38:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-03 04:46:15 +01:00
|
|
|
if($classes) {
|
|
|
|
foreach($classes as $className) {
|
|
|
|
$SNG_class = singleton($className);
|
|
|
|
$objects = DataObject::get($className);
|
|
|
|
|
|
|
|
if($objects !== NULL) {
|
|
|
|
foreach($objects as $object) {
|
|
|
|
foreach($SNG_class->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);
|
|
|
|
}
|
|
|
|
}
|
2008-12-04 23:38:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-03 04:46:15 +01:00
|
|
|
return array_diff($allThumbnails, $usedThumbnails);
|
2008-12-04 23:38:58 +01:00
|
|
|
}
|
2009-02-03 04:46:15 +01:00
|
|
|
|
2007-11-01 21:58:28 +01:00
|
|
|
}
|
2009-04-29 03:44:28 +02:00
|
|
|
?>
|