Creating a FORM with CakePHP v2



Use our step by step instructions to create a form to take information on your website easily and efficiently.

# 1 > Model

Ensure you have a Contact.php model

This has the validation of which fields will be required before your form is sent

Name this file 'Contact.php' and place into app/Model

<?php class Contact extends AppModel {

var $name = "Contact";
var $useTable = false;

public $validate = array(

'email' => array(
'rule' => 'email',
'message' => 'Enter your E-Mail',
'allowEmpty' => false
),
'name' => array(
'rule' => 'notEmpty',
'message' => 'Enter your name',
'allowEmpty' => false
)

);

}

# 2 > Element

Next if you have a non-working form already in your page simply cut-paste this form into an element 
-> eg app/View/Elements/a/form.ctp

Where the form was add

<?= $this->Element('a/form'); ?>

# 3 > Modify the form (inside the element)

Replace all the original form tags with new form tags:
-> ensure you copy the classes and id's from the orignal tag or the layout will be broken. 

OPENING TAG: Replace the original "<form......" TO:

<?= $this->Form->create('Contact', array( 'class' => 'CLASSES GO HERE', 'novalidate' => true, 'url' => array('controller' => 'Contacts', 'action' => 'form'))); ?>

 

INPUT TAG: Replace all "<input....." TO:

        <?= $this->Form->input('name', array(
//'label' => '', //leave this blank if you already have a label above
'type' => 'text',
//'id' => '', //copy from original if available
'class' => '', //copy from original tag if available
)); ?>

 

BUTTON TAG: Replace all "<button......" TO:

<?= $this->Form->button('Submit', array('type' => 'submit', 'class' => '')); ?>

 

CLOSING TAG: Replace all "</FORM>" TO:

<?= $this->Form->end(); ?>

 


# 4 > Form Controller

Create a new file "app/Controller/ContactsController.php" / Ensure you change the email address to your email address !!!

<?php
App::uses('AppController', 'Controller');

class ContactsController extends AppController {

function beforeFilter() {
parent::beforeFilter();
}

function form() {
$template = 'default'; //this can be changed to another layout - change the name and create a new file

if (!empty($this->request->data)) {
$this->request->data['Contact']['ip'] = $this->getIp();
$this->Contact->set($this->request->data);
if ($this->Contact->validates()) {
// Data Validated
//pr ($this->request->data);exit;

$to = Configure::read('email.to');
$vars = $this->request->data['Contact'];

if ($this->send($to, $vars, 'Website Submission', $template)) {
$this->Session->setFlash('Message Sent');
$this->render('form-sent');

} else {
$this->Session->setFlash('FATAL: could not send email...');
}

} else {
// Data Not Validated
$this->Session->setFlash('Could not send... check required fields');
}

}

//optional
$this->set('link_contact', true);

}

private function send($to, $vars, $subject, $template = 'default') {

$Email = new CakeEmail();
$Email->viewVars(array(
'subject' => $subject,
'vars' => $vars,
'domain' => Router::url("/", TRUE)
));
//$Email->config('smtp');

if (isset($vars['email'])) {
$Email->from($vars['email']);
}

$Email->to($to);

//$Email->bcc(array('test@undologic.com'));

$Email->subject($subject);
$Email->emailFormat('html');

$Email->template($template);

$sent = $Email->send();

if ($sent) {
return TRUE;
} else {
die ('could not email ');
return FALSE;
}
}

private function getIp () {

if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}

return $ip;
}

}

# 5 > Email layout (template)

Ensure you have the file created: app/View/Layouts/Emails/html/default.ctp
-> You can create different layouts (templates) and call them in the previous step change $template = 'default'; to the new name of the file you create

<?php
/**
*
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.View.Layouts.Email.html
* @since CakePHP(tm) v 0.10.0.1076
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title><?php echo $title_for_layout; ?></title>
</head>
<body>

<?php echo $this->fetch('content'); ?>

</body>
</html>

# 6 > Email render file

Ensure the file exists: app/View/Emails/html/default.ctp

<?php
foreach ($vars as $key => $line):
echo '<p> ' .$key.': '. $line . "</p>\n";
endforeach;
?>
<br/>
<?= 'From domain: '.$domain; ?>

# 7 > Form Controller - View

This is the file that gets used if the validation fails from the home page. The exact same form will appear. Save this file as app/View/Contacts/form.ctp


<div class="container">

<div class="row">
<div class="col-lg-12 contact-banner">
<h1>Title Goes Here</h1>

<div class="row">

<div class="col-lg-12 col-md-12">

<?= $this->Element('a/form'); ?>

</div>

</div>
</div>
</div>
<hr/>
</div>


# 8 > Form Controller - View SENT

This will display after the validation passes and the email is sent. Save this file as app/View/Contacts/form-sent.ctp

<div class="container">
<div class="row">
<div class="col-lg-12 contact-banner">
<h1>Form has been submitted</h1>
</div>
</div>
</div>

# 9 > Flash Messages

In order to see the display of the form status you must add CSS styles
-> Either add this to your styles.css 
OR
-> Create 'added-styles.css' and ensure it is connected to your website

#flashMessage {
position: absolute;
z-index: 99999999999;
width: 100%;
}

.message {
font-size: 14px;
text-align: center;
color: white;
background-color: orange;
}
.error-message {
color: red;
}

# 10 > Spam protection - 1 - modify Model

There are many ways to mitigate spam on your form. We have a simple balance which eliminates a lot (but not all) spam. We chose against the complicated modules that end up annoying customers: Our solution is straight forward, effective and less confrontational. 

In the model add:

public $validate = array(
.... other validtions here ...

'human_check' => array(
'Not empty' => array(
'rule' => 'notEmpty',
'message' => 'Please put the right answer'),
'humancheck' => array(
'rule' => 'checkReverse',
'message' => 'Put the Numbers in Reverse Order')

));

function checkReverse($data){
$random_number = $this->data['Contact']['rand_1'];
$reverse = strrev($random_number);
if ($data['human_check'] == $reverse){
    return true;
}
    return false;
}


# 11 > Spam protection - 2 - modify Controller

=> In controller modify the function with the following code

function form() {
 $this->set('linksReload', true);
if (!empty($this->request->data)) {
     $this->request->data['Contact']['ip'] = $this->getIp();
            $this->Contact->set($this->data);
            if (empty($this->request->data['Contact']['human_check'])) {
                //if the robot removes any form content, we are ensuring this is validated
                $this->Session->setFlash("Please verify you are a human");
            } elseif ($this->Contact->validates()) {
                // Data Validated
                $this->set('hideForm', true);
                $to = Configure::read('email.to');
                $vars = $this->request->data['Contact'];
                if ($this->send($to, $vars, 'Website Submission', $template = 'default')) {
                    $this->Session->setFlash('Message Sent');
                    $this->set('messageSent', true);
                } else {
                    $this->Session->setFlash('Saved... but could not send email');
                }
            } else {
                // Data Not Validated
                $this->Session->setFlash('Could not send... check required fields');
            }

        } else {
            //First time
        }
        //change the random number each time
        $rand_1 = rand(111, 999 );
        $this->request->data['Contact']['rand_1'] = $rand_1;
    }









# 12 > Spam protection - 3- modify View

=>In view add the following for the form fields

<?php $rand_1 = $this->data['Contact']['rand_1']; ?>

<?= $this->Form->create('ModelName'); ?>

<div class="form-group full-width">
<?= $this->Form->input(... other form inputs ..
</div>
<div class="form-group full-width" style="padding-bottom: 8px;">
<?php echo $this->Form->input('rand_1', array(
'value' => $rand_1,
'class' => 'form-control',
'label' => false,
'type' => 'text',
'readonly' => true)); ?>
<?php echo $this->Form->input('human_check', array(
'class' => 'form-control',
'label' => false,
'type' => 'text',
'placeholder' => "Put the number in Reverse Order")); ?>
</div>
<?= $this->Form->button('Submit', array(
'class' => 'btn btn-primary')); ?>
<?= $this->Form->end(); ?>

 


Other Instructions

Below are many other instructions that show you how to use your UpdateCase application