almonk Posted May 4, 2011 Share Posted May 4, 2011 Hi guys, I'm doing some pretty heavy stuff for a client whereby a logged in user can upload a file to the system. The files get added to the page's file field, $page->files; I've got this code... $page->setOutputFormatting(false); $page->files->add($_FILES['userfile']['tmp_name']); $page->save(); $page->setOutputFormatting(true); ... which uploads the file OK and puts it in the array, however it logs it with the temporary file name (something like php72ha). I want to preserve the original filename and perhaps add a timestamp to it, any ideas how I'd go about achieving this? Thanks Link to comment Share on other sites More sharing options...
ryan Posted May 4, 2011 Share Posted May 4, 2011 Almonk, Here's one way you could do it (below), using ProcessWire's WireUpload class: <?php $page->setOutputFormatting(false); // instantiate the class and give it the name of the HTML field $u = new WireUpload('userfile'); // tell it to only accept 1 file $u->setMaxFiles(1); // tell it to rename rather than overwrite existing files $u->setOverwrite(false); // have it put the files in their final destination. this should be okay since // the WireUpload class will only create PW compatible filenames $u->setDestinationPath($page->files->path); // tell it what extensions to expect $u->setValidExtensions('jpg', 'jpeg', 'gif', 'png'); // execute() returns an array, so we'll foreach() it even though only 1 file foreach($u->execute() as $filename) $page->files->add($filename); // save the page $page->save(); Another way to do it would be a more traditional PHP way: <?php $page->setOutputFormatting(false); // we run the $name through $sanitizer to make it PW compatible... // ...this prevents the possibility of it getting renamed on the add() call below $name = strtolower($sanitizer->name($_FILES['userfile']['name'])); // prepend underscores to filename until it's unique... // ...this is just one possible way to handle duplicate filenames while(is_file($page->files->path . $name)) $name = "_" . $name; // validate the file extension $pos = strrpos($name, "."); if(!$pos) throw new WireException("File is missing extension"); $ext = substr($name, $pos+1); if(!in_array($ext, array('jpg', 'jpeg', 'gif', 'png'))) throw new WireException("Invalid extension"); // determine the final destination and store it in $file $file = $page->files->path . $name; // move the file to it's destination using PHP's function if(move_uploaded_file($_FILES['userfile']['tmp_name'], $file)) { // add it to the page $page->files->add($file); /// save the page $page->save(); } Btw, no need to turn outputFormatting back on unless you are rendering parts of that page in the same request. Neither of these examples perform much error checking, which you may want to add. Though the WireUpload class will populate PW's "$notices" API var with any errors: <?php foreach($notices as $notice) { if($notice instanceof NoticeError) { echo "<p>Error: {$notice->text}</p>"; } } If you are using the PW's admin templates, then it already does something like the above snippet. 7 Link to comment Share on other sites More sharing options...
almonk Posted May 4, 2011 Author Share Posted May 4, 2011 Ryan, you are a lifesaver. Cheers! Link to comment Share on other sites More sharing options...
Sylvio Posted October 10, 2011 Share Posted October 10, 2011 Hi Ryan, In your first snippet (using WireUpload class) I had to change somethings to make it work, first passing the extensions as an array and second this line foreach($u->execute() as $filename) $page->add($filename); I had to change it to: foreach($u->execute() as $filename) $page->files->add($filename); (added the field in the add method) Everything works correct, one question, how do I update the 'Description' of the file field after the file has been added? 1 Link to comment Share on other sites More sharing options...
ryan Posted October 10, 2011 Share Posted October 10, 2011 Thanks scarota, I have updated the original post for that fix. To update the description, you first need to get the file that was added. If you just added it, you could use the last() method: $file = $page->files->last(); Once you've got the file, you can set it's description like this: $file->description = 'the description'; Remember to save the page. Link to comment Share on other sites More sharing options...
Sylvio Posted October 12, 2011 Share Posted October 12, 2011 AWESOME!!! Thank you Link to comment Share on other sites More sharing options...
Martijn Geerts Posted July 18, 2012 Share Posted July 18, 2012 Just to make Ryan's code complete: In your first snippet (using WireUpload class) I had to change somethings to make it work, first passing the extensions as an array $u->setValidExtensions(array('jpg', 'jpeg', 'gif', 'png')); tnx Ryan & Sylvio 1 Link to comment Share on other sites More sharing options...
onjegolders Posted November 4, 2012 Share Posted November 4, 2012 You're right Martijn, the array() needs adding, thanks. Link to comment Share on other sites More sharing options...
benbyf Posted May 11, 2016 Share Posted May 11, 2016 is there any links to examples of saving files to a new page within the _func.php file? not quite sure how to pass the file around, what i have as far: function saveUserContentLocationPage($name, $uc_email, $uc_story, $uc_lat, $uc_lng){ // check to see if content available if($name){ $t = time(); // setup page $p = new Page(); // create new page object $p->template = 'user-content-location'; // set template $p->parent = wire('pages')->get("/map-stories/"); // set the parent $p->name = $name .'-'. $t; // give it a name used in the url for the page $p->title = $name; // set page title (not neccessary but recommended) $p->addStatus(Page::statusHidden); $p->save(); // setup file save // instantiate the class and give it the name of the HTML field $u = new WireUpload('uc_file'); // tell it to only accept 1 file $u->setMaxFiles(1); $u->setDestinationPath($p->file->path); foreach($u->execute() as $filename) $p->file->add($filename); // execute() returns an array, so we'll foreach() it even though only 1 file $p->save(); Link to comment Share on other sites More sharing options...
LostKobrakai Posted May 11, 2016 Share Posted May 11, 2016 You shouldn't use the assets path of the page as upload destination. Create a temp. folder with wireTempDir() to upload files to. They'll be automatically moved to the correct location when being added to the page's file field. 1 Link to comment Share on other sites More sharing options...
benbyf Posted May 11, 2016 Share Posted May 11, 2016 Im afraid to say, i might need a little more in the way of example as i've never needed to manipulate user uploads in PW before. Files being submitted by html5 <input type="file"> Anything more would be very useful. Link to comment Share on other sites More sharing options...
LostKobrakai Posted May 11, 2016 Share Posted May 11, 2016 Probably the best example out there: https://gist.github.com/somatonic/5233338 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now