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' ;
2011-03-31 11:10:44 +02:00
static $menu_title = 'Files' ;
2008-11-02 22:27:55 +01:00
2009-11-21 04:20:23 +01:00
public static $tree_class = 'Folder' ;
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 ;
2012-02-03 00:11:11 +01:00
public static $allowed_actions = array (
2008-02-25 03:10:37 +01:00
'addfolder' ,
2009-01-06 03:18:33 +01:00
'DeleteItemsForm' ,
2008-02-25 03:10:37 +01:00
'getsubtree' ,
'movemarked' ,
'removefile' ,
'savefile' ,
2009-11-21 04:19:05 +01:00
'deleteUnusedThumbnails' => 'ADMIN' ,
2011-03-15 10:30:28 +01:00
'SyncForm' ,
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 ./
*/
2012-02-03 00:11:11 +01:00
public function init () {
2007-07-19 12:40:05 +02:00
parent :: init ();
2007-10-29 03:10:59 +01:00
2009-11-21 04:20:32 +01:00
// Create base folder if it doesnt exist already
if ( ! file_exists ( ASSETS_PATH )) Filesystem :: makeFolder ( ASSETS_PATH );
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 ( CMS_DIR . " /javascript/AssetAdmin.js " );
Requirements :: css ( CMS_DIR . " /css/AssetAdmin.css " );
2008-11-22 04:47:56 +01:00
Requirements :: customScript ( <<< JS
_TREE_ICONS = {};
_TREE_ICONS [ 'Folder' ] = {
2009-11-21 04:16:54 +01:00
fileIcon : 'sapphire/javascript/tree/images/page-closedfolder.gif' ,
openFolderIcon : 'sapphire/javascript/tree/images/page-openfolder.gif' ,
closedFolderIcon : 'sapphire/javascript/tree/images/page-closedfolder.gif'
2008-11-22 04:47:56 +01:00
};
JS
);
2009-11-21 04:19:05 +01:00
CMSBatchActionHandler :: register ( 'delete' , 'AssetAdmin_DeleteBatchAction' , 'Folder' );
2007-07-19 12:40:05 +02:00
}
2011-03-15 10:30:28 +01:00
2012-02-03 00:11:11 +01:00
public function AddForm () {
2011-04-17 10:01:54 +02:00
$form = parent :: AddForm ();
$form -> Actions () -> fieldByName ( 'action_doAdd' ) -> setTitle ( _t ( 'AssetAdmin.ActionAdd' , 'Add folder' ));
return $form ;
}
2011-03-15 10:30:28 +01:00
/**
* Add a new group and return its details suitable for ajax .
*
* @ todo Move logic into Folder class , and use LeftAndMain -> doAdd () default implementation .
*/
public function doAdd ( $data , $form ) {
$class = $this -> stat ( 'tree_class' );
// check create permissions
if ( ! singleton ( $class ) -> canCreate ()) return Security :: permissionFailure ( $this );
2011-04-19 11:16:03 +02:00
2011-03-15 10:30:28 +01:00
// check addchildren permissions
if (
2011-04-19 11:16:03 +02:00
singleton ( $class ) -> hasExtension ( 'Hierarchy' )
2011-03-15 10:30:28 +01:00
&& isset ( $data [ 'ParentID' ])
&& is_numeric ( $data [ 'ParentID' ])
) {
$parentRecord = DataObject :: get_by_id ( $class , $data [ 'ParentID' ]);
if (
$parentRecord -> hasMethod ( 'canAddChildren' )
&& ! $parentRecord -> canAddChildren ()
) return Security :: permissionFailure ( $this );
}
$parent = ( isset ( $data [ 'ParentID' ]) && is_numeric ( $data [ 'ParentID' ])) ? ( int ) $data [ 'ParentID' ] : 0 ;
$name = ( isset ( $data [ 'Name' ])) ? basename ( $data [ 'Name' ]) : _t ( 'AssetAdmin.NEWFOLDER' , " NewFolder " );
if ( ! isset ( $parentRecord ) || ! $parentRecord -> ID ) $parent = 0 ;
// Get the folder to be created
if ( isset ( $parentRecord -> ID )) $filename = $parentRecord -> FullPath . $name ;
else $filename = ASSETS_PATH . '/' . $name ;
// Actually create
if ( ! file_exists ( ASSETS_PATH )) {
mkdir ( ASSETS_PATH );
}
$record = new Folder ();
$record -> ParentID = $parent ;
// Ensure uniqueness
$i = 2 ;
$baseFilename = substr ( $record -> Filename , 0 , - 1 ) . '-' ;
while ( file_exists ( $record -> FullPath )) {
$record -> Filename = $baseFilename . $i . '/' ;
$i ++ ;
}
$record -> Name = $record -> Title = basename ( $record -> Filename );
$record -> write ();
mkdir ( $record -> FullPath );
chmod ( $record -> FullPath , Filesystem :: $file_create_mask );
// Used in TinyMCE inline folder creation
if ( isset ( $data [ 'returnID' ])) {
return $record -> ID ;
} else if ( $this -> isAjax ()) {
$form = $this -> getEditForm ( $record -> ID );
2011-06-08 01:30:54 +02:00
return $form -> forTemplate ();
2011-03-15 10:30:28 +01:00
} else {
return $this -> redirect ( Controller :: join_links ( $this -> Link ( 'show' ), $record -> ID ));
}
}
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 )) {
2009-11-21 04:20:26 +01:00
return DataObject :: get_by_id ( 'File' , $id );
2009-04-29 03:44:28 +02:00
} else if ( $id == 'root' ) {
2009-11-21 04:20:26 +01:00
return singleton ( 'File' );
2009-04-29 03:44:28 +02:00
}
}
2009-11-21 04:21:00 +01:00
2010-04-12 11:22:43 +02:00
function getSiteTreeFor ( $className , $rootID = null , $childrenMethod = null , $numChildrenMethod = null , $filterFunction = null , $minNodeCount = 30 ) {
2009-11-21 04:21:03 +01:00
if ( ! $childrenMethod ) $childrenMethod = 'ChildFolders' ;
2010-04-12 11:22:43 +02:00
return parent :: getSiteTreeFor ( $className , $rootID , $childrenMethod , $numChildrenMethod , $filterFunction , $minNodeCount );
2009-11-21 04:21:03 +01:00
}
2009-11-21 04:21:00 +01:00
public function getCMSTreeTitle () {
return Director :: absoluteBaseURL () . " assets " ;
}
2007-07-19 12:40:05 +02:00
public function SiteTreeAsUL () {
2011-03-15 10:30:28 +01:00
return $this -> getSiteTreeFor ( $this -> stat ( 'tree_class' ), null , 'ChildFolders' );
2007-07-19 12:40:05 +02:00
}
//------------------------------------------------------------------------------------------//
// Data saving handlers
2009-11-21 04:19:02 +01:00
/**
* @ return Form
*/
2012-02-03 00:11:11 +01:00
public function SyncForm () {
2009-11-21 04:19:02 +01:00
$form = new Form (
$this ,
'SyncForm' ,
2011-10-26 07:35:51 +02:00
new FieldList (
2009-11-21 04:21:00 +01:00
),
2011-10-26 07:35:51 +02:00
new FieldList (
2009-11-21 04:19:02 +01:00
$btn = new FormAction ( 'doSync' , _t ( 'FILESYSTEMSYNC' , 'Look for new files' ))
)
);
$form -> setFormMethod ( 'GET' );
$btn -> describe ( _t ( 'AssetAdmin_left.ss.FILESYSTEMSYNC_DESC' , 'SilverStripe maintains its own database of the files & images stored in your assets/ folder. Click this button to update that database, if files are added to the assets/ folder from outside SilverStripe, for example, if you have uploaded files via FTP.' ));
return $form ;
}
2009-01-06 03:18:33 +01:00
2012-02-03 00:11:11 +01:00
public function doSync ( $data , $form ) {
2011-03-15 22:13:49 +01:00
return Filesystem :: sync ();
}
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
*/
2010-11-01 02:29:02 +01:00
public function deleteunusedthumbnails ( $request ) {
// Protect against CSRF on destructive action
if ( ! SecurityToken :: inst () -> checkRequest ( $request )) return $this -> httpError ( 400 );
2009-02-03 04:46:15 +01:00
$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-11-21 04:19:05 +01:00
/**
* Delete multiple { @ link Folder } records ( and the associated filesystem nodes ) .
* Usually used through the { @ link AssetAdmin } interface .
*
* @ package cms
* @ subpackage batchactions
*/
class AssetAdmin_DeleteBatchAction extends CMSBatchAction {
2012-02-03 00:11:11 +01:00
public function getActionTitle () {
2009-11-21 04:19:05 +01:00
// _t('AssetAdmin_left.ss.SELECTTODEL','Select the folders that you want to delete and then click the button below')
return _t ( 'AssetAdmin_DeleteBatchAction.TITLE' , 'Delete folders' );
}
2012-02-03 00:11:11 +01:00
public function run ( SS_List $records ) {
2009-11-21 04:19:05 +01:00
$status = array (
'modified' => array (),
'deleted' => array ()
);
foreach ( $records as $record ) {
$id = $record -> ID ;
// Perform the action
if ( $record -> canDelete ()) $record -> delete ();
$status [ 'deleted' ][ $id ] = array ();
$record -> destroy ();
unset ( $record );
}
return Convert :: raw2json ( $status );
}
}
2009-04-29 03:44:28 +02:00
?>