Jump to:

23367 Posts in 18143 Topics by 2863 members

General Questions

SilverStripe Forums » General Questions » Custom upload directory

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

Page: 1 2
Go to End
Author Topic: 3529 Views
  • JoshuaLewis
    Avatar
    Community Member
    76 Posts

    Custom upload directory Link to this post

    Is the process described in this 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.

  • ajshort
    Avatar
    Community Member
    244 Posts

    Re: Custom upload directory Link to this post

    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.

  • JoshuaLewis
    Avatar
    Community Member
    76 Posts

    Re: Custom upload directory Link to this post

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

  • JoshuaLewis
    Avatar
    Community Member
    76 Posts

    Re: Custom upload directory Link to this post

    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?

  • Double-A-Ron
    Avatar
    Community Member
    604 Posts

    Re: Custom upload directory Link to this post

    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

  • Double-A-Ron
    Avatar
    Community Member
    604 Posts

    Re: Custom upload directory Link to this post

    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

  • banal
    Avatar
    Community Member
    901 Posts

    Re: Custom upload directory Link to this post

    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).

  • Double-A-Ron
    Avatar
    Community Member
    604 Posts

    Re: Custom upload directory Link to this post

    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

    3529 Views
Page: 1 2
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.