robguy21
1/14/2016 - 6:49 PM

form_page_controller.php

<?php
/**
 *
 * Let's make a form controller!
 * @package ProcessWire
 */
class FormPageController extends ApplicationController {
  function before() {
        $this->view = new View($this);
        $this->js_add_script('../js/inputfieldfilecustom.js');
  }
  function index() {
    return $this->render(array(
        'form' => $this->get_competition_form(),
      )
    );
  }
  function get_competition_form() {
    $mailAdmin = wireMail();
    $mailSubmitter = wireMail();
    $modules = wire('modules');
    $config = $this->config;
    $input = $this->input;
    $page = $this->page;
    $pages = $this->pages;
    $sanitizer = $this->sanitizer;
    $session = $this->session;
    $co_name = "CO Name";
    $view = new View($this);
    // Lets declare the upload path up here since it should be declared before hand...
    // In actual fact I don't know if this is being used. Best to test this later on.
        // But either way this is some good code to have around.
    $upload_path = $config->paths->assets . "files/.tmp_uploads/";
    // Create temp path if one doesn't exist yet
    if(!is_dir($upload_path)) {
      if(!wireMkdir($upload_path)) throw new WireException("No upload path");
    }
    $recipient_email = $pages->get('template=form_page')->email; // Get that nifty email address!
    $message_success = '<div class="wrap island"><p>Youre a champ!</p></div>'; // Some original success message we have here
    $output = '';
    // add groups for sections in form
    // Get that form ready and modify its markup and classes

    $form = $modules->get("InputfieldForm");
    $form->setMarkup(array(
      'list' => "<div {attrs}>{out}</div>",
      'item' => "<div {attrs}>{out}</div>",
      'item_label' => "<label class='required_-target' for='{for}'>{out}</label>",
      'item_content' => "{out}",
       // This js-swap is a cool thing Dewald made to switch where the error message appears
      'item_error' => "<p class='js-swap error-message'>Please complete the field</p>",
      'item_description' => "<p>{out}</p>",
      'item_head' => "<h2>{out}</h2>",
      'item_notes' => "<p class='notes'>{out}</p>"
    ));
    $form->setClasses(array(
      'list' => 'gw',
      'list_clearfix' => '',
      'item' => '{class} g',
      'item_required' => 'required',
      'item_error' => 'missing-required',
      'item_collapsed' => '',
      'item_column_width' => '',
      'item_column_width_first' => ''
    ));
    $form->action = "./";
    $form->method = "post";
    $form->attr("id+name",'contact-form');
    $form->attr("enctype", "multipart/form-data");
    $header = "<div class='island'><h3>Entry Form</h3></div>";
    
    // create an input for a visitor's title
    $field_text = $modules->get("InputfieldText");
    $field_text->label = "Label";
    $field_text->required = 1;
    $field_text->attr('id+name','title'); // This is important for forms.. if you don't know stackoverflow is great.
    $field_text->attr('class', 'someClass');
    $field_text->wrapClass = 'grid-size'; // This is great for setting up responsive or grid based forms!
    $form->append($form_text);
    
    // create an input for a visitor's email
    $field_email = $modules->get("InputfieldEmail");
    $field_email->label = "Email";
    $field_email->required = 1;
    $field_email->attr('class', 'someClass');
    $field_email->attr('id+name','email');
    $field_email->wrapClass = 'grid-size';
    $form->append($form_email);
    
    /* User is going to want to upload images right? */
    $field_images = $modules->get("InputfieldFile");
    $field_images->label = "Images";
    $field_images->description = "Upload your images maximal 3 files.";
    $field_images->required = 0;
    $field_images->attr("name+id",'images');
    $field_images->destinationPath = $upload_path;
    $field_images->extensions = "jpg jpeg gif png";
    $field_images->maxFiles = 10;
    $field_images->maxFilesize = 2; // This is measured in MB... you can also set max dimensions but who wants to be that guy?
    $form->append($form_images);
    
    /* Okay at first this seems silly but we're basically just generating something based on another partial */
    $field_partial = $modules->get('InputfieldMarkup'); // It's a partial that contains markup. Pretty self explanatory.
    $field_partial->attr('value', $this->view->partial('partial/partialfile')); //The value of this field comes from a partial
    $form->append($field_partial);
    
    /* Let's start killing off those robots */
    // implement basic honeypot spam protection
    $form_honeypot_markup = $modules->get('InputfieldMarkup');
    $form_honeypot_markup->wrapClass = 'visuallyhidden';
    $form_honeypot_markup->attr('value', '<label for="sendemail" style="display:none;">carbon life forms, don\'t enter this checkbox!</label>');
    $form->append($form_honeypot_markup);
    $form_honeypot = $modules->get('InputfieldCheckbox');
    $form_honeypot->label = " ";
    $form_honeypot->attr('id+name','sendemail');
    $form_honeypot->attr('style', 'display:none;');
    $form_honeypot->wrapClass = 'visuallyhidden';
    $form->append($form_honeypot);
    
    // create a submit button
    $form_submit = $modules->get("InputfieldSubmit");
    $form_submit->label - " ";
    $form_submit->skipLabel = Inputfield::skipLabelBlank;
    $form_submit->attr("value","submit");
    $form_submit->attr("id+name","submit");
    $form_submit->attr("class","btn btn_-base");
    $form_submit->wrapClass = 'someClass';
    $form->append($form_submit);
    
    // check if the form was submitted
    if ($input->post->submit) {
      // process the submitted form
      $form->processInput($input->post);
      // check if honeypot is checked
      $spam_field = $form->get("sendemail");
      $spam_action = $sanitizer->text($input->post->sendemail);
      // if it is checked, add an error to the error array
      if ($spam_action == 1) {
        $spam_field->error("You're probably a robot so you're way too cool to be here.");
        // write this attempt to a log
        $spam_log = new FileLog($config->paths->logs . 'detectedspam.txt');
        $spam_log->save('Spam caught: '.$sanitizer->textarea($input->post->body));
      }
      // check if there are errors in the submission
      if($form->getErrors()) {
        $output = $form->render();
      } else {
        
      // Okay now lets upload those images!
      $other_photos = new WireUpload('images'); // Reference field name in HTML form that uploads photos
      $other_photos->setMaxFiles(10);  // Allow 10 other photos
      $other_photos->setOverwrite(false);  // Use the temporary location set above
      $other_photos->setDestinationPath($upload_path); 
      $other_photos->setValidExtensions(array('jpg', 'jpeg', 'png', 'gif'));
      $other_files = $other_photos->execute();
    // Now this looks as if we are duplication fields from the inputfieldfiles... we are. I am not sure yet as to why, rushed for time so going to have to leave it here for now

      // Create page
      $uploadpage = new Page();
      $uploadpage->template = "competition-entry";
      $uploadpage->parent = $pages->get("/competition-entry-list/");
        // sanitise inputs
        $field_text      = $sanitizer->text($input->post->surname);
        $field_email        = $sanitizer->email($form->get('email')->value);

        /* This part makes a page that contains whatever we need */
        // Populate Page and make it Unique
        // This is from a previous project. It's pretty self explanatory what I'm doing here though
        $uploadpage->title = $sender_name . " " . $sender_surname . " - " . uniqid(); // We need to make sure every page title will be unique
        $uploadpage->headline = $sender_name . " " . $sender_surname;
        $uploadpage->text_field_primary = $sender_country . " - " . $sender_city;
        $uploadpage->text_field_secondary = $sender_number;
        $uploadpage->email = $sender_email;
        $uploadpage->body = $sender_story;

        // We're going to save the page now BEFORE we throw the images into the mix.
        // Also we don't want this page to be accessible so lets make it unpublished because it has self image issues. hardi har har..
        $uploadpage->addStatus(Page::statusUnpublished);
        $uploadpage->save();

        // Lets loop through all the submitted files and and add it.
        // Take special note that we are NOT removing these files from the system.
        foreach($other_files as $other_file)
        {
          $uploadpage->message("Added file: $other_file");
          $uploadpage->images->add($upload_path . $other_file);
          // unlink($pathname); <!-- This bad boy right here removes the images. Sometimes you need it, sometimes you dont. In this case I'm not going to use it.
        }
        $uploadpage->save();

        // We're going to need to send the admin a link to the admin view of the page
        // It looks a bit dirty but it gets the job done
        $newSubmissionUrl = $config->httpHost . $config->urls->admin . 'page/edit/?id=' . $uploadpage->id;
        
        // Here we are including the email partials
        ob_start();
        include './views/email/form-recipient.html.php';
        $recipient_msg = ob_get_clean();
        ob_start();
        include './views/email/form-sender.html.php';
        $sender_msg = ob_get_clean();
        
        // Generating Content for email to admin
        $mailAdmin
          ->to($recipient_email)
          ->from($sender_email)
          ->subject("{$co_name} - Competition Entry")
          ->bodyHTML($recipient_msg)
          ->send();
        
        // Generating Content for email to user
        $mailSubmitter
          ->to($sender_email)
          ->from($recipient_email)
          ->subject("{$co_name} - Thank you for your entry")
          ->bodyHTML($sender_msg)
          ->send();
        
        // Redirect on Success
        $session->redirect("./success");
      }
    } else {
      // render form without processing
      $output = $form->render();
    }
    return $output;
  }
}

// And that's the story of how it took me nearly a week and a half to figure this out.