I'm using the CakePHP SimplePasswordHasher to hash my customer password. Is it possible to retrieve the un hashed password in the edit view? At the moment my edit view shows the hashed password. I want it to show the original password because if the hashed password is shown in the edit and the user submits the form the hash hashes that hash value and the password changes. My code is as follows:
edit.ctp
<div class="customers form">
<?php echo $this->Form->create('Customer'); ?>
<fieldset>
<legend><?php echo __('Edit Customer Details'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('customer_name', array('required'=>false));
echo $this->Form->input('customer_address');
echo $this->Form->input('customer_suburb');
echo $this->Form->input('customer_state', array('options' => array('SA' => 'SA', 'VIC' => 'VIC','ACT' => 'ACT', 'NSW' => 'NSW', 'NT'=> 'NT', 'QLD'=>'QLD','TAS'=> 'TAS','WA'=>'WA','empty'=>'(choose one)')));
echo $this->Form->input('customer_postcode', array('required'=>false));
echo $this->Form->input('customer_dob',array('required'=>false,'id'=>'datepicker','type'=>'text'));
echo $this->Form->input('customer_anniversary',array('required'=>false,'id'=>'datepicker2','type'=>'text'));
echo $this->Form->input('customer_phone1', array('required'=>false));
echo $this->Form->input('customer_phone2', array('required'=>false));
echo $this->Form->input('customer_phone3', array('required'=>false));
echo $this->Form->input('customer_fax', array('required'=>false));
echo $this->Form->input('customer_email', array('required'=>false));
echo $this->Form->input('customer_gender', array('required'=>false,'options' => array('M' => 'M', 'F' => 'F','empty'=>'(choose one)')));
echo $this->Form->input('customer_type', array('required'=>false,'options' => array('Gold' => 'Gold', 'Silver' => 'Silver','Bronze'=> 'Bronze','empty'=>'(choose one)')));
echo $this->Form->input('customer_username', array('required'=>false));
echo $this->Form->input('customer_PW', array('required'=> false));
echo $this->Form->input('companies_id', array('label' =>'Company Name','options'=>$companies, 'label'=>'Company Name','required'=>false));
echo $this->Form->input('employees_id', array('label' =>'Employee name','options'=>$employees, 'label'=>'Employee name','required'=>false));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
customersController:
class CustomersController extends AppController {
//some code
public function edit($id = null) {
if (!$this->Customer->exists($id)) {
throw new NotFoundException(__('Invalid customer'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->Customer->save($this->request->data)) {
$this->Session->setFlash(__('The customer has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The customer could not be saved. Please, try again.'));
}
} else {
$options = array('conditions' => array('Customer.' . $this->Customer->primaryKey => $id));
$this->request->data = $this->Customer->find('first', $options);
}
//$companies = $this->Customer->Companies->find('list');
$companies= $this->Customer->Companies->find('list',array('order'=>'company_name ASC','fields'=>array('id','company_name')));
$employees= $this->Customer->Employees->find('list',array('order'=>'employee_name ASC','fields'=>array('id','employee_name')));
$this->set(compact('companies'));
$this->set(compact('employees'));
}
//some code
}
Can some one please help?
SimplePassword Hasher uses the md5 encryption.
md5 is supposed to be a one way encryption. The reason you use it, is so only the user knows their password, but you can still validate the password.
How you validate it is to create an md5 hash of the password supplied by the user, and compare that with the md5 hash of the password in the database.
The whole idea behind a one way encryption is to generate a hashed value that cannot be decrypted to reveal the original string.
That's the reason that when dealing with lost passwords administrators typically reset it to a new value.
I think you just have to empty the password field while editing in edit.ctp like
echo $this->Form->input('customer_PW', array('value'=> ''));
Do you really want the password to be on the form for the user to edit?
You might want to just clear the password fields so your users can edit and save the rest of profile without bothering with the password. If they post the form, and the password field has been filled out, you know that they have entered a new password which should be hashed and saved. If the password field is blank, then make sure you delete the password field from the array before you save the Model from the Controller.
If you use jquery, it is simple to make sure the password field is empty.
$(document).ready(function() {
$('#CustomerPW').val('');
});
Related
I have been trying for days now using the form class to populate the text fields from my database. I have also been searching to find out how to do it without any luck.
Please could somebody take a look at my code and tell me what I'm doing wrong.
Model
//This function brings up the selected users information for editing.
public function edit_user($id)
{
$this->db->select('id, email, name, lastname, homeaddress, posteladdress,
mobile, hometel, idnum');
$this->db->where('id', $id)->limit(1);
$query = $this->db->get('user');
return $query->result();
}
Controller
public function get_user_edit($id)
{
$this->load->helper('form');
$this->load->model('model_users'); //Load the user model
//Get the database results from the model
$data['results'] = $this->model_users->edit_user($id);
foreach ($data['results'] as $key => $row)
{
$data['results'] = array( 'id' => $row->id,
'email' => $row->email,
'name' => $row->name,
'lastname' => $row->lastname,
'homeaddress' => $row->homeaddress,
'posteladdress' => $row->posteladdress,
'mobile' => $row->mobile,
'hometel' => $row->hometel,
'idnum' => $row->idnum);
}
$this->load->view('edit_user', $data);
}
View
<div id="body">
<p>Edit user information.</p>
<?php
echo form_open('user_admin/user_update', $results);
echo validation_errors();
echo "<p><lable>Email:</lable>";
echo form_input('email', set_value('email'));
echo "</p>";
echo "<p><lable>Name:</lable>";
echo form_input('name', set_value('name'));
echo "</p>";
echo "<p>";
echo form_submit('edit_submit', 'Update');
echo "</p>";
echo form_close();
?>
I keep getting this error
A PHP Error was encountered
Severity: 4096
Message: Object of class stdClass could not be converted to string
Filename: helpers/form_helper.php
Line Number: 1010
First thing. You're expecting a single row to be returned from the database, right? But you're looping through the result in your controller. Instead of doing that in your model:
return $query->result();
do this:
return $query->row();
and remove the foreach loop from your controller (it even has an unused $key var in there). You'll end up having cleaner and shorter code. Only if you're getting a single row, which seems to be the case.
Moving on.
Have you read the documentation here: https://ellislab.com/codeigniter/user-guide/helpers/form_helper.html ?
form_open('user_admin/user_update', $results); - what are you trying to do here?
You use the second parameter to pass attributes to the opening tag. Now looking at your code, your $results array has values for each field. Doesn't make much sense to push all this into the form opening tag, does it?
Field rendering with the correct values.
This is an example from the documentation how to configure and render an input field:
$data = array(
'name' => 'username',
'id' => 'username',
'value' => 'johndoe',
'maxlength' => '100',
'size' => '50',
'style' => 'width:50%',
);
echo form_input($data);
So, your email input should be formatted having the minimal config like that:
$data = array(
'name' => 'email',
'value' => $results['email']
);
echo form_input('email', $data);
On validation (in your user_update() method in user_admin controller), you'll have to do some logic to capture the value you're validating. So you'll need something like:
$results['email'] = set_value('email');
Hope that makes sense!
Thank you very much for your help. I'm sure you must have realised that I'm new to Codeigniter, but with your help I was able to sort out the problem that I had.
I changed the query to return only the one result that it found like you suggested
return $query->row();
and you were right I didn't need the foreach loop to populate an array to pass to the view.
Thanks for pointing out that I was trying to pass the results from db as the attribute for the form.:)
I added my code below for anybody that come across my question with the same problem. Maybe it will help them.
My controller
public function get_user_edit($id)
{
$this->load->model('model_users'); //Load the user model
//Get the database results from the model
$data['results'] = $this->model_users->edit_user($id);
$this->load->view('edit_user', $data);
}
My model
//This fetches the selected users information for editing.
public function edit_user($id)
{
$this->db->select('id, email, name, lastname, homeaddress, posteladdress,
mobile, hometel, idnum');
$this->db->where('id', $id)->limit(1);
$query = $this->db->get('user');
return $query->row();
}
My view
<div id="container">
<h1>Edit user</h1>
<div id="body">
<p>Edit user information.</p>
<?php
echo form_open('user_admin/user_update');
echo validation_errors();
echo form_hidden('id', $results->id);
echo "<p><lable>Email:</lable>";
echo form_input('email', $results->email);
echo "</p>";
echo "<p><lable>Name:</lable>";
echo form_input('name', $results->name);
echo "</p>";
echo "<p><lable>Last name:</lable>";
echo form_input('lastname', $results->lastname);
echo "</p>";
echo "<p><lable>Home address:</lable>";
echo form_input('homeaddress', $results->homeaddress);
echo "</p>";
echo "<p><lable>Postal address:</lable>";
echo form_input('posteladdress', $results->posteladdress);
echo "</p>";
echo "<p><lable>Mobile number:</lable>";
echo form_input('mobile', $results->mobile);
echo "</p>";
echo "<p><lable>Home telephone:</lable>";
echo form_input('hometel', $results->hometel);
echo "</p>";
echo "<p><lable>ID number:</lable>";
echo form_input('idnum', $results->idnum);
echo "</p>";
echo "<p>";
echo form_submit('edit_submit', 'Update');
echo "</p>";
echo form_close();
?>
</div>
I have an add() view for Lessons - in it I have a form:
<?php echo $this->Form->create('Lesson'); ?>
<fieldset>
<legend><?php echo __('Add Lesson'); ?></legend>
<?php
echo $this->Form->input('name');
echo $this->Form->input('course_id', array('selected' => $this->request->data['named']['belongsToCourse']));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
It seems that when I set $this->request->data['named']['belongsToCourse'] in the controller, it somehow made it so that I am not saving the $this->Form->input('name');
How do I set the course_id without breaking the $this->request->data which should include the new lesson's name?
Here's the error I get when trying to save. Because it thinks I'm saving a duplicate name '':
Error: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'name'
Here is the action add():
public function add() {
$this->request->data = $this->request->params;
if ($this->request->is('post')) {
$courseID = $this->request->data['named']['belongsToCourse'];
$this->Lesson->create();
if ($this->Lesson->save($this->request->data)) {
$this->Session->setFlash(__('The lesson has been saved.'));
return $this->redirect(array('controller' => 'courses', 'action' => 'view', $courseID));
} else {
$this->Session->setFlash(__('The lesson could not be saved. Please, try again.'));
}
}
//debug(func_get_args());
$courses = $this->Lesson->Course->find('list');
$this->set(compact('courses'));
//$this->Form->input('course_id') = $belongsToCourse;
}
I have to 2 models that are related ItQuery and ItQueryComment. When a user adds a ItQuery other users should be able to comment on it. What i am trying to achieve is when other users add comments on a query they should be redirect to the view of the query not the index page for the it_query_comments
here is my code for my comments add view
<?php echo $this->Form->create('ItQueryComment'); ?>
<fieldset>
<legend><?php echo __('Add It Query Comment'); ?></legend>
<?php
echo $this->Form->input('it_query_id');
echo $this->Form->input('comment');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
and here is my add function in the controller
public function add() {
if ($this->request->is('post')) {
$this->ItQueryComment->create();
if ($this->ItQueryComment->save($this->request->data)) {
$this->Session->setFlash(__('The it query comment has been saved'));
$this->redirect(array('controller' => 'it_queries','action' => 'view', $itQuery['ItQuery']['id']));
} else {
$this->Session->setFlash(__('The it query comment could not be saved. Please, try again.'));
}
}
$itQueries = $this->ItQueryComment->ItQuery->find('list');
$this->set(compact('itQueries'));
}
If anyone could show me how to do this, that would be awesome. Thanks in advance
try the following
$this->redirect(array(
'controller' => 'it_queries',
'action' => 'view',
$this->request->data['ItQuery']['id'])
);
I've searched high and low for a solution but can't seem to get this figured out. What I'm trying to do is upon adding a product, I want the name field to be populated from the inputs in the form. So the name would include the values the user selects for type_id,category_id and subcategory_id. Does anyone know of a way to accomplish this?
Add product View page
<fieldset>
<legend><?php echo __('Add Product'); ?></legend>
<?php
echo $this->Form->input('type_id');
echo $this->Form->input('category_id', array('label' => 'Vendor'));
echo $this->Form->input('subcategory_id', array('label' => 'Model'));
echo $this->Form->input('location', array('label' => 'Location'));
echo $this->Form->input('sku', array('label' => 'Asset Tag'));
echo $this->Form->input('mac');
echo $this->Form->input('description', array('label' => 'Notes'));
echo $this->Form->input('name', array( 'value' => ['type_id']['category_id'] , 'type' => 'hidden'));
//echo $this->Form->input('cost');
// echo $this->Form->input('Tag');
?>
</fieldset>
Product controller add function
public function add() {
if ($this->request->is('post')) {
$this->Product->create();
if ($this->Product->save($this->request->data)) {
$this->Session->setFlash(__('The product has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The product could not be saved. Please, try again.'));
}
}
$subcategories = $this->Product->Subcategory->find('list',array('order'=>'Subcategory.name asc'));
$categories = $this->Product->Category->find('list',array('order'=>'Category.name asc'));
$types = $this->Product->Type->find('list',array('order'=>'Type.name asc'));
$this->set(compact('subcategories', 'categories', 'types'));
}
In order to do it the way you are trying to do it, you would have to use client-side javascript to update the input value "on-the-fly", but that's not very safe and can easily be messed with. It would make much more sense to drop the name input altogether and just handle this in the beforeSave method of your Product model (or alternatively by defining the name value in your Controller just before saving).
public function beforeSave($options = array()) {
// Generate the name based on type and category
$this->data['Product']['name'] = $this->data['Product']['type_id'] .
$this->data['Product']['category_id'];
return true;
}
Update based on your comment.
In order to get the names, just find those names (assuming your models are associated) and define those:
public function beforeSave($options = array()) {
// Get the type name
$type = $this->Type->field('name', array(
// Set the condition for the field
'Type.id' => $this->data['Product']['type_id']
));
// Get the category name
$category = $this->Category->field('name', array(
// Set the condition for the field
'Category.id' => $this->data['Product']['category_id']
));
// Generate the name based on type and category
$this->data['Product']['name'] = $type . $category;
return true;
}
trying to edit multiple models
The Controller
function edit($id = null) {
if (!empty($this->data)) {
$this->Qnote->save($this->data);
if ($this->Qnote->save($this->data)) {
$this->data['Step']['qnote_id'] = $this->Qnote->id;
$this->Step->save($this->data);
$this->Session->setFlash(__('The qnote has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The qnote could not be saved. Please, try again.', true));
}
}
The Form
<?php echo $this->Form->create();?>
<fieldset>
<legend><?php __('Edit Qnote'); ?></legend>
<?php
echo $this->Form->hidden('Qnote.id');
echo $this->Form->input('Qnote.subject');
echo $this->Form->input('Qnote.body');
echo $this->Form->hidden('Step.0.id');
echo $this->Form->Hidden('Step.qnote_id');
echo $this->Form->Hidden('Step.user_id');
echo $this->Form->input('Step.0.body');
?>
<?php echo $this->Form->end(__('Submit', true));?>
I am trying to edit and update information in associated models , Qnotes and Step
The information show up in the form. however when i submit the form. the
the Qnote information is saving with out any problem . however the step information is not updating
The models are associated. with Steps belong to Qnote, QNote has Many Steps
Your form include '0' for all the Step inputs.
echo $this->Form->hidden('Qnote.id');
echo $this->Form->input('Qnote.subject');
echo $this->Form->input('Qnote.body');
echo $this->Form->hidden('Step.0.id');
echo $this->Form->Hidden('Step.0.qnote_id');
echo $this->Form->Hidden('Step.0.user_id');
echo $this->Form->input('Step.0.body');
And in your controller action, you need to call saveAll() instead.
if ($this->Qnote->saveAll($this->data)) {
...
Try this to load different model. :)
var $uses = array('Qnote', 'Step', 'modelName');
If you want to save data in mutiple model you have to call the model in controller. Using
$this->loadModel('Step');
then do the save part like below. You have called save function for an object twice.
function edit($id = null) {
if (!empty($this->data)) {
$save = $this->Qnote->save($this->data);
if ($save) {
$this->data['Step']['qnote_id'] = $this->Qnote->id;
$this->Step->save($this->data);
$this->Session->setFlash(__('The qnote has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The qnote could not be saved. Please, try again.', true));
}
}
If the models are associated, you can save the whole thing at once (in all the models concerned) just by using the saveAll() function.