CakePHP 2.1 Contact Form Data Won't Save - php

I have a few different contact forms in my CakePHP 2.0 application. All of the contact forms are emailing as they should, but I need this particular one to also save the form results to the database. The post data is populating, and I can print_r() and pr() the form data. I can even email the post data. However, it is not actually saving the data to the model table. The database table is named contacts and has the following fields: id, publication, company, name, email, phone, message, contact_method, selections, received.
Here is my model:
class Contact extends AppModel {
public $name = 'Contact';
public $useTable = 'contacts';
public $validate = array(
'name' => array(
'rule' => 'notEmpty'
),
'email' => array(
'rule' => 'notEmpty'
)
);
Here is my controller:
App::uses('CakeEmail', 'Network/Email');
class ContactsController extends AppController
{
public $name = 'Contacts';
public $helpers = array('Html', 'Form', 'Js');
public $components = array('Email', 'Session');
...
public function contact_att() {
if ($this->request->is('post')) {
//pr($this->data);
if ($this->Contact->save($this->request->data)) {
$this->redirect('/pages/publications-alabama-turf-times');
$this->Session->setFlash("Mesage Saved!");
}
else {
print_r($this->data);
Configure::write('debug', 2);
debug($this->Contact->validationErrors);
exit;
}
}
Here is the form in my view:
echo $this->Form->create('Contact', array(
'action' => 'contact_att',
'label' => '',
'class' => 'pubs'));
echo $this->Form->input('publication', array(
'type' => 'hidden',
'value' => 'A',
'label' => ''));
echo $this->Form->input('company', array(
'default' => 'company name (required)',
'onfocus' => 'clearDefault(this)',
'label' => array(
'text' => 'Company Name',
'style' => 'position:absolute;')));
echo $this->Form->input('name', array(
'default' => 'name (required)',
'onfocus' => 'clearDefault(this)',
'label' => array(
'text' => 'Your Name',
'style' => 'position:absolute;')));
echo $this->Form->input('phone', array(
'default' => 'phone number (required)',
'onfocus' => 'clearDefault(this)',
'label' => array(
'text' => 'Your Phone Number',
'style' => 'position:absolute;')));
echo $this->Form->input('email', array(
'default' => 'email (required)',
'onfocus' => 'clearDefault(this)',
'label' => array(
'text' => 'Your Email Address',
'style' => 'position:absolute;')));
echo $this->Form->input('message', array(
'label' => array(
'text' => 'Your Message',
'style' => 'position:absolute;')));
echo $this->Form->input('contact_method', array(
'type' => 'radio',
'style' => 'padding-right:20px;',
'legend' => 'Preferred contact method:',
'options' => array(
'phone' => 'phone',
'email' => 'email'
)
));
echo $this->Form->input('selections', array(
'type' => 'select',
'label' => array(
'text' => 'I am interested in the following:',
'style' => 'display:block; width:250px; margin-left:-12px;padding-bottom:15px;'),
'multiple' => 'checkbox',
'options' => array(
'ABC' => 'ABC',
'DEF' => 'DEF',
'GHI' => 'GHI'
)
));
echo $this->Form->end('Submit');
What am I missing?

After much banging my head on the desk, the answer turned out to be simple -- of course. I simply removed this line from my model. I thought that having it set to the correct table would be fine, but turns out, it needed to be removed:
public $useTable = 'contacts';

You can try with this:
$this->Contact->save($this->request->data, false);

Try with:
debug($this->model->invalidFields());
sometimes, model have errors on validations, and not shows with validationErrors()
also note this..
If $fieldList is not supplied, a malicious user can add additional fields to the form data (if you are not using SecurityComponent), and by this change fields that were not originally intended to be changed.
http://book.cakephp.org/2.0/en/models/saving-your-data.html
take some time and read this documentation is very important, I hope have helped you.

Friend, I see your problem, check..
This line is missing in your controller
public $uses = array('Contact');
put and try, then you told me...

Is post will only return true when the form sets the posted hidden flag. So try this instead.
if(!empty($this->request->data))

Pls add this line
$this->Contact->create();
before you tried to save using
if ($this->Contact->save($this->request->data)) {

Related

Best practice of handling user's input in Codeigniter

I wonder what is the best and the most secured way of handling user's input in Codeigniter. Basically I have form for user's profile made by form helper like this:
echo form_open();
echo form_label($this->lang->line('user_update_profile_first_name'), 'first_name');
echo form_input(array('type' => 'text', 'name' => 'first_name', 'id' => 'first_name', 'maxlength' => '255', 'required' => 'true', 'value' => set_value('first_name', $user_profile['first_name'], false)));
echo form_label($this->lang->line('user_update_profile_last_name'), 'last_name');
echo form_input(array('type' => 'text', 'name' => 'last_name', 'id' => 'last_name', 'maxlength' => '255', 'required' => 'true', 'value' => set_value('last_name', $user_profile['last_name'], false)));
echo form_label($this->lang->line('user_update_profile_birth_date'), 'birth_date');
echo form_input(array('type' => 'text', 'name' => 'birth_date', 'id' => 'birth_date', 'maxlength' => '255', 'required' => 'true', 'value' => set_value('birth_date', $user_profile['birth_date'],
echo form_submit(array('value' => $this->lang->line('user_update_profile_form_submit'), 'name' => 'submit', 'class' => 'btn btn-primary'));
echo form_close();
As you can see in my code I am skipping xss filtering provided in set_value function due to xss filtering is done in form_input() already.
My Controller function for inserting data in DB looks like this
$validation_rules = array(
array(
'field' => 'first_name',
'label' => $this->lang->line('user_update_profile_validation_error_first_name'),
'rules' => 'required|trim|max_length[255]'
),
array(
'field' => 'last_name',
'label' => $this->lang->line('user_update_profile_validation_error_last_name'),
'rules' => 'required|trim|max_length[255]'
),
array(
'field' => 'birth_date',
'label' => $this->lang->line('user_update_profile_validation_error_birth_date'),
'rules' => 'required|trim|max_length[255]'
)
);
$this->form_validation->set_rules($validation_rules);
if($this->form_validation->run()) {
$user_data = array(
'user_id' => $this->profile_data->user_id,
'first_name' => $this->input->post('first_name', TRUE),
'last_name' => $this->input->post('last_name', TRUE),
'birth_date' => date('Y-m-d',strtotime($this->input->post('birth_date', TRUE)))
);
if($this->user_model->update_user_profile($user_data)) {
$view_data['success'] = TRUE;
$new_site_language = $this->language_model->getLanguageFolderById($user_data['site_language']);
$this->lang->load('application/user_lang', $new_site_language);
} else {
$view_data['server_error'] = TRUE;
}
}
I am filtering here data from user by provided $this->input->post('', true) xss filter. In model I am inserting data to DB by active record class. I am just wondering if this is the right and secure way of handling users input if there is not needed something like htmlspecialchars() . But what happens when someone have some "special" chars in name like for example Someone O'Sombody or some names from foreign countries? I am also showing data in navbar using html_escape($this->profile_data->first_name) to prevent running users potentially dangerous code. Did I get this whole "security thing" in the right way or there should be something changed because of potential danger?

filtering cakedc search results

i'm using cakeDC's search plugin in my app. can;t seem to figure out why the results are empty if i pass no value in the username field i'm searching but have the account type filter set to either admin or user For the record, having the filter set to all with the username field empty will output all the users in the system trying to replicate the behavior of searches having the account type filter set to all with an empty username search field for having the account type filter set to either 2 user types
here's the relevant code if needed:
controller
public $components = array('Paginator', 'Session','Search.Prg');
public $presetVars = array(
array('field' => 'username', 'type' => 'value'),
array('field' => 'account_type', 'type' => 'value'));
public function admin_index() {
$this->Prg->commonProcess();
$this->paginate = array(
'conditions' => $this->User->parseCriteria($this->passedArgs));
$this->set('users', $this->Paginator->paginate(),'session',$this->Session);
model
public $actsAs = array('Search.Searchable');
public $filterArgs = array( array('name' => 'username', 'type' => 'query', 'method' => 'filterName'),
array('name' => 'account_type', 'type' => 'value'),
);
public function filterName($data, $field = null) {
$nameField = '%' . $data['username'] . '%';
return array(
'OR' => array(
$this->alias . '.username LIKE' => $nameField,
));
}
view search form
<div><?php echo $this->Form->create('User', array(
'novalidate' =>true,'url' => array_merge(array('action' => 'index','admin'=> true), $this->params['pass'])
)); ?>
<?php
$account_types = array(
'' => __('All', true),
0 => __('admin', true),
1 => __('user', true),);
echo $this->Form->input('username', array('div' => false, 'empty' => true)); // empty creates blank option.
echo $this->Form->input('account_type', array('label' => 'account_type', 'options' => $account_types));
echo $this->Form->submit(__('Search', true), array('div' => false));
echo $this->Form->end();
?></div>
Try to put 'empty' and allowEmpty in username and account_type like this:
public $filterArgs = array( array('name' => 'username', 'type' => 'query', 'method' => 'filterName', 'empty'=>true, 'allowEmpty'=>true),
array('name' => 'account_type', 'type' => 'value','empty'=>true, 'allowEmpty'=>true),
);
I had this kind of behavior as well from CakeDC/search and this two configs saved me, hope it will do for you as well.
It's a good idea to check the queries being executed as well using DebugKit.Toolbar.

CakePHP form not working

I have created a Controller, a model and a view for this. I want to make a form in CakePHP. But this is not working and till now I cannot understand the reason why is this happening...
My code for the controller is:
class MlistsController extends AppController {
public $helpers = array('Html','Form');
public function create() {
if ($this->request->is('post')) {
if ($this->Mlist->save($this->request->data)) {
$this->Session->setFlash(__('okay..'));
$this->redirect('action' => 'index');
}
}
}
}
My Model is:
App::uses('AuthComponent', 'Controller/Component');
class MList extends AppModel {
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
public $validate = array(
'listname' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A listname '
)
),
'replyto' => array(
'required' => array(
'rule' => array('notEmpty'),
'email' => 'email'
)
),
'fromName' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Your name'
)
),
'subject' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A subject '
)
),
'reminder' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A reminder '
)
),
'contactsfile' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'custom message'
)
));
}
And my view file create.ctp is:
<h2>Create new list</h2>
<?php
$this->Form->create('Mlist');
echo $this->Form->input('listname',array('label' => 'Your ListName:'));;
echo $this->Form->input('replyto',array('label' => 'Reply To email:'));
echo $this->Form->input('fromName',array('label' => 'From Name:'));
echo $this->Form->input('subject',array('label' => 'mail subject:'));
echo $this->Form->input('reminder',array('label' => 'Reminder'));
echo $this->Form->input('contactsfile',array('label' => 'Upload your file','type' => 'file'));
echo '<br />';
echo $this->Form->end('submit');
Finally, the Submit button of the form is not even green, but grey and does not function when I click it. Also the star symbol (*) is not showing apart the form labels where the fields are required...
Can you help me with this issue?
You're kind of bypassing Cake's 'Convention over configuration' paradigm.
In order for these conventions to work Cake uses the Inflector Class which handles the plural forms of English words.
So when you use an appropriate (to this convention) naming policy it will work for you "out of the box". Otherwise you will have to configure the Model, Controller and any Helpers/Components/Behaviours you're using. They all have configuration parameters for this, but there is not a big point in doing this static configuration with Cake since you will also have to go through it again if you rename a DB table for example.
I's just against the idea of Cake. If you need to do this just use some other configuration based framework.
I believe the problem is in your view. You also have to echo the starting of the form:
echo $this->Form->create('Mlist');
The naming convention is ok. Cake doesn't have any database of real english words, only few irregularities (see arrays in http://api.cakephp.org/2.3/source-class-Inflector.html) so anything like Mlist is just pluralized with adding "s" at the end.

custom config file not working with form validation

i've set the validation rules in application/config/validation_rules.php and it looks like this
(short version)
$config = array(
'member/register' => array(
'field' => 'language',
'label' => 'language',
'rules' => 'required|min_length[5]|max_length[12]'
),
array(
'field' => 'email',
'label' => 'email',
'rules' => 'required|valid_email'
),
array(
'field' => 'password',
'label' => 'password',
'rules' => 'required|min_length[8]'
),
array(
'field' => 'verify_password',
'label' => 'password',
'rules' => 'required|min_length[8]|matches[password]'
));
and i'm calling it like this:
$this->config->load('validation_rules');
$this->form_validation->set_rules($config);
if($this->form_validation->run('member/register') == FALSE)
{
$page = array(
'meta_title' => 'member registration',
'load_page' => 'front/register_view'
);
$this->load->view('front/template', $page);
}
not only is the validation_errors() function not showing anything but i'm also getting this error:
Message: Undefined variable: config
update: (here is my controller)
class register extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->library('form_validation');
}
function index()
{
$this->config->load('validation_rules', TRUE);
$this->form_validation->set_rules($this->config->item('config', 'validation_rules'));
if($this->form_validation->run('member/register') == FALSE)
{
//validation doesnt pass, load view
$page = array(
'meta_title' => 'member registration',
'load_page' => 'front/register_view'
);
$this->load->view('front/template', $page);
}
else
{
$register_data = array(
'language' => $this->input->post('language'),
'email' => $this->input->post('email'),
'password' => md5($this->input->post('password')),
'fname' => $this->input->post('fname'),
'lname' => $this->input->post('lname'),
'phone' => $this->input->post('phone'),
'address' => $this->input->post('address'),
'address2' => $this->input->post('address2'),
'city' => $this->input->post('city'),
'state' => $this->input->post('state'),
'zipcode' => $this->input->post('zipcode'),
'gfname' => $this->input->post('gfname'),
'glname' => $this->input->post('glname'),
'gphone' => $this->input->post('gphone')
);
$this->session->set_userdata($register_data);
}
}
function package()
{
$page = array(
'meta_title' => 'Register Package',
'load_page' => 'register_package_view'
);
$this->load->view('includes/template', $page);
}
}
I encountered same problem but I managed to fix it by using following configuration:
In my application/config/form_validation.php:
$config = array(
"register" => array(
array(
"field" => "username",
"label" => "Username",
"rules" => "required"
)
)
);
Auto-load the custom config file "form_validation.php" inside application/config/autoload.php:
$autoload['config'] = array('form_validation');
In my controller:
// manually set rules by taking $config["register"] from form_validation.php
$this->form_validation->set_rules($this->config->item("register"));
// call run() without parameter
if ($this->form_validation->run() == FALSE) {
$this->load->view("user/register_test");
} else {
echo "Form content is correct";
}
I've tried calling the validator using $this->form_validation->run("register"), without using $this->form_validation->set_rules() function, but I got no luck. Setting the rules manually by retrieving it from config array in form_validation.php make my day.
In case you are extending the form_validation library, you need to pass the $config array to the parent constructor:
class MY_Form_validation extends CI_Form_validation {
/**
* constuctoooor
*/
function MY_Form_validation($config){
parent::__construct($config);
}
http://ellislab.com/forums/viewthread/181937/
It's also cleaner using the method outlined in the docs: http://ellislab.com/codeigniter%20/user-guide/libraries/form_validation.html#savingtoconfig to avoid calling $this->form_validation->set_rules(...);
/**
* This is the POST target for the password reset form above
* #return null
*/
public function submit(){
// perform validation //
if($this->form_validation->run() == FALSE){
// display error on sign-up page //
$this->session->set_flashdata("system_validation_errors", validation_errors());
redirect('member/forgot/password');
}
// more awesome code
}
$this->config->load('validation_rules');
$this->form_validation->set_rules($config);
should be:
$this->config->load('validation_rules', TRUE);
$this->form_validation->set_rules($this->config->item('validation_rules', 'validation_rules'));
Per the documentation:
// Loads a config file named blog_settings.php and assigns it to an index named "blog_settings"
$this->config->load('blog_settings', TRUE);
// Retrieve a config item named site_name contained within the blog_settings array
$site_name = $this->config->item('site_name', 'blog_settings');
Your rules are wrong, you forgot to put the validation group in an array:
$config['validation_rules'] = array(
'member/register' => array(
array(
'field' => 'language',
'label' => 'language',
'rules' => 'required|min_length[5]|max_length[12]'
),
array(
'field' => 'email',
'label' => 'email',
'rules' => 'required|valid_email'
),
array(
'field' => 'password',
'label' => 'password',
'rules' => 'required|min_length[8]'
),
array(
'field' => 'verify_password',
'label' => 'password',
'rules' => 'required|min_length[8]|matches[password]'
)
)
);

Working with Fieldset class and ORM in FuelPHP

First : sorry for my long message.
I'm trying to learn Fuel, but I have some problems with Fieldset class and Orm.
I've create a Model which extends ORM, in order to get an automatic generated form, according to my database.
My Model
class Model_Product extends \Orm\Model
{
protected static $_table_name = 'products';
protected static $_properties = array(
'id' => array(
'data_type' => 'int'
),
'name' => array(
'data_type' => 'varchar',
'label' => 'Name',
'validation' => array(
'required', 'trim', 'max_length'=>array(30), 'min_length'=>array(3)
),
),
'description' => array(
'data_type' => 'varchar',
'label' => 'Description',
'validation' => array(
'max_length' => array(290)
),
'form' => array(
'type' => 'textarea'
),
),
'price' => array(
'data_type' => 'integer',
'label' => 'Price',
'validation' => array(
'required', 'trim', 'valid_string' => array('numeric','dots')
),
),
'pic' => array(
'data_type' => 'varchar',
'label' => 'Path to the pic',
'validation' => array(
'required', 'trim'
),
),
'registered' => array(
'data_type' => 'date',
'label' => 'Registration date',
'validation' => array(
'required', 'trim'
) //'valid_string' => array('numeric','dashes')
),
);
} //end of class Model_Product
Then I create the controller which will validate the form.
My function from the controller
function action_add()
{
$fieldset = Fieldset::forge('add_product')->add_model('Model_Product')->repopulate();
$form = $fieldset->form();
$form->add('submit', '', array('type' => 'button', 'value' => 'Add item', 'class' => 'button-link' ));
$validation = $fieldset->Validation();
if($validation->run() === true)
{
$fields = $fieldset->validated();
//create a new Product, with validated fields
$product = new Model_Product;
$product->name = $fields['name'];
$product->description = $fields['description'];
$product->price = $fields['price'];
$product->pic = $fields['pic'];
$product->registered = $fields['registered'];
try
{
//if the product is successfully inserted in the database
if($product->save())
{
Session::set_flash('success', 'Product successfully added !');
\Response::redirect('products/product_details/'.$product->id);
}
}
catch(Exception $e)
{
Session::set_flash('error', 'Unable to save the product into the database !'.$e->getMessage());
}
}
//If the validation doesn't pass
else
{
Session::set_flash('error', $fieldset->show_errors());
}
$this->template->set('content', $form->build(), false);
} // end of method add()
My first question :
How and where in my function from controller can i add a 'fieldset' tag with a specific class, in order to 'beautify' my auto-generated form ?
Let's say
<fieldset class="add_product">
Second question :
What do I have to do in order to correctly validate de 'price' field, because in MySQL is set as decimal(5,2), but when I'm trying to validate with my actual validation rule, it doesn't pass (it works only with integer values Ex.: 42, but not with decimal Ex.: 42.35). I have tried to change the type from 'integer' to 'double', but it doesn't work .
If you can point to some specific documentation regarding my problems, which I possible didn't read yet, please do feel free.
Gabriel
I can answer the first question To change the automatically generated form you will need to copy fuel/core/config/form.php to the fuel/app/config directory and edit this file to suit your needs.

Categories