unclecheese / KickAssets

The KickAssets module for SilverStripe is an alternative to AssetAdmin
http://www.leftandmain.com
40 stars 8 forks source link

FileAttachmentField setDefaultFolder always creates new folder #50

Open micahsheets opened 12 years ago

micahsheets commented 12 years ago

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();
    }

}

} ?>