Jump to content


Photo

Does anyone know how to upload a form File threw the api


  • Please log in to reply
8 replies to this topic

#1 peterb

peterb

    Full Member

  • Members
  • PipPipPip
  • 51 posts
  • 2

Posted 05 April 2012 - 12:41 AM

I have a site page, outside the admin with a form. The form uploads a file which then needs to be inserted into a pw File field. Is this possible using the processwire api?

if(isset($_POST['title'])) {
    // Process the form
    echo  "processed... <br>";

    $newpage = new Page();
    $newpage->template = $templates->get("upload");
    $newpage->parent = $pages->get("/uploader-test/");  
    $newpage->name = $_POST['title'];
    $newpage->title = $_POST['title'];
    $newpage->save();
    $newpage->file->add( $_POST['upload'] );  // this throws an error  - [color=#000000][font=Times][size=1]Exception: Item added to Pagefiles is not an allowed type (in httpdocs/pw/wire/core/Array.php line 142)[/size][/font][/color]
    $newpage->save();
}  
?>

<h1>Upload file...</h1>
<form action="" method="post"  enctype="multipart/form-data">
  <input name="id" value="<?=$page->id?>" type="hidden">
  <table>
	<tr><td>File:</td> <td><input name="upload" id="upload" type="file"></td></tr>
	<tr><td>Title:</td> <td><input type="text" name="title"></td></tr>
  </table>
  <input type="submit" value="NEXT" class="subbut">
</form>


#2 Pete

Pete

    Administrator

  • Administrators
  • 1,756 posts
  • 658

  • LocationChester, England

Posted 07 April 2012 - 06:17 PM

Just a quick reply from my mobile so I can't type much detail, but your file data will be accessible through $_FILES['upload'] and not $_POST['upload'].

Hope that helps a little, but for more information (such as where your file sits after submitting your form - it will have to be moved from your server's temp upload folder to the field in PW) you should run a quick search for $_FILES on PHP.net

#3 renobird

renobird

    Sr. Member

  • Members
  • PipPipPipPip
  • 368 posts
  • 235

  • LocationGainesville, Florida

Posted 07 April 2012 - 07:29 PM

If you are still having trouble, I can post some code to help when I"m back at work on Monday.
Right now I have to make 2 dozen easter eggs. :)

#4 peterb

peterb

    Full Member

  • Members
  • PipPipPip
  • 51 posts
  • 2

Posted 09 April 2012 - 12:37 AM

thanks.. this seems to work....

if(isset($_POST['title'])) {
    $newpage = new Page();
    $newpage->template = $templates->get("upload");
    $newpage->parent = $pages->get("/uploader-test/");
    $newpage->name = $_POST['title'];
    $newpage->title = $_POST['title'];
    $newpage->save();

    $path=$newpage->images->path; // GET THE PATH TO THE UPLOADS FOLDER FOR NEW PAGE
    $name = strtolower($sanitizer->name($_FILES['upload']['name']));	//  RUN THE $NAME THROUGH $SANITIZER TO MAKE IT PW COMPATIBLE...
    $file = $path . $name; // DETERMINE THE FINAL DESTINATION AND STORE IT IN $FILE

    if(move_uploaded_file($_FILES['upload']['tmp_name'], $file)) { // MOVE THE FILE TO IT'S DESTINATION USING PHP'S FUNCTION
        $newpage->report_request->add($file);	// ADD IT TO THE PAGE
        $newpage->save();	 // SAVE THE PAGE AGAIN
    }
}


#5 Oliver

Oliver

    Sr. Member

  • Members
  • PipPipPipPip
  • 133 posts
  • 25

  • LocationBasel, Switzerland

Posted 09 April 2012 - 04:20 AM

Had to deal with this prob these days, too. In my opinion, the API should also process the $_FILES var and provide the post files data through $input->files or something within templates etc.

#6 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,526 posts
  • 854

  • LocationVihti, Finland

Posted 09 April 2012 - 05:12 AM

It would be great to have native pw implementation for file uploads.

Peter: you should definitely do some more validation for the file. At least check for file extension (and match them against whitelist), rename the uploaded file etc.. there are plenty of tutorials for how to secure php file uploads.

You can also first upload file anywhere you want on your server, ->add($file) will do the final copying for you.

#7 peterb

peterb

    Full Member

  • Members
  • PipPipPip
  • 51 posts
  • 2

Posted 09 April 2012 - 09:51 AM

indeed, here is the code with validation

if(isset($_POST['title'])) {
    $newpage = new Page();
    $newpage->template = $templates->get("upload");
    $newpage->parent = $pages->get("/uploader-test/");
    $newpage->name = $_POST['title'];
    $newpage->title = $_POST['title'];
    $newpage->save();

    $path=$newpage->images->path; // GET THE PATH TO THE UPLOADS FOLDER FOR NEW PAGE
    $name = strtolower($sanitizer->name($_FILES['upload']['name'])); // RUN THE $NAME THROUGH $SANITIZER TO MAKE IT PW COMPATIBLE...

    // prepend underscores to filename until it's unique...
    while(is_file($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('pdf', 'jpg', 'jpeg', 'gif', 'png')))
  	  throw new WireException("Invalid extension");

    $file = $path . $name; // DETERMINE THE FINAL DESTINATION AND STORE IT IN $FILE

    if(move_uploaded_file($_FILES['upload']['tmp_name'], $file)) { // MOVE THE FILE TO IT'S DESTINATION USING PHP'S FUNCTION
        $newpage->report_request->add($file); // ADD IT TO THE PAGE
        $newpage->save(); // SAVE THE PAGE AGAIN
    }
}


#8 Pete

Pete

    Administrator

  • Administrators
  • 1,756 posts
  • 658

  • LocationChester, England

Posted 09 April 2012 - 10:05 AM

Good work, glad you got it sorted and thanks for posting your working code - that's always useful :)

If you're posting more code in future though, could you use the code tags button (looks like this in blue: <> ) just makes it a bit easier to read - thanks! I've just tweaked your posts to make it a bit easier to follow for others.

#9 ryan

ryan

    Hero Member

  • Administrators
  • 5,773 posts
  • 3122

  • LocationAtlanta, GA

Posted 09 April 2012 - 03:59 PM

$newpage->template = $templates->get("upload");
$newpage->parent = $pages->get("/uploader-test/");


You can also do this in newer versions of PW:

$newpage->template = 'upload';
$newpage->parent = '/uploader-test/';


$newpage->name = $_POST['title'];
$newpage->title = $_POST['title'];


I suggest sanitizing the title, and excluding the name (since PW will autogen it from the title). So the above code would be replaced with this:

$newpage->title = $sanitizer->text($input->post->title);

Had to deal with this prob these days, too. In my opinion, the API should also process the $_FILES var and provide the post files data through $input->files or something within templates etc.


Here is the current PW implementation for uploaded files. Perhaps there is a way we can populate this to $input->files, but currently I think it's best to be more specific when it comes to file uploads since there are added dangers and overhead. The WireUpload class does make things simpler and more secure. It also provides options for handling known quantities, filename sanitization, overwriting vs. making unique filenames, processing ZIP files, handling ajax uploads, etc.
http://processwire.c...ndpost__p__1371
The full class is in /wire/core/WireUpload.php




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users