Codeigniter get mysql value - php

Can someone please guide me how I can fetch mysql row's value for "pk" to the $response variable to be able to allow the script to unfollow users automatically. I have already tried the script and it does unfollow when an pk id is provided but I want to automatically fetch it from mysql to be able to run it. Thank you for any help provided.
These are the methods I tried with no success:
$this->db->select('pk');
$this->model->from(INSTAGRAM_FOLLOW_TB);
$this->db->where("id = '11'");
$query1 = $this->db->get();
$result = $query1->result();
Main ID that only unfollow this ID- created by Mushfik Media,
$response = $i->unfollow($result);
I have also tried
$accounts = $this->model->fetch("*", INSTAGRAM_ACCOUNT_TB, "id = '11'");
$response = $i->unfollow($accounts->pk);
But didn't work. $NEED MYSQL DATA VALUE is where the value is supposed to be echoed but doesn't
case 'unfollow':
try {
$result = $i->getSelfUsersFollowing();
if(!empty($result) && $result->status == "ok" && !empty($result->users)){
$response = $i->unfollow($NEED MYSQL DATA VALUE);
$response = $response->status;
$CI =& get_instance();
$CI->load->model('Schedule_model', 'schedule_model');
$lang = $CI->db->insert(INSTAGRAM_FOLLOW_TB, array(
"pk" => $row->pk,
"name" => $row->username,
"type" => $data->schedule_type,
"uid" => $data->uid,
"account_id" => $data->account,
"account_name" => $data->name,
"created" => NOW
));
}
} catch (Exception $e){
$response = $e->getMessage();
}
break;

Maybe something like this to get your pk:
$query1 = $this->db->select('pk')
->from(INSTAGRAM_FOLLOW_TB)
->where('id', 11)
->get();
if( $query1->num_rows() == 1 ){
$row = $query1->row();
$response = $i->unfollow( $row->pk );
}
Regarding your information that you are trying to use $this when not in object context, because you are in a helper, you need to get the CI super object. So, if you were trying to use $this->db, you would do this:
$CI =& get_instance();
// Now you can use $CI->db
// and anything you would normally
// access via $this in a controller
// or model
OK, finally to show an example of how to order or limit a query:
$query1 = $this->db->select('pk')
->from(INSTAGRAM_FOLLOW_TB)
->where('id', 11)
->order_by('your_timestamp_field', 'ASC') // This would order by timestamp in ascending order
->limit(1) // This would limit to a single row
->get();

Related

How to fetch columns data from a table using the foreign key in CodeIgniter 3

Hi first of all I should tell you that English is not my first language so excuse any misunderstandings. What I'm trying here is to access to the "donors" table data using the foreign key in the "packets" table and I need to get that data in the controller to use. I refer PacketID in my view and in the staff controller I need to get the specific DonorMobile and DonorName to send an SMS to that donor. I have tried creating multiple model functions but didn't work. Can it be done by that way or is there any other way? TIA!
Screenshots of donors and packets tables
donors table and
packets table
Staff controller - I know you can't access data like $donorData->DonorID in the controller
public function markAsUsed($packet)
{
$this->load->Model('Donor_Model');
$donorData = $this->Donor_Model->getDonors($packet);
$this->load->Model('Donor_Model');
$data = $this->Donor_Model->markAsUsed($donorData->DonorID);
$sid = 'twilio sid';
$token = 'twilio token';
$donorMobile = '+94' . $donorData->DonorMobile;
$twilioNumber = 'twilio number';
$client = new Twilio\Rest\Client($sid, $token);
$message = $client->messages->create(
$donorMobile, array(
'from' => $twilioNumber,
'body' => 'Thank you ' . $donorData->DonorName . ' for your blood donation. Your donation has just saved a life.'
)
);
if ($message->sid) {
$this->load->Model('Donor_Model');
$this->Donor_Model->changeStatus($data->isAvailable);
redirect('staff/viewpackets');
}
}
Model
function getDonors($packet) {
$data = $this->db->get_where('packets', array('PacketID' => $packet));
return $data->row();
}
function markAsUsed($donor)
{
$data = $this->db->get_where('donors', array('DonorID' => $donor));
return $data->row();
}
function changeStatus($packet)
{
$data = array(
'isAvailable' => False,
);
return $this->db->update('packets', $data, ['PacketID' => $packet]);
}
What you did in the answer is not advisable, using loops to fetch from tables will slow the system by large when you have large datasets. What was expected is to use JOIN queries to join the donors and packets tables as shown below:
$this->db->select('donors_table.DonorName,donors_table.DonorMobile,packets_table.*')->from('packets_table');
$this->db->join('donors_table','donors_table.DonorID=packets_table.DonorID');
$query = $this->db->get();
$result = $this->db->result();
Then you can iterate through each donor as below:
foreach($result as $row){
$donarName = $row->DonorName;
$donorMobile = $row->DonorMobile;
}
NB: It is always advisable to perform any fetch, insert, delete or update operations from the model, that is why Codeigniter is an MVC. Stop fetching data directly from database within Controllers.
Found the answer! You can do this only using the controller.
$packetData = $this->db->get_where('packets', array('PacketID' => $packet));
foreach ($packetData->result() as $row) {
$donorID = $row->DonorID;
$packetDonatedDate = $row->DonatedDate;
}
$donorData = $this->db->get_where('donors', array('DonorID' => $donorID));
foreach ($donorData->result() as $row) {
$donarName = $row->DonorName;
$donorMobile = $row->DonorMobile;
}

What's a better way to make this insert more secure and safe from injection and manipulation

I've been trying to put together functions in a more secure way that keeps us safe from injection or manipulating inserts by calling different columns to be updated. In your opinion, is this function safe at all, and if not what would you suggest is a better way to do it, and why.
This function is called when a user updates their profile, or specific parts of their profile, as you can see I've made an array with items which is all they can update in that table. Also, the user_id I am getting is from the secure encrypted JSON token that's attached to their session, they are not sending that. Thanks for your time.
function updateProfile( $vars, $user_id ) {
$db = new Database();
$update_string = '';
$varsCount = count($vars);
$end = ',';
$start = 1;
$safeArray = array( "gradYear", "emailAddress", "token", "iosToken", "country",
"birthYear", "userDescription" );
foreach($vars as $key => $value) {
if(in_array( $key, $safeArray )) {
if($start == $varsCount) {
$end = '';
}
$update_string .= $key . '=' . '"' . $value . '"' . $end;
}
$start++;
}
if($start > 0) {
$statement = "update users set " . $update_string . " where userId = '$user_id'";
$query = $db->updateQuery( $statement );
if($query) {
$response = array( "response" => 200 );
} else {
$response = array( "response" => 500, "title" => "An unknown error occured,
please try again");
}
}
As the comments above suggest, it's worth using query parameters to protect yourself from SQL injection.
You asked for an example of how anything malicious could be done. In fact, it doesn't even need to be malicious. Any innocent string that legitimately contains an apostrophe could break your SQL query. Malicious SQL injection takes advantage of that weakness.
The weakness is fixed by keeping dynamic values separate from your SQL query until after the query is parsed. We use query parameter placeholders in the SQL string, then use prepare() to parse it, and after that combine the values when you execute() the prepared query. That way it remains safe.
Here's how I would write your function. I'm assuming using PDO which supports named query parameters. I recommend using PDO instead of Mysqli.
function updateProfile( $vars, $userId ) {
$db = new Database();
$safeArray = [
"gradYear",
"emailAddress",
"token",
"iosToken",
"country",
"birthYear",
"userDescription",
];
// Filter $vars to include only keys that exist in $safeArray.
$data = array_intersect_keys($vars, array_flip($safeArray));
// This might result in an empty array if none of the $vars keys were valid.
if (count($data) == 0) {
trigger_error("Error: no valid columns named in: ".print_r($vars, true));
$response = ["response" => 400, "title" => "no valid fields found"];
return $response;
}
// Build list of update assignments for SET clause using query parameters.
// Remember to use back-ticks around column names, in case one conflicts with an SQL reserved keyword.
$updateAssignments = array_map(function($column) { return "`$column` = :$column"; }, array_keys($data));
$updateString = implode(",", $updateAssignments);
// Add parameter for WHERE clause to $data.
// This must be added after $data is used to build the update assignments.
$data["userIdWhere"] = $userId;
$sqlStatement = "update users set $updateString where userId = :userIdWhere";
$stmt = $db->prepare($sqlStatement);
if ($stmt === false) {
$err = $db->errorInfo();
trigger_error("Error: {$err[2]} preparing SQL query: $sqlStatement");
$response = ["response" => 500, "title" => "database error, please report it to the site administrator"];
return $response;
}
$ok = $stmt->execute($data);
if ($ok === false) {
$err = $stmt->errorInfo();
trigger_error("Error: {$err[2]} executing SQL query: $sqlStatement");
$response = ["response" => 500, "title" => "database error, please report it to the site administrator"];
return $response;
}
$response = ["response" => 200, "title" => "update successful"];
return $response;
}
In addition to the excellent Bill's answer, one little suggestion: always make your methods to do one thing at a time. If a method's job is to update a database, then it should only update a database and nothing else, the HTTP interaction included. Imagine this method could be used in non-AJAX context or without a web-server at all but from a command line utility. Those HTTP codes and JSON responses would look completely off the track. So have two classes: one to update the database and one to interact with the client. It will make your code much cleaner and reusable.
Also, never create a new connection to the database for the every query. Instead, have a ready made connection and use it for all database interactions.
function updateProfile($db, $vars, $userId )
{
$safeArray = array( "gradYear", "emailAddress", "token", "iosToken", "country",
"birthYear", "userDescription" );
// let's check if all columns are safe
if (array_diff(array_keys($vars), $safeArray)) {
throw new InvalidArgumentException("Unknown columns provided");
}
$updateAssignments = array_map(function($column) {
return "`$column` = :$column"; }, array_keys($vars)
);
$updateString = implode(",", $updateAssignments);
$vars["userIdWhere"] = $userId;
$sqlStatement = "update users set $updateString where userId = :userIdWhere";
$db->prepare($sqlStatement)->execute($vars);
}
See, it makes your code slim and readable. And, above all - reusable. You don't have to make your methods bloated. PHP is a very concise language, if used properly

zend update is deleting old values

I am doing update in zend which in some cases doesn't update all the fields, the fields that are not updated become null as if we are doing an add.
This is the code from the Controller
$result = $theuserModel->updateUserTest(
$id,
$this->getRequest()->getPost('user_name'),
/*some code*/
$this->getRequest()->getPost('user_postee')
);
if ($result) {
$this->view->notif = "Successfull Update";
return $this->_forward('index');
}
The corresponding model
public function updateUserRest($id, $nom,$poste)
{
$data = array(
'user_name' => $nom,
'user_postee' => $poste
);
$result=$this->update($data, 'user_id = '. (int)$id);
return $result;
}
I do an update for user_name only I found that the old value of user_postee got deleted and replaced by the default value (initial value which we get at the time of creation) for example null.
Thanks in advance!
I have done this changes (bad solution) If anyone has another one optimised
->Controller
if($this->getRequest()->getPost('user_name')){
$resultname=$userModel->updateUserName($id,$this-
>getRequest()->getPost('user_name'));
}
if($this->getRequest()->getPost('user_postee')){
$resultpostee=$userModel->updateUserPoste($id,$this-
>getRequest()->getPost('user_postee'));
}
if ($resultname|| $resultpostee){
$this->view->notif = "Mise à jour effectuée";
return $this->_forward('index');
}
-> Model
public function updateUserName($id, $name)
{
$data = array(
'user_name' => $name
);
$result=$this->update($data, 'user_id = '. (int)$id);
return $result;
}
public function updateUserPostee($id, $postee)
{
$data = array(
'user_postee' => $poste
);
$result=$this->update($data, 'user_id = '. (int)$id);
return $result;
}
that is complete correct response of update in Zend Db Table.
I believe your assumption is if the value of 'user_postee' is null then it should not be updated into the database, am I correct.
The answer is they will update the new value of "NULL" into the database.
To avoid it , what you should do is
using fetchrow() to get the value of the line by id
foreach user_name and user_postee check if the value of them matching the array value your fetched , if nothing changed or Null, then use the old value from array , if new value exist use new value insert into the array , finally use update to update the new array into database
Assume your Table Column is also "user_name" and "user_postee"
public function updateUserRest($id, $nom,$poste)
{
$row = $this->fetchRow('user_id = '. (int)$id);
if(!empty($nom) && $row['user_name'] != trim($nom)){
$row['user_name'] = $nom;
}
if(!empty($poste) && $row['user_poste'] != trim($poste)){
$row['user_poste'] = $poste;
}
$result=$this->update($row, 'user_id = '. (int)$id);
return $result;
}

[vtiger][Webservice] Database error while performing requested operation

I use the Vtiger webservice with its different methods CRUD, login ... etc. I created a task via the Calendar module, it worked well, but when I want to delete it does not work.
If I'm not mistaken, I need to have the object's id (so Calendar) in order to delete it. So I do:
public static function getTaskUser($user)
{
$idUser = self::getUserAccountId('XXXX');
$vtiger = new VtigerWS();
$connect = $vtiger->getConnection();
if ($connect && $connect['success'] == true) {
$response = $vtiger->query("id", "Calendar", "parent_id = '$idUser' ORDER BY id");
if ($response['success'] == false) {
$result = $response['error'];
} else {
$result = array();
foreach ($response['result'] as $task) {
$result[] = $task['id'];
}
}
} else {
$result = $connect['error'];
}
$vtiger->logout();
return $result;
}
==> In this function, I first look for the user id in vtiger (the user who was assigned to the previously created task). It works well.
But when the query is running:
($ vtiger-> query ("id", "Calendar", "parent_id = '$ idBaz' ORDER BY id");)
I get an error:
"code" => "DATABASE_QUERY_ERROR"
"message" => "Database error while performing requested operation"
The connection is good, I tried a query SELECT * FROM Calendar it does not work either ... I do not see where the error can come from.

ZF2 custom db query using SUM

Can someone give me a hint what I am doing wrong?
public function getPaymentSumByTypeAndProject($project_id,$type) {
$type = (int) $type;
$project_id = (int) $project_id;
$rowset = $this->tableGateway->select(array('total_amount' => new Expression('SUM(payment.amount)')))->where(array('type' => $type, 'project_id' => $project_id));
$row = $rowset->toArray();
if (!$row) {
throw new \Exception("Busted :/");
}
return $rowset;
}
I want to make the same query:
SELECT SUM(amount) FROM payment WHERE type='$type' AND project_id ='$project_id';
Edit:
I made small progress, i have figured out how to sum whole column
public function getPaymentSumByTypeAndProject($project_id, $type) {
$type = (int) $type;
$project_id = (int) $project_id;
$resultSet = $this->tableGateway->select(function (Select $select) {
$select->columns(array(new \Zend\Db\Sql\Expression('SUM(amount) as amount')))->where('type="0"');
});
return $resultSet;
Maybe someone could help me to figure out how to add condition: "WHERE type='$type' AND project_id='$project_id'" ?
I know this is an old question, but I came across it and figured I'd throw in my two cents:
public function getPaymentSumByTypeAndProject($project_id, $type) {
// This TableGateway is already setup for the table 'payment'
// So we can skip the ->from('payment')
$sql = $this->tableGateway->getSql();
// We'll follow the regular order of SQL ( SELECT, FROM, WHERE )
// So the query is easier to understand
$select = $sql->select()
// Use an alias as key in the columns array instead of
// in the expression itself
->columns(array('amount' => new \Zend\Db\Sql\Expression('SUM(amount)')))
// Type casting the variables as integer can take place
// here ( it even tells us a little about the table structure )
->where(array('type' => (int)$type, 'project_id' => (int)$project_id));
// Use selectWith as a shortcut to get a resultSet for the above select
return $this->tableGateway->selectWith($select);
}
Also, an adapter can be retrieved from a table gateway like this:
$adapter = $this->tableGateway->getAdapter();
But you don't really need it anymore when you select using the above mentioned method.
Ok now this is working, tell me is this how it;s should be done?
public function getPaymentSumByTypeAndProject($project_id, $type) {
$type = (int) $type;
$project_id = (int) $project_id;
$adapter = $this->tableGateway->adapter;
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('payment');
$select->where(array('type'=>$type,'project_id'=>$project_id));
$select->columns(array(new \Zend\Db\Sql\Expression('SUM(amount) as amount')));
$selectString = $sql->getSqlStringForSqlObject($select);
$resultSet = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE);
return $resultSet;
}
use This one
$select = $this->getSql()->select()
->columns(array('amount' => new \Zend\Db\Sql\Expression('SUM(amount)')))
->where("type ='$type'")
->where("project_id ='$project_id'");
$resultSet = $this->selectWith($select);
$row = $resultSet->current();
// echo $select->getSqlString();die; //check query use this line
if(!$row){
return False;
}
return $row->amount;
try to make like that instead of (int) $type
intval($type);
and
intval($project_id);
and in your sql
change your variables to
'".$type."'
AND
'".$project_id."'

Categories