I'm building an android app that uses Phil Sturgeon's RESTful Server for CodeIgniter as a RESTful API.
When the android app makes a POST request to register a user with facebook oauth data the method below is called when it reaches server side. It works, but if one or more of the optional params is empty it will insert a 0 into my database.
How do I prevent this? I'd much prefer it enters nothing at all or null.
function fb_register_post(){
if($this->get_request_method() != "POST"){
$this->response('',406);
}
$oauth_email = $this->input->post('OAUTH_EMAIL');
$oauth_uid = $this->input->post('OAUTH_UID');
$oauth_provider = $this->input->post('OAUTH_PROVIDER');
$first_name = $this->input->post('FIRST_NAME');
$last_name = $this->input->post('LAST_NAME');
if(!empty($oauth_provider) and !empty($oauth_uid) and !empty($oauth_email) and !empty($first_name) and !empty($last_name)){
if(filter_var($oauth_email, FILTER_VALIDATE_EMAIL)){
$new_member_insert_data = array(
'first_name' => $first_name,
'last_name' => $last_name,
'email' => $oauth_email,
'OAUTH_EMAIL' => $oauth_email,
'OAUTH_PROVIDER' => $oauth_provider,
'OAUTH_UID' => $oauth_uid,
//OPTIONAL DATA
'gender' => $this->post('GENDER'),
'hometown' => $this->post('HOMETOWN'),
'bio' => $this->post('BIO'),
'birthday' => $this->post('BIRTHDAY')
);
$this->load->model('membership_model');
$data['user'] = $register = $this->membership_model->oauth_register($new_member_insert_data);
$this->response($data, 200);
}
}else{
$message = array('message' => 'FAIL');
$this->response($message, 201);
}
$message = array('message' => 'FAIL!');
$this->response($message, 200); // 200 being the HTTP response code
}
The model function being called is :
function oauth_register($new_member_insert_data)
{
$insert = $this->db->insert('users', $new_member_insert_data);
if($insert){
$UID = $new_member_insert_data['OAUTH_UID'];
$q = $this->db->query("SELECT * FROM users WHERE OAUTH_UID = $UID LIMIT 1 ") or die(mysql_error());
if($q->num_rows() > 0)
{
foreach($q->result() as $row)
{
$data[] = $row;
}
return $data;
}
}
else
{
return false;
}
}
The issue is your post parameters is passing an empty string '' for the value (at least that's what the $_POST array will see it as). Then you try to insert this into an numeric column and Mysql magically is casting it to 0 -- even if you've got another default value set.
The best thing you can do is check the parameters for being empty before adding them to the $new_member_insert_data array any values that are numeric (assuming this array is used to construct the insert statement). Below is an explicit example of not setting array members that have empty values:
//assuming all non-optional details have values
$new_member_insert_data = array(
'first_name' => $first_name,
'last_name' => $last_name,
'email' => $oauth_email,
'OAUTH_EMAIL' => $oauth_email,
'OAUTH_PROVIDER' => $oauth_provider,
'OAUTH_UID' => $oauth_uid
) ;
//OPTIONAL DATA
$gender = $this->post('GENDER')? $this->post('GENDER'):null;
if(!empty($gender)){
$new_member_insert_data['gender'] = $gender;
}
$hometown = $this->post('HOMETOWN')? $this->post('HOMETOWN'):null;
if(!empty($hometown)){
$new_member_insert_data['hometown'] = $hometown;
}
...etc...
You can also prevent this on the client request side by not putting any thing without an value into your post parameters, but I always protect against this on the webservice side, not just the client POST request side.
You'll also see this happen with dates and timestamps... when you try to set them to '' tehy end up like 0000-00-00 00:00:00.
You can turn on a strict mode in Mysql that will cause inserts fail when you try to stuff an empty string into a numeric field or other non-character field (I highly recommend against this though).
Related
Is there a way with MySQL to specify "use previous / inherit / no change / existing value"?
Rather than needing to pull the current data from the database and use it, or have a customized database function excluding editing those columns.
if(x > y) {
$role_id = 3;
} else {
$role_id = '#no-change'; // Is there a way to do this? (not proper SQL syntax)
}
$update_user = $this->db->update('users',
array(
'first_name' => filterName($post['first_name']),
'last_name' => filterName($post['last_name']),
'email' => filterEmail($post['email']),
'role_id' => $role_id,
), $user_id_to_edit, 'user_id');
In a case like this where the db function is using prepared statements (not shown) I can't use the column name as to reflect the current value.
Is there such a MySQL function / variable that will essentially "ignore" updating that column? (just leave the existing value)
UPDATE: Here's the Update function:
public function update($table, $data, $where_id, $column = 'user_id') {
// Check for $table or $data not set
if (( empty( $table ) || empty( $data )) || empty($data) ) {
return false;
}
// Initiate variable to append to
$placeholders ='';
// Parse data for column and placeholder names
foreach ($data as $key => $value) {
$placeholders .= sprintf('%s=:%s,', $key, $key);
}
// Trim excess commas
$placeholders = rtrim($placeholders, ',');
// Append where ID to $data
$data['where_id'] = $where_id;
// Prepary our query for binding
$stmt = $this->db->prepare("UPDATE {$table} SET {$placeholders} WHERE $column = :where_id");
// Execute the query
$stmt->execute($data);
// Check for successful insertion
if ( $stmt->rowCount() ) {
return true;
}
return false;
}
You could try this:
$data = array(
'first_name' => filterName($post['first_name']),
'last_name' => filterName($post['last_name']),
'email' => filterEmail($post['email']))
if(x > y) {
$data['role_id'] = 3;
}
$update_user = $this->db->update('users', $data, $user_id_to_edit, 'user_id');
That way, you can customize $data before hand if you like.
I should also mention, if you're concerned about redundancy, you can put your data sanitation inside a function. Something along the lines of:
function sanitize($data) {
if(x > y) {
$data['role_id'] = 3;
} else {
if(isset($data['role_id']) {
unset($data['role_id']);
}
}
return $data;
}
$data = array(
'first_name' => filterName($post['first_name']),
'last_name' => filterName($post['last_name']),
'email' => filterEmail($post['email']))
$update_user = $this->db->update('users', sanitize($data), $user_id_to_edit, 'user_id');
Edit: Something I should mention is that, if we're talking pure SQL, all you need to do is omit those columns from the query, so:
UPDATE table SET Col1=val1, Col2=val2, Col3=val3 WHERE id=val
But if for some reason you don't want to update Col3, just remove it from the query:
UPDATE table SET Col1=val1, Col2=val2 WHERE id=val
Since you have a function that just adds whatever you give it, you just need to sanitize the data ahead of time. That's probably the best way to do it.
Hi all am trying to insert array of data to database using api in laravel .my task is i need to insert data from postman using some paramters(inputs)
when i run url the data is not inserting into database .
getting output status::true. am not getting any errors .how to solve this to insert data?
below is my code:
public function addToCart(){
$input = Input::all();
$data['status'] = 0;
$data['error'] = true;
// print_r($input);
$carty=array($input['cart']);
if(isset($input['user_id']) && isset($carty)> 0 ){
foreach($carty as $key => $val){
if(!empty($val['quantity']) && !empty($val['price']) && !empty($val['sku']) && !empty($val['qrcode']) && !empty($val['product_id']))
{
echo "here";
$totalPrice = $val['quantity']* $val['price'];
$cartId = [];
$cartId[] = DB::table('jocom_cart')->insertGetId(array(
'user_id' => $input['user_id'],
'product_id' => $val['product_id'],
'sku' => $val['sku'],
'quantity' => $val['quantity'],
'price' => $val['price'],
'total_price' => $totalPrice,
'qrcode' => $val['qrcode']
));
}
}
}
else{
$data['message'] = 'All field are required.';
}
return Response::json($data);
}
I saw some syntax errors in your posted code
$input = Input::all()
Must be (; missing)
$input = Input::all();
and
DB::table('jocom_cart')>insertGetId
must be (with ->, not >)
DB::table('jocom_cart')->insertGetId
Hope it's could resolved the problem
I'm trying to prevent the user to create the same username. well my real problem is how to loop a list of data from model in controller. Maybe we know how to loop it in view by using this -> data['user'] and in view we can call $user. but how can we do that in controller layer.
here's my code
Controller
$username = strtolower($this->input->post('name'));
$fixUsername = str_replace(" ",".",$username);
$counter = 1;
$list[] = $this->addusermodel->getAllUsername();
for($i=0;$i<sizeof($list);$i++) {
if($list[$i] == $fixUsername) {
$counter = 0;
}
}
if($counter == 0) {
$data['result'] = "The username has already been taken";
$this->load->view('adduserview',$data);
} else {
$data = array(
'Nama' => $this->input->post('name'),
'Username' => $fixUsername."#praba",
'Password' => md5($this->input->post('password')),
'created' => date("Y-m-d h:i:sa"),
'createdBy' => $createdBy,
'lastModified' => date("Y-m-d h:i:sa"),
'lastModifiedBy' => $lastModifiedBy
);
$this->addusermodel->saveUser($data);
//$data['Username'] = $listName;
$data['message'] = "New user successfully added.";
$data['messageContent'] = "The username: ".$fixUsername."#praba". $counter;
$this->load->view('successpageview',$data);
//redirect('successpageview','refresh');
}
my model (is like usual)
function getAllUsername() {
$this->db->select('Username');
$this->db->from('tbluser');
$query = $this->db->get();
return $query->result_array();
}
I think a better approach would be to create another function in your model, which searches your database by ID, or by email, or by another unique field. If the function returns a row - then the user exists. If it returns nothing - then add a new user.
Im tying to update a table with the followning function in PHP. The problem is that the second parameter $work_place is not accepted and the update fails. This is my first time working with PHP and mySQL so my knowledge is a bit limited.
public function timestampOut($work_done, $work_place)
{
// clean the input to prevent for example javascript within the notes.
$work_done = strip_tags($work_done);
$work_place = strip_tags($work_place);
$userLastTimestampID = $this->getUserLastTimestampID();
$sql = "UPDATE timestamps SET timestamp_work_description = :work_done, timestamp_work_dropdown = :work_place, timestamp_out = now() WHERE timestamp_id = $userLastTimestampID[0] AND user_id = :user_id";
$query = $this->db->prepare($sql);
$query->execute(array(':work_done' => $work_done, ':user_id' => $_SESSION['user_id']));
$count = $query->rowCount();
if ($count == 1) {
return true;
} else {
$_SESSION["feedback_negative"][] = FEEDBACK_NOTE_CREATION_FAILED;
}
// default return
return false;
}
You just need to add work_place to the param array in your execute call, like so:
$query->execute(array(':work_done' => $work_done, ':work_place' => $work_place, ':user_id' => $_SESSION['user_id']));
Please read again how execute works. You would want to use it like this:
$query->execute(array(':work_done' => $work_done, ':work_place' => $work_place, ':user_id' => $_SESSION['user_id']));
Try to replace
$query->execute(array(':work_done' => $work_done, ':user_id' => $_SESSION['user_id']));
with
$query->execute(array(':work_done' => $work_done, ':user_id' => $_SESSION['user_id']), ':work_place' => $work_place);
I am using Codeigniter to create an Autocomplete for user names:
Using the parameter : search-user?term=s I get the following data back as Json :
{"id":"1","value":"Stuart Blackett"}{"id":"2","value":"Simon Wilton"}
However when I am running the auto select, On the search for say "St" it brings back by name in the options, But also the ID as well.
How do I prevent this from happening? I suspect my loop could be the issue.
My PHP Function is as follows :
function search_user()
{
$term = $this->input->get('term');
$user_search = $this->vendor_model->search_user($term);
$user['response'] = 'false';
if(count($user_search) > 0)
{
$user['response'] = 'true';
$user = array();
foreach($user_search as $user)
{
$user = array(
'id' => $user->user_id,
'value' => $user->user_firstname .' '. $user->user_surname
);
echo json_encode($user);
}
}
}
{"id":"1","value":"Stuart Blackett"}{"id":"2","value":"Simon Wilton"} isn't valid JSON.
Try not echoing each $user's information separately - instead, build a new array of users and json_encode() that array. Example:
foreach($user_search as $user) {
$users[] = array(
'id' => $user->user_id,
'value' => $user->user_firstname .' '. $user->user_surname
);
}
echo json_encode($users);