1 <?php
2 3 4 5 6 7 8
9 class AssetAdmin extends LeftAndMain {
10
11 static $url_segment = 'assets';
12
13 static $url_rule = '/$Action/$ID';
14
15 static = 'Files & Images';
16
17 public static $tree_class = 'File';
18
19 20 21 22
23 public static $allowed_max_file_size;
24
25 static $allowed_actions = array(
26 'addfolder',
27 'deletefolder',
28 'deletemarked',
29 'DeleteItemsForm',
30 'deleteUnusedThumbnails',
31 'doUpload',
32 'doMultiUpload',
33 'getfile',
34 'getsubtree',
35 'movemarked',
36 'removefile',
37 'save',
38 'savefile',
39 'sync',
40 'uploadiframe',
41 'UploadForm',
42 'handleupload',
43 'deleteUnusedThumbnails' => 'ADMIN'
44 );
45
46 47 48 49 50 51 52
53 public static $metadata_upload_enabled = false;
54
55 56 57
58 public function currentPageID() {
59 if(isset($_REQUEST['ID']) && is_numeric($_REQUEST['ID'])) {
60 return $_REQUEST['ID'];
61 } elseif (is_numeric($this->urlParams['ID'])) {
62 return $this->urlParams['ID'];
63 } elseif(is_numeric(Session::get("{$this->class}.currentPage"))) {
64 return Session::get("{$this->class}.currentPage");
65 } else {
66 return "root";
67 }
68 }
69
70 71 72
73 function init() {
74 parent::init();
75
76 if(!file_exists(ASSETS_PATH)) {
77 mkdir(ASSETS_PATH);
78 }
79
80
81 Requirements::css(THIRDPARTY_DIR . "/greybox/greybox.css");
82 Requirements::css(SAPPHIRE_DIR . "/css/ComplexTableField.css");
83
84 Requirements::javascript(CMS_DIR . "/javascript/AssetAdmin.js");
85
86 Requirements::javascript(THIRDPARTY_DIR . "/greybox/AmiJS.js");
87 Requirements::javascript(THIRDPARTY_DIR . "/greybox/greybox.js");
88 Requirements::css(THIRDPARTY_DIR . "/greybox/greybox.css");
89
90 Requirements::css(CMS_DIR . "/css/AssetAdmin.css");
91
92 Requirements::customScript(<<<JS
93 _TREE_ICONS = {};
94 _TREE_ICONS['Folder'] = {
95 fileIcon: 'sapphire/javascript/tree/images/page-closedfolder.gif',
96 openFolderIcon: 'sapphire/javascript/tree/images/page-openfolder.gif',
97 closedFolderIcon: 'sapphire/javascript/tree/images/page-closedfolder.gif'
98 };
99 JS
100 );
101 }
102
103 /**
104 * Show the content of the upload iframe. The form is specified by a template.
105 */
106 function uploadiframe() {
107 Requirements::clear();
108
109 Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/prototype/prototype.js");
110 Requirements::javascript(SAPPHIRE_DIR . '/javascript/loader.js');
111 Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/behaviour/behaviour.js");
112 Requirements::javascript(SAPPHIRE_DIR . "/javascript/prototype_improvements.js");
113 Requirements::javascript(SAPPHIRE_DIR . "/javascript/layout_helpers.js");
114 Requirements::javascript(CMS_DIR . "/javascript/LeftAndMain.js");
115 // Requirements::javascript(CMS_DIR . "/thirdparty/multifile/multifile.js");
116 // Requirements::css(CMS_DIR . "/thirdparty/multifile/multifile.css");
117 Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/jquery/jquery.js");
118 Requirements::javascript(SAPPHIRE_DIR . "/javascript/jquery_improvements.js");
119 Requirements::css(CMS_DIR . "/css/typography.css");
120 Requirements::css(CMS_DIR . "/css/layout.css");
121 Requirements::css(CMS_DIR . "/css/cms_left.css");
122 Requirements::css(CMS_DIR . "/css/cms_right.css");
123
124 if(isset($data['ID']) && $data['ID'] != 'root') $folder = DataObject::get_by_id("Folder", $data['ID']);
125 else $folder = singleton('Folder');
126
127 return array( 'CanUpload' => $folder->canEdit());
128 }
129
130 /**
131 * Needs to be enabled through {@link AssetAdmin::$metadata_upload_enabled}
132 *
133 * @return String
134 */
135 function UploadMetadataHtml() {
136 if(!self::$metadata_upload_enabled) return;
137
138 $fields = singleton('File')->uploadMetadataFields();
139
140 // Return HTML with markers for easy replacement
141 $fieldHtml = '';
142 foreach($fields as $field) $fieldHtml = $fieldHtml . $field->FieldHolder();
143 $fieldHtml = preg_replace('/(name|for|id)="(.+?)"/', '$1="$2[__X__]"', $fieldHtml);
144
145 // Icky hax to fix certain elements with fixed ids
146 $fieldHtml = preg_replace('/-([a-zA-Z0-9]+?)\[__X__\]/', '[__X__]-$1', $fieldHtml);
147
148 return $fieldHtml;
149 }
150
151 /**
152 * Return the form object shown in the uploadiframe.
153 */
154 function UploadForm() {
155 $ff = new MultiUploadField(
156 'UploadForm',
157 'Upload',
158 "",
159 array(
160 'file_upload_limit' => 10, // how many files can be uploaded
161 'file_queue_limit' => 10, // how many files can be in the queue at once
162 'upload_url' => Director::absoluteURL('admin/assets/handleupload'),
163 'required' => 'false'
164 )
165 );
166
167 MultiUploadConfig::addStaticPostParams(array(
168 'FolderID' => $this->currentPageID(),
169 ));
170 MultiUploadConfig::addFileTypes(File::$allowed_extensions);
171
172 if (property_exists('WebylonSiteConfig', 'max_file_upload_size')) {
173 MultiUploadConfig::$file_size_limit = WebylonSiteConfig::$max_file_upload_size;
174 } else {
175 MultiUploadConfig::$file_size_limit = ((int)ini_get('upload_max_filesize')) * 1024 * 1024;
176 }
177
178 $form = new Form($this,'UploadForm', new FieldSet(
179 new HiddenField("ID", "", $this->currentPageID()),
180 new HiddenField("FolderID", "", $this->currentPageID()),
181 new HiddenField("action_doMultiUpload", "", "1"),
182 $ff
183 ), new FieldSet(
184 ));
185
186 $this->extend('updateUploadForm', $form);
187
188 // Makes ajax easier
189 $form->disableSecurityToken();
190
191 return $form;
192 }
193
194 /**
195 * This method processes the results of the UploadForm. !!! NOT USED HERE, BUT USED IN CMSMAIN IN Visual Editor !!!
196 * It will save the uploaded files to /assets/ and create new File objects as required.
197 */
198 function doUpload($data, $form) {
199 $newFiles = array();
200 $fileIDs = array();
201 $fileNames = array();
202 $fileSizeWarnings = '';
203 $uploadErrors = '';
204 $jsErrors = '';
205 $status = '';
206 $statusMessage = '';
207 $processedFiles = array();
208
209 foreach($data['Files'] as $param => $files) {
210 if(!is_array($files)) $files = array($files);
211 foreach($files as $key => $value) {
212 $processedFiles[$key][$param] = $value;
213 }
214 }
215
216 // Load POST data from arrays in to the correct dohickey.
217 $processedData = array();
218 foreach($data as $dataKey => $value) {
219 if ($dataKey == 'Files') continue;
220 if (is_array($value)) {
221 $i = 0;
222 foreach($value as $fileId => $dataValue) {
223 if (!isset($processedData[$i])) $processedData[$i] = array();
224 $processedData[$i][$dataKey] = $dataValue;
225 $i++;
226 }
227 }
228 }
229 $processedData = array_reverse($processedData);
230
231 if($data['FolderID'] && $data['FolderID'] != '') $folder = DataObject::get_by_id("Folder", $data['FolderID']);
232 else $folder = singleton('Folder');
233
234 foreach($processedFiles as $filePostId => $tmpFile) {
235 if($tmpFile['error'] == UPLOAD_ERR_NO_TMP_DIR) {
236 $status = 'bad';
237 $statusMessage = _t('AssetAdmin.NOTEMP', 'There is no temporary folder for uploads. Please set upload_tmp_dir in php.ini.');
238 break;
239 }
240
241 if($tmpFile['tmp_name']) {
242 // Workaround open_basedir problems
243 if(ini_get("open_basedir")) {
244 $newtmp = TEMP_FOLDER . '/' . $tmpFile['name'];
245 move_uploaded_file($tmpFile['tmp_name'], $newtmp);
246 $tmpFile['tmp_name'] = $newtmp;
247 }
248
249 // validate files (only if not logged in as admin)
250 if(!File::$apply_restrictions_to_admin && (Permission::check('ADMIN') || Permission::check('CMS_ACCESS_AssetAdmin'))) {
251 $valid = true;
252 } else {
253
254 // Set up the validator instance with rules
255 $validator = new Upload_Validator();
256 $validator->setAllowedExtensions(File::$allowed_extensions);
257 $validator->setAllowedMaxFileSize(self::$allowed_max_file_size);
258
259 // Do the upload validation with the rules
260 $upload = new Upload();
261 $upload->setValidator($validator);
262 $valid = $upload->validate($tmpFile);
263 if(!$valid) {
264 $errors = $upload->getErrors();
265 if($errors) foreach($errors as $error) {
266 $jsErrors .= "alert('" . Convert::raw2js($error) . "');";
267 }
268 }
269 }
270
271 // move file to given folder
272 if($valid && $folder) {
273 $newFile = $folder->addUploadToFolder($tmpFile);
274
275 if(self::$metadata_upload_enabled && isset($processedData[$filePostId])) {
276 $fileObject = DataObject::get_by_id('File', $newFile);
277 $metadataForm = new Form($this, 'MetadataForm', $fileObject->uploadMetadataFields(), new FieldSet());
278 $metadataForm->loadDataFrom($processedData[$filePostId]);
279 $metadataForm->saveInto($fileObject);
280 $fileObject->write();
281 }
282
283 $newFiles[] = $newFile;
284 }
285 }
286 }
287
288 if($newFiles) {
289 $numFiles = sizeof($newFiles);
290 $statusMessage = sprintf(_t('AssetAdmin.UPLOADEDX',"Uploaded %s files"),$numFiles);
291 $status = "good";
292 } else if($status != 'bad') {
293 $statusMessage = _t('AssetAdmin.NOTHINGTOUPLOAD','There was nothing to upload');
294 $status = "";
295 }
296
297 $fileObj = false;
298 foreach($newFiles as $newFile) {
299 $fileIDs[] = $newFile;
300 $fileObj = DataObject::get_one('File', "\"File\".\"ID\"=$newFile");
301 // notify file object after uploading
302 if (method_exists($fileObj, 'onAfterUpload')) $fileObj->onAfterUpload();
303 $fileNames[] = $fileObj->Name;
304 }
305
306 // workaround for content editors image upload.Passing an extra hidden field
307 // in the content editors view of 'UploadMode' @see HtmlEditorField
308 // this will be refactored for 2.5
309 if(isset($data['UploadMode']) && $data['UploadMode'] == "CMSEditor" && $fileObj) {
310 // we can use $fileObj considering that the uploader in the cmseditor can only upload
311 // one file at a time. Once refactored to multiple files this is going to have to be changed
312 $width = (is_a($fileObj, 'Image')) ? $fileObj->getWidth() : '100';
313 $height = (is_a($fileObj, 'Image')) ? $fileObj->getHeight() : '100';
314
315 $values = array(
316 'Filename' => $fileObj->Filename,
317 'Width' => $width,
318 'Height' => $height
319 );
320
321 return Convert::raw2json($values);
322 }
323
324 $sFileIDs = implode(',', $fileIDs);
325 $sFileNames = implode(',', $fileNames);
326
327 echo <<<HTML
328 <script type="text/javascript">
329 /* IDs: $sFileIDs */
330 /* Names: $sFileNames */
331
332 var form = parent.document.getElementById('Form_EditForm');
333 form.getPageFromServer(form.elements.ID.value);
334 parent.statusMessage("{$statusMessage}","{$status}");
335 $jsErrors
336 parent.document.getElementById('sitetree').getTreeNodeByIdx( "{$folder->ID}" ).getElementsByTagName('a')[0].className += ' contents';
337 </script>
338 HTML;
339 }
340
341 public function handleupload() {
342 $rs = false;
343 $message = '';
344 if(isset($_FILES['upload_file']) && !empty($_FILES['upload_file'])) {
345 $file = new File();
346 if(!isset($_POST['FolderID']) || !($folder = DataObject::get_by_id("Folder",$_POST['FolderID']))) {
347 $folder = singleton('Folder');
348 }
349 try {
350 if(!class_exists("Upload")) {
351 throw new ValidationException(_t("FileDataObjectManager.NoUploadClass", "No Upload class!"), E_USER_WARNING);
352 }
353 $u = new Upload();
354 $u->validator->setAllowedExtensions(File::$allowed_extensions);
355 $valid = $u->validate($_FILES['upload_file']);
356 if(!$valid) {
357 $errors = implode("; ", $u->getErrors());
358 throw new ValidationException($errors, E_USER_WARNING);
359 }
360 $newFile = $folder->addUploadToFolder($_FILES['upload_file']);
361 $file = DataObject::get_by_id('File', $newFile);
362 if (!$file) {
363 $errors = _t("FileDataObjectManager.UploadError", "Upload Error");
364 throw new ValidationException($errors, E_USER_WARNING);
365 }
366
367 if(isset($_POST['FolderID']))
368 $file->setField("ParentID",$folder->ID);
369
370
371 if($file->class == "File") {
372 $ext = strtolower($file->Extension);
373 if(in_array($ext, MP3::$allowed_file_types))
374 $file = $file->newClassInstance("MP3");
375 else if(in_array($ext, array('jpg','jpeg','gif','png')))
376 $file = $file->newClassInstance("Image");
377 else if(in_array($ext, FLV::$allowed_file_types))
378 $file = $file->newClassInstance("FLV");
379 }
380 $file->OwnerID = Member::currentUserID();
381 $file->write();
382 $rs = true;
383 $message = $file->ID;
384 } catch (Exception $e) {
385 $rs = false;
386 if (method_exists($e,'getResult') && $e->getResult()) {
387 $message = $e->getResult()->message();
388 } else {
389 $message = $e->getMessage();
390 }
391 }
392 }
393 echo json_encode(array('rs' => $rs, 'message' => $message));
394 }
395
396 397 398 399
400 function doMultiUpload($data, $form) {
401 if(isset($data['uploaded_files']) && !empty($data['uploaded_files'])) {
402 $statusMessage = sprintf(_t('AssetAdmin.UPLOADEDX',"Uploaded %s files"), count($data['uploaded_files']));
403 $status = "good";
404 } else {
405 $statusMessage = _t('AssetAdmin.NOTHINGTOUPLOAD','There was nothing to upload');
406 $status = "";
407 }
408
409 $folderID = 0;
410 if (isset($data['FolderID'])) {
411 $folderID = $data['FolderID'];
412 }
413
414 echo <<<HTML
415 <script type="text/javascript">
416
417 var form = parent.document.getElementById('Form_EditForm');
418 form.getPageFromServer(form.elements.ID.value);
419 parent.statusMessage("{$statusMessage}","{$status}");
420 parent.document.getElementById('sitetree').getTreeNodeByIdx( "{$folderID}" ).getElementsByTagName('a')[0].className += ' contents';
421 </script>
422 HTML;
423 }
424
425
426 427 428
429 public function currentPage() {
430 $id = $this->currentPageID();
431 if($id && is_numeric($id)) {
432 return DataObject::get_by_id($this->stat('tree_class'), $id);
433 } else if($id == 'root') {
434 return singleton($this->stat('tree_class'));
435 }
436 }
437
438 439 440
441 function getEditForm($id) {
442 if($id && $id != "root") {
443 $record = DataObject::get_by_id("File", $id);
444 } else {
445 $record = singleton("Folder");
446 }
447
448 if($record) {
449 $fields = $record->getCMSFields();
450 $actions = new FieldSet();
451
452
453 if($record->canEdit() && $id != 'root') {
454 $actions = new FieldSet(
455 new FormAction('save',_t('AssetAdmin.SAVEFOLDERNAME','Save folder name'))
456 );
457 }
458
459 $form = new Form($this, "EditForm", $fields, $actions);
460 if($record->ID) {
461 $form->loadDataFrom($record);
462 } else {
463 $form->loadDataFrom(array(
464 "ID" => "root",
465 "URL" => Director::absoluteBaseURL() . 'assets/',
466 ));
467 }
468
469 if(!$record->canEdit()) {
470 $form->makeReadonly();
471 }
472
473 $this->extend('updateEditForm', $form);
474
475 return $form;
476 }
477 }
478
479 480 481 482
483 public function movemarked($urlParams, $form) {
484 if($_REQUEST['DestFolderID'] && (is_numeric($_REQUEST['DestFolderID']) || ($_REQUEST['DestFolderID']) == 'root')) {
485 $destFolderID = ($_REQUEST['DestFolderID'] == 'root') ? 0 : $_REQUEST['DestFolderID'];
486 $fileList = "'" . preg_replace('! *, *!',"','",trim(addslashes($_REQUEST['FileIDs']))) . "'";
487 $numFiles = 0;
488
489 if($fileList != "''") {
490 $files = DataObject::get("File", "\"File\".\"ID\" IN ($fileList)");
491 if($files) {
492 foreach($files as $file) {
493 if($file instanceof Image) {
494 $file->deleteFormattedImages();
495 }
496 $file->ParentID = $destFolderID;
497 $file->write();
498 $numFiles++;
499 }
500 } else {
501 user_error("No files in $fileList could be found!", E_USER_ERROR);
502 }
503 }
504
505 $message = sprintf(_t('AssetAdmin.MOVEDX','Moved %s files'),$numFiles);
506
507 FormResponse::status_message($message, "good");
508 FormResponse::add("$('Form_EditForm_Files').refresh();");
509
510 return FormResponse::respond();
511 }
512 }
513
514 515 516 517
518 public function deletemarked($urlParams, $form) {
519 $fileList = "'" . preg_replace('! *, *!',"','",trim(addslashes($_REQUEST['FileIDs']))) . "'";
520 $numFiles = 0;
521 $folderID = 0;
522 $deleteList = '';
523 $brokenPageList = '';
524
525 if($fileList != "''") {
526 $files = DataObject::get("File", "\"File\".\"ID\" IN ($fileList)");
527 if($files) {
528 foreach($files as $file) {
529 if($file instanceof Image) {
530 $file->deleteFormattedImages();
531 }
532 if(!$folderID) {
533 $folderID = $file->ParentID;
534 }
535 $file->delete();
536 $numFiles++;
537 }
538 if($brokenPages = Notifications::getItems('BrokenLink')) {
539 $brokenPageList = " ". _t('AssetAdmin.NOWBROKEN', 'These pages now have broken links:') . '</ul>';
540 foreach($brokenPages as $brokenPage) {
541 $brokenPageList .= "<li style="font-size: 65%">" . $brokenPage->Breadcrumbs(3, true) . '</li>';
542 }
543 $brokenPageList .= '</ul>';
544 Notifications::notifyByEmail("BrokenLink", "Page_BrokenLinkEmail");
545 } else {
546 $brokenPageList = '';
547 }
548
549 $deleteList = '';
550 if($folderID) {
551 $remaining = DB::query("SELECT COUNT(*) FROM \"File\" WHERE \"ParentID\" = $folderID")->value();
552 if(!$remaining) $deleteList .= "Element.removeClassName(\$('sitetree').getTreeNodeByIdx('$folderID').getElementsByTagName('a')[0],'contents');";
553 }
554 } else {
555 user_error("No files in $fileList could be found!", E_USER_ERROR);
556 }
557 }
558
559 $message = sprintf(_t('AssetAdmin.DELETEDX',"Deleted %s files.%s"),$numFiles,$brokenPageList) ;
560
561 FormResponse::add($deleteList);
562 FormResponse::status_message($message, "good");
563 FormResponse::add("$('Form_EditForm').getPageFromServer($('Form_EditForm_ID').value)");
564
565 return FormResponse::respond();
566 }
567
568
569 570 571 572
573 public function getfile() {
574 SSViewer::setOption('rewriteHashlinks', false);
575
576
577 if (is_object($this->getSubForm($this->urlParams['ID']))) {
578 return $this->getSubForm($this->urlParams['ID'])->formHtmlContent();
579 }
580 else return null;
581 }
582
583 584 585 586
587 public function savefile($data, $form) {
588 $record = DataObject::get_by_id("File", $data['ID']);
589 $form->saveInto($record);
590 $record->write();
591 $title = Convert::raw2js($record->Title);
592 $name = Convert::raw2js($record->Name);
593 $saved = sprintf(_t('AssetAdmin.SAVEDFILE','Saved file %s'),"#$data[ID]");
594 echo <<<JS
595 statusMessage('$saved');
596 $('record-$data[ID]').getElementsByTagName('td')[1].innerHTML = "$title";
597 $('record-$data[ID]').getElementsByTagName('td')[2].innerHTML = "$name";
598 JS;
599 }
600
601 public function sync() {
602 echo Filesystem::sync();
603 }
604
605 606 607 608
609 public function SiteTreeAsUL() {
610 $obj = singleton('Folder');
611 $obj->setMarkingFilter('ClassName', ClassInfo::subclassesFor('Folder'));
612 $obj->markPartialTree(30, null, "ChildFolders");
613
614 if($p = $this->currentPage()) $obj->markToExpose($p);
615
616
617 $siteTreeList = $obj->getChildrenAsUL(
618 '',
619 '"<li id=\"record-$child->ID\" class=\"$child->class" . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
620 '"<a href=\"" . Controller::join_links(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" class=\"" . ($child->hasChildFolders() ? " contents" : "") . "\" >" . $child->TreeTitle() . "</a>" ',
621 $this,
622 true,
623 "ChildFolders"
624 );
625
626
627 $rootLink = $this->Link() . 'show/root';
628 $baseUrl = Director::absoluteBaseURL() . "assets";
629 if(!isset($rootID)) {
630 $siteTree = "<ul id=\"sitetree\" class=\"tree unformatted\"><li id=\"record-root\" class=\"Root\"><a href=\"$rootLink\"><strong>{$baseUrl}</strong></a>"
631 . $siteTreeList . "</li></ul>";
632 }
633
634 return $siteTree;
635 }
636
637 638 639
640 public function getsubtree($request) {
641 $obj = DataObject::get_by_id('Folder', $_REQUEST['ID']);
642 $obj->setMarkingFilter('ClassName', ClassInfo::subclassesFor('Folder'));
643 $obj->markPartialTree();
644
645 $results = $obj->getChildrenAsUL(
646 '',
647 '"<li id=\"record-$child->ID\" class=\"$child->class" . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
648 '"<a href=\"" . Controller::join_links(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" >" . $child->TreeTitle() . "</a>" ',
649 $this,
650 true
651 );
652
653 return substr(trim($results), 4, -5);
654 }
655
656
657
658
659
660
661 662 663
664 public function addfolder() {
665 $parent = ($_REQUEST['ParentID'] && is_numeric($_REQUEST['ParentID'])) ? (int)$_REQUEST['ParentID'] : 0;
666 $name = (isset($_REQUEST['Name'])) ? basename($_REQUEST['Name']) : _t('AssetAdmin.NEWFOLDER',"NewFolder");
667
668 if($parent) {
669 $parentObj = DataObject::get_by_id('File', $parent);
670 if(!$parentObj || !$parentObj->ID) $parent = 0;
671 }
672
673
674 if(isset($parentObj->ID)) $filename = $parentObj->FullPath . $name;
675 else $filename = ASSETS_PATH . '/' . $name;
676
677
678 if(!file_exists(ASSETS_PATH)) {
679 mkdir(ASSETS_PATH);
680 }
681
682 $p = new Folder();
683 $p->ParentID = $parent;
684 $p->Name = $p->Title = basename($filename);
685
686
687 $i = 2;
688 $baseFilename = substr($p->Filename, 0, -1) . '-';
689 while(file_exists($p->FullPath)) {
690 $p->Filename = $baseFilename . $i . '/';
691 $i++;
692 }
693
694 $p->write();
695
696 mkdir($p->FullPath);
697 chmod($p->FullPath, Filesystem::$file_create_mask);
698
699 if(isset($_REQUEST['returnID'])) {
700 return $p->ID;
701 } else {
702 return $this->returnItemToUser($p);
703 }
704
705 }
706
707 708 709
710 function DeleteItemsForm() {
711 $form = new Form(
712 $this,
713 'DeleteItemsForm',
714 new FieldSet(
715 new LiteralField('SelectedPagesNote',
716 sprintf('<p>%s</p>', _t('AssetAdmin_left.ss.SELECTTODEL','Select the folders that you want to delete and then click the button below'))
717 ),
718 new HiddenField('csvIDs')
719 ),
720 new FieldSet(
721 new FormAction('deletefolder', _t('AssetAdmin_left.ss.DELFOLDERS','Delete the selected folders'))
722 )
723 );
724 $form->addExtraClass('actionparams');
725
726 return $form;
727 }
728
729 730 731
732 public function deletefolder() {
733 $ids = preg_split('! *, *!', $_REQUEST['csvIDs']);
734
735 if(!$ids) return false;
736 $script = '';
737
738 foreach($ids as $id) {
739 if(is_numeric($id)) {
740 $record = DataObject::get_by_id($this->stat('tree_class'), $id);
741 if($record) {
742 $script .= $this->deleteTreeNodeJS($record);
743 $record->delete();
744 $record->destroy();
745 }
746 }
747 }
748
749 $size = sizeof($ids);
750 if($size > 1) {
751 $message = $size.' '._t('AssetAdmin.FOLDERSDELETED', 'folders deleted.');
752 } else {
753 $message = $size.' '._t('AssetAdmin.FOLDERDELETED', 'folder deleted.');
754 }
755
756 $script .= "statusMessage('$message');";
757
758 return $script;
759 }
760
761 public function removefile(){
762 if($fileID = $this->urlParams['ID']) {
763 $file = DataObject::get_by_id('File', $fileID);
764
765 if($file instanceof Image) {
766 $file->deleteFormattedImages();
767 }
768 $file->delete();
769
770
771 if(Director::is_ajax()) {
772 echo <<<JS
773 $('Form_EditForm_Files').removeFile($fileID);
774 statusMessage('removed file', 'good');
775 JS;
776 } else {
777 Director::redirectBack();
778 }
779 } else {
780 user_error("AssetAdmin::removefile: Bad parameters: File=$fileID", E_USER_ERROR);
781 }
782 }
783
784 public function save($urlParams, $form) {
785
786 if($_REQUEST['ID'] == 'root') {
787 FormResponse::status_message('Saved', 'good');
788 return FormResponse::respond();
789 }
790
791 $form->dataFieldByName('Name')->Value = $form->dataFieldByName('Title')->Value();
792
793 return parent::save($urlParams, $form);
794 }
795
796 797 798 799 800
801
802 803 804 805
806 public function deleteunusedthumbnails() {
807 $count = 0;
808 $thumbnails = $this->getUnusedThumbnails();
809
810 if($thumbnails) {
811 foreach($thumbnails as $thumbnail) {
812 unlink(ASSETS_PATH . "/" . $thumbnail);
813 $count++;
814 }
815 }
816
817 $message = sprintf(_t('AssetAdmin.THUMBSDELETED', '%s unused thumbnails have been deleted'), $count);
818 FormResponse::status_message($message, 'good');
819 echo FormResponse::respond();
820 }
821
822 823 824 825 826 827 828 829 830 831
832 private function getUnusedThumbnails() {
833 $allThumbnails = array();
834 $usedThumbnails = array();
835 $dirIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(ASSETS_PATH));
836 $classes = ClassInfo::subclassesFor('SiteTree');
837
838 if($dirIterator) {
839 foreach($dirIterator as $file) {
840 if($file->isFile()) {
841 if(strpos($file->getPathname(), '_resampled') !== false) {
842 $pathInfo = pathinfo($file->getPathname());
843 if(in_array(strtolower($pathInfo['extension']), array('jpeg', 'jpg', 'jpe', 'png', 'gif'))) {
844 $path = str_replace('\\','/', $file->getPathname());
845 $allThumbnails[] = substr($path, strpos($path, '/assets/') + 8);
846 }
847 }
848 }
849 }
850 }
851
852 if($classes) {
853 foreach($classes as $className) {
854 $SNG_class = singleton($className);
855 $objects = DataObject::get($className);
856
857 if($objects !== NULL) {
858 foreach($objects as $object) {
859 foreach($SNG_class->db() as $fieldName => $fieldType) {
860 if($fieldType == 'HTMLText') {
861 $url1 = HTTP::findByTagAndAttribute($object->$fieldName,array('img' => 'src'));
862
863 if($url1 != NULL) {
864 $usedThumbnails[] = substr($url1[0], strpos($url1[0], '/assets/') + 8);
865 }
866
867 if($object->latestPublished > 0) {
868 $object = Versioned::get_latest_version($className, $object->ID);
869 $url2 = HTTP::findByTagAndAttribute($object->$fieldName, array('img' => 'src'));
870
871 if($url2 != NULL) {
872 $usedThumbnails[] = substr($url2[0], strpos($url2[0], '/assets/') + 8);
873 }
874 }
875 }
876 }
877 }
878 }
879 }
880 }
881
882 return array_diff($allThumbnails, $usedThumbnails);
883 }
884
885 }
886 ?>
887
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-