Jump to content

"Unable to move uploaded file" on front-end upload form


Marc
 Share

Recommended Posts

I've wasted many hours trying to get file uploads working on my front-end form, trying different ways of doing it by following examples on the forum and finally by stripping my form and adding some debug features. Looks like ProcessWire is not able write to my temp directory. The form below gets its template via POST. The template includes a file upload field called "sm_files". I have manually set the upload directory and even let ProcessWire write that directory itself by deleting the directory. Folder permissions should be in order. Writing a test.txt file to the upload folder works just fine. Running the code below returns this error:

Unable to move uploaded file to: /Applications/MAMP/htdocs/ProcessWire/site/assets/files/.temp/test.png

The test.png file that is being copied is already in the assets/files folder. Suggestions are more than welcome at this point...

$page_id = (int) $input->post->select_product; // page ID

// Set a temporary upload folder where the files are stored during form processing
// RC: precede temp dir with a period to ensure it remains non-web accessible
//$upload_path = $config->paths->assets . "files/.temp/";
$upload_path = "/Applications/MAMP/htdocs/ProcessWire/site/assets/files/.temp/";

// test if the upload folder is writable
file_put_contents ($upload_path.'/test.txt', 'Hello File');

// RC: create temp path if it isn't there already
if(!is_dir($upload_path)) {
    if(!wireMkdir($upload_path)) throw new WireException("No upload path"); 
}

// show empty form
if ($page_id) {
    $p = $pages->get($page_id);
    $template = $p->template->name; // this is the template where we will get the fields from

    // make a form
    $form = $modules->get('InputfieldForm');
    $form->method = 'post';
    $form->action = './';
    $form->attr("id+name",'aanvraag-form');

    // add the page's fields to the form
    $fields = $p->fieldgroup;
    foreach ($fields as $field) {
        $inputfield = $fields->{$field->name}->getInputfield($p);
        $form->append($inputfield);
    }

    // add select_product to the form
    $field = $modules->get("InputfieldHidden");
    $field->attr('id', 'select_product');
    $field->attr('name', 'select_product');
    $field->value = $page_id;
    $form->append($field); // append the field

    // add a submit button to the form
    $submit = $modules->get('InputfieldSubmit');
    $submit->name = 'save_new_aanvraag';
    $submit->attr("value", "Go");
    $form->append($submit);

    // only show the form if it was not just submitted/processed
    if (!$input->post->save_new_aanvraag)
        echo $form->render();
}

// process the form if it was submitted
if ($input->post->save_new_aanvraag) {
    // now we assume the form has been submitted.
    // tell the form to process input from the post vars.
    $form->processInput($input->post);
    
    // new wire upload
    $u = new WireUpload('sm_files');
    $u->setMaxFiles(2);
    $u->setMaxFileSize(200*1024);
    // tell it to rename rather than overwrite existing files
    $u->setOverwrite(false);
    $u->setDestinationPath($upload_path);
    $u->setValidExtensions(array('jpg', 'jpeg', 'gif', 'png'));

    // execute upload and check for errors
    $files = $u->execute();

    if(!$u->getErrors()) {

        echo "<p>No errors!</p>";
    }
    else {
        // remove files
        foreach($files as $filename) unlink($upload_path . $filename);

        // get the errors
        foreach($u->getErrors() as $error) echo "<p class='error'>$error</p>";
    }
}
Link to comment
Share on other sites

Got it working. Here's my working code in case anybody is interesting (suggestions on improving it are welcome as I'm a ProcessWire newbie):

$page_id = (int) $input->post->select_product; // page ID

// Set a temporary upload folder where the files are stored during form processing
// RC: precede temp dir with a period to ensure it remains non-web accessible
//$upload_path = $config->paths->assets . "files/.temp/";
$upload_path = "/Applications/MAMP/htdocs/ProcessWire/site/assets/files/.temp/";

// RC: create temp path if it isn't there already
if(!is_dir($upload_path)) {
    if(!wireMkdir($upload_path)) throw new WireException("No upload path"); 
}

// show empty form
if ($page_id) {
    $p = $pages->get($page_id);
    $template = $p->template->name; // this is the template where we will get the fields from

    // make a form
    $form = $modules->get('InputfieldForm');
    $form->method = 'post';
    $form->action = './';
    $form->attr("id+name",'aanvraag-form');

    // add the page's fields to the form
    $fields = $p->fieldgroup;
    foreach ($fields as $field) {
        $inputfield = $fields->{$field->name}->getInputfield($p);
        $form->append($inputfield);
    }

    // add template name field to the form
    $field = $modules->get("InputfieldHidden");
    $field->attr('id', 'Inputfield_template_name');
    $field->attr('name', 'template_name');
    $field->value = $template;
    $form->append($field); // append the field

    // add select_product to the form
    $field = $modules->get("InputfieldHidden");
    $field->attr('id', 'select_product');
    $field->attr('name', 'select_product');
    $field->value = $page_id;
    $form->append($field); // append the field

    // add a submit button to the form
    $submit = $modules->get('InputfieldSubmit');
    $submit->name = 'save_new_aanvraag';
    $submit->attr("value", "Go");
    $form->append($submit);

    // only show the form if it was not just submitted/processed
    if (!$input->post->save_new_aanvraag)
        echo $form->render();
}

// process the form if it was submitted
if ($input->post->save_new_aanvraag) {
    
    // new wire upload
    $u = new WireUpload('images');
    $u->setMaxFiles(2);
    $u->setMaxFileSize(200*1024);
    // tell it to rename rather than overwrite existing files
    $u->setOverwrite(false);
    $u->setDestinationPath($upload_path);
    $u->setValidExtensions(array('jpg', 'jpeg', 'gif', 'png'));

    // execute upload and check for errors
    $files = $u->execute();

    if(!$u->getErrors()) {
        // now we assume the form has been submitted.
        // tell the form to process input from the post vars.
        $form->processInput($input->post);

        // validation
        $email = $form->get("email");
        if ($email && (strpos($email->value,'@hotmail') !== FALSE)) { 
            // attach an error and it will get displayed along the field
            $email->error("Sorry we don't accept hotmail addresses for now.");
        }

        // see if any errors occurred
        if (count( $form->getErrors() )) {
            // re-render the form, it will include the error messages
            echo $form->render();
        } else {
            // successful form submission
            $np = new Page(); // create new page object
            $np->template = $form->get("template_name")->value; // set template
            $np->parent = $pages->get('/aanvraag/'); // set the parent
            $np->of(false); // turn off output formatting before setting values
            $np->save();

            foreach ($np->fields as $f) {
                // do not sanitize or set Image and File fields here, because that will happen at the next step which will break if we do not skip images and files here
                if ($f->type == 'FieldtypeImage' || $f->type == 'FieldtypeFile') continue;

                echo $inputval = $form->get($f->name)->value;
                // sanitize fields
                if ($f->type == 'FieldtypePageTitle') {
                    $sanitizer->text($inputval);
                    // also set page name based on title
                    $np->set('name', $sanitizer->pageName($inputval, true));
                }
               
                if ($f->type == 'FieldtypeEmail') $sanitizer->email($inputval);
                if ($f->type == 'FieldtypeText') $sanitizer->text($inputval);
                if ($f->type == 'FieldtypeTextarea') $sanitizer->textarea($inputval);
                if ($f->type == 'FieldtypeInteger') $inputval = (int) $inputval;

                // attach fields to page
                $np->set($f->name, $inputval);
            }

            // add images upload
            foreach($files as $filename) {
                $np->images = $upload_path . $filename;
            }

            $np->save(); //create the page

            // remove all tmp files uploaded
            foreach($files as $filename) unlink($upload_path . $filename);

            echo "<p>Page saved.</p>";
        }
    }
    else {
        // remove files
        foreach($files as $filename) unlink($upload_path . $filename);

        // get the errors
        foreach($u->getErrors() as $error) echo "<p class='error'>$error</p>";
    }
} else {
    //echo $form->render();
}
  • Like 1
  • Confused 1
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...