codeigniter query builder will update db with just about anything - php

I'm new to codeigniter and trying to get my mind around the query builder functionality. I currently have an update method where I pass user entered data to update a record in the db. I've noticed it seems to be successful no matter what kind of junk data I throw at it, and I'm wondering if there's a setting or something I need to change, or what.
As you can see below, in my model I'm bypassing the user entered value and putting in junk data and it is still successful. It just inserts 0000-00-00. DOB in the DB is a date datatype.
I always get a success result from this, and it updates the DB, so techically it was successful. I have controls in place to prevent junk data from ever being sent to the model, but it doesn't give me warm fuzzies knowing that it is behaving this way.
Controller:
$updateResult = $this->Patients_model->update_patient_profile($this->data['post_data']);
if($updateResult === true)
{
$this->data['patient_profile'] = $this->Patients_model->get_patient_profile($patientId);
$this->data['update_result'] = true;
$this->load->view('index', $this->data);
}
else
{
$this->data['update_result'] = false;
print_r($updateResult);
}
Model:
function update_patient_profile($data)
{
$patient_id = $data['patient_id'];
unset($data['patient_id']);
$data['dob'] = 'this is not even a date'; //will store 0000-00-00 in DB.
$this->db->where('patient_id', $patient_id);
$this->db->update($this->patientsTable, $data);
if($this->db->affected_rows()) {
return true;
}
else
{
return $this->db->error();
}
}

You can check with PHP and thorw an error for invalid date. try this:
function update_patient_profile($data)
{
$patient_id = $data['patient_id'];
unset($data['patient_id']);
$check_date = $data['dob'];
if(strtotime($check_date))
{
$data['dob'] = date("Y-m-d",strtotime($check_date)); // to confirm date is valid and equivalant to database format
}
else
{
throw new Exception("Invalid date", 1);
}
$data['dob'] = 'this is not even a date'; //will store 0000-00-00 in DB.
$this->db->where('patient_id', $patient_id);
$this->db->update($this->patientsTable, $data);
if($this->db->affected_rows()) {
return true;
}
else
{
return $this->db->error();
}
}

Related

MySQL database and importing dates problems

Okay,so in my mysql database I use a date field. Using PHP I check if the user is 18 years of age or not. Then I try to enter all the form information to my MySQL database to make a user. I keep getting a blank screen (besides my navbar and footer) The user is not being saved into the database, and the error log shows this error: PHP Recoverable fatal error: Object of class DateTime could not be converted to string in ....
$age = checkAge($_POST["birthday"]);
if($age != false)
{
$ageSuc = "All Good!";
}
else ....
function checkAge ($data)
{
$dateObj = new DateTime($data);
$ageLimit = new DateTime('-18 years');
if ($dateObj > $ageLimit)
{
return false;
}
else
{
$dateObj->format('Y-m-d');
return $dateObj;
}
}
So the question is, do I need to convert the dateTime Obj into a string before MySQL will accept it? The field is set to hold 'dates' so I thought the date obj would be the same thing? How does one change it to a string.
You are returning the DateTime object, because the format function returns a string, it doesn't change the object. Try returning the result of the format function which is the formatted string.
return $dateObj->format('Y-m-d');
$age = checkAge($_POST["birthday"]);
if($age != false)
{
$ageSuc = "All Good!";
}
else ....
function checkAge ($data)
{
$dateObj = new DateTime($data);
$ageLimit = new DateTime('-18 years');
if ($dateObj > $ageLimit)
{
return false;
}
else
{
return $dateObj->format('Y-m-d');
}
}
If you want a string result, you have to return the format() result, not the object itself.
But the error you have specified is not triggered directly in this code, but somewhere in the else, where you try to convert the result to string.

Codeigniter how to use transactions

I have read up on some stuff about transactions in Codeigniter. I have implemented them in my code and was wondering if someone could take a look and see if I am going in the right direction? So far I have not encountered any database issues but I want to make sure I have implemented transactions correctly.
In my code, I create the user details first and get the ID, then I insert that ID into the user accounts table.
Controller
if($this->form_validation->run()==false){
$this->index();
}else{
$password = md5($password);
$package = array(
'first_name'=>$first_name,
'last_name'=>$last_name,
'email'=>$email,
'client_id'=>$client_id,
'date_of_birth'=>$date_of_birth,
'phone_number'=>$phone_number,
'address'=>$address,
'country'=>$country,
'created_on'=>$this->get_date(),
'updated_on'=>$this->get_date()
);
if($this->AccountModel->user_account_exists($email)){
$this->session->set_flashdata('Error',"Account already exists");
redirect('/Register');
}else{
$this->db->trans_start();
$id = $this->AccountModel->create_person($package);
$error = $this->db->error();
$this->db->trans_complete();
$expiration_date = date('Y-m-d', strtotime($this->get_date() . "+1 month") );
if($this->db->trans_status()===false){
$this->index();
}else{
$account = array(
'username'=>$email,
'password'=>$password,
'user_type'=>'user',
'person_id'=>$id,
'is_active'=>true,
'created_on'=>$this->get_date(),
'updated_on'=>$this->get_date(),
'expires_on'=>$expiration_date,
'status'=>'active'
);
$this->db->trans_start();
$id = $this->AccountModel->create_user_account($account);
$error = $this->db->error();
$this->db->trans_complete();
if($this->db->trans_status()===false){
$this->index();
}else{
$this->session->set_flashdata('Success','Account has been created');
redirect('/Login');
}
}
}
if($error!=''){
$this->session->set_flashdata('Error',$error["message"]);
redirect('/Register');
}
}
Model
public function create_user_account($input){
$this->db->insert('user_accounts',$input);
return $this->db->insert_id();
}
public function create_person($input){
$this->db->insert('person',$input);
return $this->db->insert_id();
}
Hope someone can help me with this
The reason for transactions is to perform multiple db query operations and if any operations fail undo any that have already taken place.
You are only performing one operation within your transaction block so transactions are pointless. Other than that, you've got the idea.
In your case where you are only using db->insert() you can easily check the results and respond accordingly. db->insert() returns either true or false. If the return is false, get the error and set it into flashdata. Otherwise, go on with your work.
As #Topjka say, transactions should be in the model code.
Here's a sample model
class Some_model extends CI_Model
{
public function save_stuff($data)
{
//let's assume $data has values for two different tables
$newInfo = $data['newStuff'];
$updateInfo = $data['oldStuff'];
$this->db->trans_start();
$this->db->insert('other_table', $newInfo);
$this->db->update('one_table', $updateInfo);
$this->db->trans_complete();
if($this->db->trans_status() === FALSE)
{
$this->set_flash_error();
return FALSE;
}
return TRUE; //everything worked
}
public function set_flash_error()
{
$error = $this->db->error();
$this->session->set_flashdata('Error', $error["message"]);
}
}
Transactions are justified above because we do two db ops and if the either fails we don't want any changes to the db made.
Using the model/method in the controller
if($this->some_model->save_stuff($the_stuff) === FALSE)
{
redirect('/wherever');
}
//All OK, proceed
//do other controller things

How to check the given values are updated are not into Database in php

I'm doing webservice using laravel,Here I need to send response after the value get updated into database...
I tried something like this,
public function getPhoneverify(){
$_REQUEST['user_id'] = str_replace('"','', $_REQUEST['user_id']);
$_REQUEST['status'] = str_replace('"','', $_REQUEST['status']);
$user = \DB::table('tb_users')->where('id', $_REQUEST['user_id'] )->update(array('phone_verified' => $_REQUEST['status']));
if($user)
{
echo "success";exit;
}
else
{
echo "failed";exit;
}
}
But here,always it shows the else part message,even if the value get updated into the database..
How should I do this..
Is there any other option to do this!!..
Someone help me..
If you need to check if the query was successful, I'd suggest a different approach. Assuming the user_id field is unique, following should work:
$user = \DB::table('tb_users')->where('id', $_REQUEST['user_id'] )->first();
Or you can also retrieve the user like this:
$user = \DB::table('tb_users')->find($_REQUEST['user_id']);
And then update/save it:
$user->fill(array('phone_verified' => $_REQUEST['status']));
$saved = $user->save(); //this will always return true or false.
if($saved)
{
echo "success";exit;
}
else
{
echo "failed";exit;
}
You can use exception handling if you want
try {
$user = \DB::table('tb_users')->where('id', $_REQUEST['user_id'] )->update(array('phone_verified' => $_REQUEST['status']));
}catch(\Exception $e){
//write statements here if query fails
}
By the way as far I know DB::update() returns boolean
The return value will never be true since it returns the number of rows affected by the database transaction.
So you should check for the integer value, not if it is true or false

Check or Add to DB quickly

I'm using apache, php, mysql and code igniter and I have a database set up. In the database I have two columns that both need to be unique in combo: latitude and longitude.
So I set up the database using this call:
alter table pano_raw add unique index(lat, lng)
Now when I insert values into the two columns (lat and lng) if the value is the same, the database should reject the write correct?
function addNewSet($data)
{
$this->db->insert('sets', $data);
}
This function should return a true or false, depending on the success of the read or write correct?
So now how so I alter it so that when it will return the row_id of the inserted record or return FALSE? If the write worked, I need the row_id, if it didn't I need FALSE so I can alter the code that called this function.
Would this work? I don't think so. Ideas?
function addNewSet($data)
{
$this->db->insert('sets', $data);
return $this->db->insert_id();
}
By default it wont return false, it will have a database error before returning false.
If you really want this, you need to go to application/config/database.php and change set this to false $db['default']['db_debug'] = FALSE;
Then you should be able to do this (assuming your table has an id field set to auto increment)
function addNewSet($data) {
if ($this->db->insert('sets', $data)) {
return $this->db->insert_id();
} else {
return FALSE;
}
}
Try this:
function addNewSet($data)
{
$result = $this->db->insert('sets', $data);
if ( $result )
return $this->db->insert_id();
return false;
}
You can use $this->db->affected_rows(); after inserting the data to check if any record was added (or affected).
So
function addNewSet($data)
{
$this->db->insert('sets', $data);
if($this->db->affected_rows()==1)
{
return $this->db->insert_id();
}
else
{
return false; // nothing was added!
}
}
Should do it (untested).

CodeIgniter - checking data and receiving 'Trying to get property of non-object'

Im trying to test a pin number in the database compared to one entered by a user, whenever i run it i get a 'Trying to get property on non-object' error ... I cant seem to spot where im going wrong, could someone please help me out ... Its saying the error is on the $thepin = $pins->pin; line
The code i have in my controller is as follows:
function check_pin()
{
$pin = md5($this->input->post('oldpin'));
$email = $this->input->post('email');
$existingpin = $this->users->get_pin_by_email($email);
foreach($existingpin as $pins){
$thepin = $pins->pin;
}
if($pin != $thepin){
$this->form_validation->set_message('check_pin', 'The Old Pin Number does not match the existing one');
return FALSE;
} else {
return TRUE;
}
}
and the following is the code in my model
function get_pin_by_email($emailaddress)
{
$this->db->where('LOWER(email)=', strtolower($emailaddress));
$query = $this->db->get($this->table_name);
if ($query->num_rows() == 1) return $query->row();
return NULL;
}
The Controller code should be:-
function check_pin()
{
$pin = md5($this->input->post('oldpin'));
$email = $this->input->post('email');
$existingpin = $this->users->get_pin_by_email($email);
foreach($existingpin as $pins){
// Check for the NULL return
if ($pins != NULL && is_object($pins)) {
$thepin = $pins->pin;
}
}
if($pin != $thepin){
$this->form_validation->set_message('check_pin', 'The Old Pin Number does not match the existing one');
return FALSE;
} else {
return TRUE;
}
}
If you look closely in the model code, you will find that you are returning two data types - one is Object & another is NULL. So in your controller code, you should also check that accordingly.
Hope it helps.

Categories