I use setDefaultFolder on two FileAttachmentFields in the same DataObject. I pass the same folder path to each one. I expected that if the folder did not exists the 1st one would create the folder and the second one would use the folder created by the 1st one. However I find that each FileAttachmentField creates a new folder. KickAssetField uses Folder::findormake($folder); Which I have found to be very unsatisfactory in that it often will create duplicates of folders even when they exist already.
I have written my own version of FindOrMake that has a lot more logic and is much more robust. This class does make use of Folder::findormake($folder); but first does a lot more checking for an existing valid folder so it does not fail where the other function does.
Here is my utility class. Maybe it can be incorporated into Kickassets.
<?php
class Utils extends Controller{
/**
* checkFolder
* Makes sure that the a folder exists and does not make a new one if it does. Will check for both a linked folder and also check the folder name.
* @param CallerObject is the DataObject that we are going to make a folder for
* @param FolderRef has one reference that is or needs to be attatched to this object
* @param RootFolder is a string that will be the name of the root folder to put this objects folder into. Defaults to Assets.
* @param Title is a string that is the name and title of the folder
* @param Boolean to set if the DataObjects ID is to be appended to the Folder Title
* @return Folder that this DataObject will use to store it's images.
*/
function checkFolder($CallerObject, $FolderRef, $RootFolder, $Title = '', $AppendID) {
// Sometimes I have found that the Page has a Folder ID for a folder that does not actually exist so I
// check here to make sure that if the ID exists so also does the entry in the Files table and that it also exists
// in the filesystem.
$FolderRef.="ID";
if (!$Title)
$Title = SiteTree::generateURLSegment($CallerObject->Title);
else $Title = SiteTree::generateURLSegment($Title);
$folderTitle = $Title;
if ($AppendID)
$folderTitle .= '_ID' . $CallerObject->ID;
if (!$RootFolder) $RootFolder = 'assets';
if ($CallerObject->$FolderRef > 0)
{
$supposedFolder = DataObject::get_by_id("Folder", $CallerObject->$FolderRef); // If the ID exists, find if there is a folder in the database of that ID
if ($supposedFolder && file_exists($_SERVER{'DOCUMENT_ROOT'} . "/" . $supposedFolder->Filename)) // Make sure the Folder exists in the file system.
{
$supposedFolder->Title = $folderTitle;
$supposedFolder->setName($folderTitle); // If all is good so far make sure the Folder has the right name.
$supposedFolder->write();
}
else
{
// If the ID exists and the database knows about the Folder but for some reason it was deleted from the filesystem,
// make a new folder and set the new ID
$galleries = Folder::findOrMake($RootFolder);
$galleries->Title = $RootFolder;
$galleries->write();
$folder = Folder::findOrMake($RootFolder. "/" . $folderTitle);
$folder->Title = $folderTitle;
$folder->setName($folderTitle);
$folder->write();
$CallerObject->$FolderRef = $folder->ID;
$CallerObject->write();
}
}
else if( !$CallerObject->$FolderRef || $CallerObject->$FolderRef == 0) // If there is no folder anywhere then go ahead and make the dang thing.
{
$galleries = Folder::findOrMake($RootFolder);
$galleries->Title = $RootFolder;
$galleries->write();
$folder = Folder::findOrMake($RootFolder. "/" . $folderTitle);
$folder->Title = $folderTitle;
$folder->setName($folderTitle);
$folder->write();
$CallerObject->$FolderRef = $folder->ID;
$CallerObject->write();
}
}
I use setDefaultFolder on two FileAttachmentFields in the same DataObject. I pass the same folder path to each one. I expected that if the folder did not exists the 1st one would create the folder and the second one would use the folder created by the 1st one. However I find that each FileAttachmentField creates a new folder. KickAssetField uses Folder::findormake($folder); Which I have found to be very unsatisfactory in that it often will create duplicates of folders even when they exist already.
I have written my own version of FindOrMake that has a lot more logic and is much more robust. This class does make use of Folder::findormake($folder); but first does a lot more checking for an existing valid folder so it does not fail where the other function does.
Here is my utility class. Maybe it can be incorporated into Kickassets.
<?php
class Utils extends Controller{
} ?>