Okay, here we go. The following is a run-down on how you can add a custom form to an Information page. You could essentially transpose this to any other page, but for the sake of brevity we'll just cover adding it to an Information page.
Down the road I hope to turn this into a VQmod, but for the time being you'll need to be comfortable with just altering core files of OpenCart. Best thing here is to make a backup of the original file and just keep it in the same directory in case you need to backtrack. You'll want to be especially careful when upgrading OpenCart that you make a copy of these modified files before upgrading otherwise you'll lose these changes.
These are the files you will be editing:
/catalog/controller/information/information.php (Information Controller)
/catalog/language/YOUR LANGUAGE/information/information.php (Information Language)
/catalog/view/theme/YOURTHEME/template/information/information.tpl (Information Template)
You'll need these file for reference and to glean some code out of:
/catalog/controller/information/contact.php (Contact Controller)
/catalog/view/theme/YOURTHEME/template/information/contact.tpl (Contact Template)
/catalog/language/YOUR LANGUAGE/information/contact.php (Contact Language)
Step 1:
- Open Contact Template and locate the <form> element in the file.
- Copy everything between <form> and </form>.
- Open Information Template and after the line <?php echo description; ?> paste the form content you just copied.
- Where the it says: <form action="<?php echo $action; ?>"... > just make action="" to tell the form to call itself
Step 2:
- Edit the form to your liking. This is going to require some knowledge of how to format an HTML form, but the vast majority of what you will likely need is right there.
- Once you've added your input, textarea, select, checkbox, radio, etc. etc. options take note of the various PHP variable names. You should see something similar to:
These variables are going to be defined in your Information Controller file (see path directory above).
Step 3:
- Open the Information Controller file and declare an array named 'error' at the top. This is very important because you will get some errors when trying to submit the form without this.
Code: Select all
class ControllerInformationInformation extends Controller {
private $error = array(); // <-- add this line right here!
public function index() {
.....
Now, further down in the Information Controller file you will need to add some information inside of the index() function.
Code: Select all
public function index() {
$this->language->load('information/information');
$this->load->model('catalog/information');
/* Begin adding custom content here */
/**
* In the form data you copied over from the Contact Template you will
* have noticed that there were little bits of code that looked like:
* <?php echo $entry_name; ?>
*
* These variables need to be defined here, and then we'll set them later
* in the Information Language file. Just go ahead and set one of the below
* for each of them that appear in your form.
*/
$this->data['text_name'] = $this->language->get('text_name');
/**
* Now as for sending the mail, you'll want to add the following. I have some changes
* in here from what you will see in the Contact Controller file because I didn't just want to
* send the 'comments' field as the body of my message.
*/
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
$mail = new Mail();
$mail->protocol = $this->config->get('config_mail_protocol');
$mail->parameter = $this->config->get('config_mail_parameter');
$mail->hostname = $this->config->get('config_smtp_host');
$mail->username = $this->config->get('config_smtp_username');
$mail->password = $this->config->get('config_smtp_password');
$mail->port = $this->config->get('config_smtp_port');
$mail->timeout = $this->config->get('config_smtp_timeout');
$mail->setTo($this->config->get('config_email'));
$mail->setFrom($this->request->post['email']);
$mail->setSender($this->request->post['name']);
/**
* Here I set some custom content for the body of the e-mail. You can change this
* or remove it, etc. Seemed to work well for me to get more than just the 'comments'
* field in the email body.
*/
$email_body = 'Name: ' . $this->request->post['name'] . "\n\r";
$email_body .= 'Company: ' . $this->request->post['company'] . "\n\r";
$email_body .= 'Phone: ' . $this->request->post['phone'] . "\n\r";
$email_body .= 'Email: ' . $this->request->post['email'] . "\n\r";
$email_body .= 'Comments: ' . $this->request->post['enquiry'] . "\n\r";
$mail->setSubject(sprintf("Outfitters Request Form", $this->request->post['name']));
$mail->setText(strip_tags(html_entity_decode($email_body, ENT_QUOTES, 'UTF-8')));
$mail->send();
$this->redirect($this->url->link('information/contact/success'));
}
/**
* You will need one of these for every required element in your form.
* So if you have a form with input elements 'name', 'phone', 'email' and
* all are required, then do the following once for each of those input fields.
*/
if (isset($this->error['name'])) {
$this->data['error_name'] = $this->error['name'];
} else {
$this->data['error_name'] = '';
}
// and you will want this at the end of your error declarations
if (isset($this->error['captcha'])) {
$this->data['error_captcha'] = $this->error['captcha'];
} else {
$this->data['error_captcha'] = '';
}
/**
* You will need one of these for every element in your form because
* if a user fails to fill out the form correctly you don't want them to have
* to type everything out again.
*/
if (isset($this->request->post['name'])) {
$this->data['name'] = $this->request->post['name'];
} else {
$this->data['name'] = '';
}
// and again, you don't want to forget your CAPTCHA variable
if (isset($this->request->post['captcha'])) {
$this->data['captcha'] = $this->request->post['captcha'];
} else {
$this->data['captcha'] = '';
}
Okay, let's go over what we've done so far. First of all, we created a form that we wanted based on the layout we copied from the Contact Template form.
Second, we added a bunch of variable declarations and a mail function to the Information Controller. These are necessary because if you don't declare these variables in here OpenCart is going to get all freaky on you when you reload the page.
Well then. Let's carry on.
Step 3:
Still in the Information Controller file you will want to scroll down to the very bottom, and directly before the last curly bracket } you will want to carriage-return a few times and make yourself some space for the following.
Code: Select all
/**
* Here was get the CAPTCHA working correctly so that you
* reduce your spam getting chances. No changes necessary
* in the captcha() function. Just copy and paste.
*/
public function captcha() {
$this->load->library('captcha');
$captcha = new Captcha();
$this->session->data['captcha'] = $captcha->getCode();
$captcha->showImage();
}
/**
* This function you will notice was called up above when we tried to
* send an e-mail. If the following doesn't evaluate to TRUE then you
* are not going to be able to send an e-mail.
*/
private function validate() {
/**
* Here is where you need to set up the validation that will keep your
* form from submitting until everything required is filled in correctly.
*
* This is where that very first declaration of private $error = array();
* becomes necessary. These errors will get assigned to that array above,
* and if these exist will be output on the Information View page below each
* input element that wasn't filled in correctly. You can easily move these
* error elements around on the form by moving the <?php echo $error_name; ?>
* lines. (or whatever the error is you are targeting: email, phone, etc.)
*/
if ((utf8_strlen($this->request->post['name']) < 3) || (utf8_strlen($this->request->post['name']) > 32)) {
$this->error['name'] = $this->language->get('error_name');
}
if (!preg_match('/^[^\@]+@.*\.[a-z]{2,6}$/i', $this->request->post['email'])) {
$this->error['email'] = $this->language->get('error_email');
}
if ((utf8_strlen($this->request->post['phone']) < 7) || (utf8_strlen($this->request->post['phone']) > 3000)) {
$this->error['phone'] = $this->language->get('error_phone');
}
if ((utf8_strlen($this->request->post['enquiry']) < 10) || (utf8_strlen($this->request->post['enquiry']) > 3000) && $this->request->get['information_id'] == 10)) {
$this->error['enquiry'] = $this->language->get('error_enquiry');
}
/**
* I left this following one in because this is a useful example of how you
* can create separate forms on more than one Information Page.
* Essentially what I'm asking OpenCart to do is tell me if we are on a
* specific Information Page that has a form, and if so, execute the
* following code.
*
* In this case, I had two different forms on different Information Pages
* and if I didn't wrap certain elements in this tag it would cause some
* serious issues if I tried to submit one form that didn't have required
* elements from the other!
*
* But if you aren't concerned about having multiple forms, just get rid of
* that first if ($this->request->get['information_id'] == 9) { part.
*/
if ($this->request->get['information_id'] == 9) {
if ((utf8_strlen($this->request->post['product']) < 3)) {
$this->error['product'] = $this->language->get('error_product');
}
if ((utf8_strlen($this->request->post['prod_description']) < 3)) {
$this->error['prod_description'] = $this->language->get('error_prod_description');
}
}
if (!isset($this->session->data['captcha']) || ($this->session->data['captcha'] != $this->request->post['captcha'])) {
$this->error['captcha'] = $this->language->get('error_captcha');
}
/**
* This just tells the page if the form was submitted correctly.
*/
if (!$this->error) {
return true;
} else {
return false;
}
}
Okay. Now that we are finished with that, we should be all done with the Information Controller file.
Step 4:
Open the Information Language file and add the following. Please read the comments in the code section as a straight copy/paste of this probably won't work for your individual needs.
Code: Select all
/**
* Define each of your various errors here. These are going to be loaded in
* as the default errors for your form. If you remember toward the beginning
* of the Information Controller file we declared a few items such as:
* $this->data['error_name'] = $this->error['name']
* Well this is where it is getting that information from.
*/
// Errors
$_['error_name'] = 'Name must be between 3 and 32 characters!';
$_['error_email'] = 'E-Mail Address does not appear to be valid!';
$_['error_enquiry'] = 'Enquiry must be between 10 and 3000 characters!';
$_['error_captcha'] = 'Verification code does not match the image!';
$_['error_phone'] = 'Phone number must be at least 7 characters!';
$_['error_quant'] = 'Please select at least 1 item of interest and a quantity!';
$_['error_prod_description'] = 'Please provide a description of your product!';
$_['error_product'] = 'Please provide a name for your product!';
/**
* And as I had mentioned before, we now need to set the language for
* some of these other form variables such as $entry_name
*
* Just edit the below line and create as many as you need. Just remember
* to rename the 'entry_name' to whatever the variable name is your calling.
*/
$_['entry_name'] = 'First Name:';
...
Hopefully at this point your form is now correctly submitting, you are being directed to the 'Success' page, and an e-mail is arriving in your inbox.
If not, well then please let me know and I'll try and answer your questions.