Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Custom upload directory


Go to End
Reply

11 Posts   3606 Views

Avatar
JoshuaLewis

9 November 2009 at 9:05pm (Last edited: 9 November 2009 9:08pm), Community Member, 76 Posts

Is the process described in [url=http://www.silverstripe.org/archive/show/220484]this[/url] archived thread the best way enable the use of custom upload directories with a FileIFrameField in the cms or is there an easier fix that won't make it difficult to update the silverstripe?

Note - I'm using Silverstripe 2.3.3 with r317 of DataObjectManager.

Avatar
ajshort

9 November 2009 at 9:10pm Community Member, 244 Posts

Yes, you can checkout either the 2.4 branch or trunk from svn (I recommend using the 2.4 branch for stability), and then use the $folderName argument to the constructor. This was broken in the 2.3 series.

Avatar
JoshuaLewis

10 November 2009 at 12:06pm (Last edited: 10 November 2009 12:16pm), Community Member, 76 Posts

Thanks, would that be the 2.4 installer found here? : http://svn.silverstripe.com/open/phpinstaller/branches/2.4

Avatar
JoshuaLewis

10 November 2009 at 4:05pm Community Member, 76 Posts

I'm using DataObjectManager and relying on functionality from it that is more critical than the custom directories. UncleCheese said he hasn't got the module stable with trunk or the 2.4 branch.

So what other options do I have?

Avatar
Double-A-Ron

15 November 2009 at 5:49pm Community Member, 604 Posts

Subscribe

I am currently needing the same thing. I have taken UncleCheese's gallery module (that uses DOM) and checked out how it creates and saves images to directories organised by album name.

It must be possible as he was able to achieve it for Gallery. I have managed to get my page type to create it's own directory when saved using this on the main page class (My Page is called "Publications")

/**
* Overload OnBeforWrite to create or set the Folder ID for this Publication
* This is done as we are automatically storing the issue PDFs in a custom directory for tidyness
*/
function onBeforeWrite() {
parent::onBeforeWrite();

if(isset($_POST['URLSegment'])) {
if($this->FolderID) {
$this->Folder()->setName($_POST['URLSegment']);
$this->Folder()->Title = $_POST['URLSegment'];

$this->Folder()->write();
}
else {
$folder = Folder::findOrMake('publications/'.$_POST['URLSegment']);
$this->FolderID = $folder->ID;
$this->write();
}
}
}

Be sure that your Page has_one Folder first ofcourse. The above code with create the directory if it doesn't already exist and save the FolderID to your page.

Next step is to get the files saved to that path from a FileIFrameField. So I'm picking through ImageGalleryManager (Which extends ImageDataObjectManager). I can see how he's doing it, however he uses ImageField for uploading images, not the IFrame variation, so I'm not sure if it's even possible at this stage.

Aaron

Avatar
Double-A-Ron

15 November 2009 at 7:17pm (Last edited: 15 November 2009 10:57pm), Community Member, 604 Posts

Well, I decided to can this hack due to deadline. What I have done instead is used FileDataObjectManager instead of DataObjectManager after looking at this doc: http://doc.silverstripe.org/doku.php?id=modules:dataobjectmanager (about 1/2 way down).

I still use the code above to create the directory when my page is made (not sure if the next lot of code would do a findOrMake()).

Note:
My page is "Publications" (magazines) - Extends Page
Publications has_many "PublicationIssues" (monthly releases) - Extends DataObject
PublicationIssues has_one "DigitalCopy", which is the File.

Then, in the same Page class, instead of:

// Setup the Issues table Dataobject manager
$issues = new DataObjectManager(
$this,
'PublicationIssues',
'PublicationIssue',
array('Name' => 'Name','ReleaseDate'=>'ReleaseDate'),
'getCMSFields_forPopup'
);
$issues->setAddTitle('PDF Issue');

I use:

// Setup the Issues table Dataobject manager
$issues = new FileDataObjectManager(
$this,
'PublicationIssues',
'PublicationIssue',
'DigitalCopy', // This is the name of the file object in PublicationIssue
array('Name' => 'Name','ReleaseDate'=>'ReleaseDate'),
'getCMSFields_forPopup'
);
$issues->setAddTitle('PDF Issue');
$dest = substr_replace(str_replace('assets/','',$this->Folder()->Filename),"", -1); // DIR is already created. Just get it here.
$issues->setUploadFolder($dest); // Set the file destination field
$issues->setUploadLimit(1); // Set the upload limit (We only want one)

The only difference in the process from the original, is that you upload the file first, and enter the other data afterwards.

The glaring downside that may not be any good for you is that editing existing records display's the same FileIframeField that defaults to "Uploads" when you do a "Replace File". Not so bad for us, as these are magazine issues that never change. If an incorrect PDF is uploaded, it's no big deal to delete the original and redo. Worst case scenario we have a few PDFs sitting in the Uploads directory.

Not the perfect solution, but will cover us until 2.4 is stable.

Aaron

Avatar
banal

15 November 2009 at 10:03pm (Last edited: 15 November 2009 10:12pm), Community Member, 901 Posts

Nice solution there Aaron. Not sure if I would use the URLSegment as folder name though, since users can easily change that and then you'll end up with files for one page, but in different folders? I'd probably use something like 'folder' + PageID, although that's not as readable. Best would probably be an ID based foldername, then change the "Title" of the folder to the URLSegment. Whenever URLSegment changes, change the title of the folder associated with the page.

I'd probably also add the relation to the Folder to the $has_one array.

public static $has_one = array(
   'UploadFolder' => 'Folder'
);

In your DataObjects you could have an onBeforeWrite function that moves the file to the UploadFolder...

protected function onBeforeWrite(){
   // get the file of this DataObject
   $file = $this->MyFileField();

   // get the UploadFolder from the holder of this dataObject
   $folder = $this->HolderPage()->UploadFolder();

   if($file && $folder){
      // check if file isn't stored in folder yet
      if($folder->ID != $file->ParentID){
         // move file to folder
         $file->setParentID($folder->ID);
         $file->write();
      }
   }
   parent::onBeforeWrite();
}

Update If you establish a has_one relation from your Page to an UploadFolder, you can simply create a folder whenever the page is written for the first time (eg. check if it has a folder, if not create one). From that point on you can forget about the issues that might occur when you use URLSegment to determine the upload-folder (since you would use the UploadFolder instead of going the URLSegment route).

Avatar
Double-A-Ron

15 November 2009 at 10:24pm (Last edited: 15 November 2009 10:26pm), Community Member, 604 Posts

Not sure if I would use the URLSegment as folder name though, since users can easily change that and then you'll end up with files for one page, but in different folders

Hmmm. I've been SS developing for 14 days straight so my mind might be a muddle on this one. When the page is first created, the very fisrt block of code checks to see if it has a FolderID, if not, it creates the folder using the URLSegment, and assigns the FolderID (from the Files table) to the page.

So I may be wrong, but wouldn't that ID stay the same no matter what the URL is changed to?

E.G.
One of these pages in my case is called MIR Report. The URLSegment is mir-report. On initial save the folder that is created is called /assets/publications/mir-report.

Lets say the ID for that folder is 30. This is assigned to the MIR Report page's FolderID field in the table.

If I change the Title of the page to "Our MIR Reports" and the URL to "our-mir-reports", the FolderID shouldn't be touched. All that it means is that all the files are dropping into a folder that doesn't exactly reflect the URL anymore. Which isn't a biggie for me.

Can you logic check that for me to save my brain from exploding? I will test tomorrow when I get in.

public static $has_one = array(
'UploadFolder' => 'File'
);

Yes I did that in my Page Type. But based on the ImageGallery module, it was

public static $has_one = array(
'UploadFolder' => 'Folder' // See Folder - The Files table stores both classes.
);

Ta
Aaron

Go to Top