Foreach loop, and array building - php

I have an admin area where they can delete multiple users at a time. This is part of the code that handles the deletion. Basically it goes through the user ids and deletes each one that was marked checked.
if ($_POST['doDelete'] == 'Delete') {
if (!empty($_POST['u'])) {
foreach ($_POST['u'] as $uid) {
$id = escape($uid);
$delete = Nemesis::query("DELETE FROM users WHERE id = '{$id}' AND id <> '{$_SESSION[user_id]}'");
if (!$delete) {
$msg->add('e', QUERY_ERROR);
redirect('users.php');
exit();
}
}
}
/* we need a way to iterate over users deleted */
$msg = new Messages();
$msg->add('s', QUERY_DELETE_SUCCESS);
redirect('users.php');
exit();
}
function get_user_name_from_id($user_id)
{
if ($_SESSION['user_level'] == ADMIN_LEVEL) {
$viewUserMod = 1;
} else {
$config = Nemesis::select("usr_view_cm", "config");
$row_config = $config->fetch_assoc();
$viewUserMod = $row_config['usr_view_cm'];
}
if (is_numeric($user_id) && $viewUserMod == 1) {
$sql = Nemesis::select("full_name", "users", "id = {$user_id}");
if ($sql->num_rows > 0) {
$user_name = $sql->fetch_assoc();
return $user_name['full_name'];
} else {
// user name cannot be matched with db, either error, or most likely user was deleted
return 'User ' . $user_id;
}
} else {
return $user_id;
}
}
Where it says QUERY_DELETE_SUCCESS I would like to output something like "Deleted Bob, Jack, Tim" .etc I have a function that uses the users id and gets their names. The issue is that once the iteration is complete. Obviously those users no longer exist in the database and I cannot get their names. Is there a way of running this function during the loop, and building a string or array. That can be outputted in place of the message?

You should just be able to do this:
if ($_POST['doDelete'] == 'Delete') {
$deleted = array();
if (!empty($_POST['u'])) {
foreach ($_POST['u'] as $uid) {
$id = escape($uid);
$username = get_user_name_from_id($uid);
$delete = Nemesis::query("DELETE FROM users WHERE id = '{$id}' AND id <> '{$_SESSION[user_id]}'");
if (!$delete) {
$msg->add('e', QUERY_ERROR);
redirect('users.php');
exit();
}
$deleted[] = $username // push name to array after deletion is successful
}
}
/* The $deleted array now holds the names of the deleted users.
* Do with it what you want.
*/
$names = implode(",", $deleted)
$msg = new Messages();
$msg->add('s', QUERY_DELETE_SUCCESS . " Deleted: $names");
redirect('users.php');
exit();
}
There are several improvements that can be made here, including efficiency (combining many small single queries into a few larger ones) and error handling (don't redirect on the first error - instead redirect after all processing is complete to a page with a list of successes and errors), but this is the basic idea.
Here is a quick change that will do all of the operations, even if one of them errors:
if ($_POST['doDelete'] == 'Delete') {
$deleted = array();
$errored = array();
if (!empty($_POST['u'])) {
foreach ($_POST['u'] as $uid) {
$id = escape($uid);
$username = get_user_name_from_id($uid);
$delete = Nemesis::query("DELETE FROM users WHERE id = '{$id}' AND id <> '{$_SESSION[user_id]}'");
if (!$delete) {
$errored[] = $username;
} else {
$deleted[] = $username // push name to array after deletion is successful
}
}
}
/* The $deleted array now holds the names of the deleted users.
* The $errored array now holds the names of users who were not deleted due to errors.
* Do with them what you want.
*/
$msg = new Messages();
$names_deleted = implode(",", $deleted)
$msg->add('s', QUERY_DELETE_SUCCESS . " Deleted: $names_deleted");
if (count($errored) > 0) {
$names_errored = implode(",", $errored)
$msg->add('e', QUERY_ERROR . " Did not delete: $names_errored");
}
redirect('users.php');
exit();
}

You could add the names to an array as you are looping over the uids with something like this:
$names = array();
if (!empty($_POST['u'])) {
foreach ($_POST['u'] as $uid) {
$names[] = get_user_name_from_id($uid);
$id = escape($uid);
$delete = Nemesis::query("DELETE FROM users WHERE id = '{$id}' AND id <> '{$_SESSION[user_id]}'");
if (!$delete) {
$msg->add('e', QUERY_ERROR);
redirect('users.php');
exit();
}
}
}
Then when you want to output the confirmation message, you could turn that array into a comma separated string with something like this:
$names = implode(', ',$names);
$message = "Deleted $names";

Related

PHP/MySQL: Always show "No data" even though the data is exist at database table

currently I create a system with a 'search' function. At the input text, if I enter the correct badge id, it will display all the staff data, but if enter wrong data, it will alert 'No Data'. Below is the code:
<?php
require_once "../../config/configPDO.php";
require_once "../../config/check.php";
$team = $_SESSION['team'];
$badgeid = '';
$fullname = '';
$roles_id = '';
function getPosts()
{
$posts = array();
$posts[0] = $_POST['badgeid'];
$posts[3] = $_POST['fullname'];
$posts[4] = $_POST['roles_id'];
return $posts;
}
if(isset($_POST['search']))
{
$data = getPosts();
if(empty($data[0]))
{
echo "
<script>alert('Please enter badge id')</script>";
} else {
$searchStmt = $conn->prepare('SELECT * FROM users WHERE badgeid = :badgeid AND roles_id = "4"');
$searchStmt->execute(array(
':badgeid'=> $data[0]
));
if($searchStmt)
{
$user = $searchStmt->fetch();
if(empty($user))
{
echo "
<script>alert('No data')</script>";
}
$badgeid = $user[0];
$fullname = $user[3];
$roles_id = $user[4];
}
}
}
From the query above, when the roles_id = '4', and I enter the correct badge id, it will display all the staff data.
But if I entered the correct badge id, but the roles_id at the database is 5, it also will display alert 'No data'.
Now, how I want to make sure that, if I entered correct badge id but the roles id is not equal to 4, it will alert 'Staff is eligible'
Can anyone know how to solve my problem?
You can change your query to fetch user data when roles_id is either 4 or 5, and then check the value fetched in the query. If it is 5, Staff is eligible is alerted, otherwise the values from the fetch are assigned as you do currently:
$searchStmt = $conn->prepare('SELECT * FROM users WHERE badgeid = :badgeid AND roles_id IN (4, 5)');
$searchStmt->execute(array(
':badgeid'=> $data[0]
));
if($searchStmt) {
$user = $searchStmt->fetch();
if(empty($user)) {
echo "<script>alert('No data')</script>";
}
elseif ($user[4] == 5) {
echo "<script>alert('Staff is eligible')</script>";
}
else {
$badgeid = $user[0];
$fullname = $user[3];
$roles_id = $user[4];
}
}
Note that using associative keys for fetching data from a table is much safer. If the table was modified with an extra column between the first and the fourth columns, your code would stop working.

session_decode() doesn't retrieve the right $_SESSION informations from CodeIgniter 3

I have an ecommerce built with CodeIgniter 3 and a dashboard site built in php.
I would that the user logged on the ecommerce, would be already logged also in the personal dashboard.
In the ecommerce, there is a button to pass to the dashboard. This button calls the file of the dashboard (APS) named /APS/index.php.
In this file I put:
<?php session_start();
require_once("config.php");
if(!isset($_SESSION['client']) || empty($_SESSION['client'])) {
if (isset($_COOKIE['ci_session']) && !empty($_COOKIE['ci_session'])) {
// Check connection
$sql = "SELECT `data` FROM `ci_sessions` WHERE id=" . "'" . $_COOKIE['ci_session'] . "'";
$result = $conn->query($sql);
$first_arr = '';
if ($result->num_rows > 0) {
// output data of each row
while ($row = $result->fetch_assoc()) {
$first_arr = explode(';', $row['data']);
}
$res = '';
foreach ($first_arr as $v) {
if (strpos($v, 'customer_id') !== false) {
$res = explode('|', $v);
}
}
$conn->close();
$_SESSION['client'] = unserialize($res[1]);
} else {
$_SESSION['client'] = '';
}
}
}
if(isset($_SESSION['client']) && !empty($_SESSION['client'])){ header('location:account.php'); $x=$client->get($_SESSION['client']); $_SESSION['client']=$x[0]; exit; }
The problem is that in $_SESSION['client'] there is not the user informations. There are all the users in the user table and then it passes the first element of this list to the next page, /APS/account.php, showing the dashboard always for the first user of the user table.
How can I do?
ps. I printed some variables. The $sql statement is correct, and in $res there is the right customer_id of the logged user. The unserialize() function - I already tried the session_decode() function, but with the same result - return 1 (true), but this is not what I want.

PHP API returning wrong response for android app

I am creating a API for android developer in PHP in which he want to delete some values from database and want to show a message after that.
Now the problem is this data is deleting successfully but this API always shows else part message after complete the process. If I remove the else part its return the null which crash the android app. So I just want to give a proper json message to the android developer
Here is the code which I am trying
if($clear_my_property == "yes" && $clear_my_requirement == "yes" && $all_of_these == "yes" && $user_name_id == $user_name_id1)
{
$tables_count = array("property_for_sale","property_for_rent","cpo_post_requirements");
foreach($tables_count as $table_count)
{
$user_count = mysql_query("select * from $table_count where user_name = '$user_name'");
$total_user_count = mysql_num_rows($user_count);
if($total_user_count > 0)
{
$tables_data = array("property_for_sale","property_for_rent","cpo_post_requirements");
foreach($tables_data as $table_data)
{
$user_sql = mysql_query("delete from $table_data where user_name='$user_name'");
if($user_sql)
{
$response['success'] = 1;
$response['user']['error_msg'] = 'Clear Successfully All History!';
}
}
}
else
{
$response['success'] = 0;
$response['user']['error_msg'] = 'Record Not Found!';
}
}
}
I know there is something wrong with this logic. But I need expert advise where my logic is wrong and what I have to do make it success
Problem with your original code, is that you are setting success/failure inside the loop. One of the four table may/may not contain the username. And if the last table don't have that, then as per your logic you are getting "record not found" even if previous iteration of the loop deleted data from the tables where username exists.
<?php
$conn = mysqli_connect(.....);
if($clear_my_property == "yes" && $clear_my_requirement == "yes" && $all_of_these == "yes" && $user_name_id == $user_name_id1) {
$tables_count = array("property_for_sale","property_for_rent","cpo_post_requirements");
$userHistoryDeleted = 0;
foreach($tables_count as $table_count) {
//if history is found, then it will be deleted otherwise not
mysql_query("delete from $table_count where user_name = '$user_name'");
if(mysqli_affected_rows($conn)) {
$userHistoryDeleted = 1;
}
}
$msg = 'Record Not Found!';
if($userHistoryDeleted) {
$msg = 'Clear Successfully All History!';
}
$response['success'] = $userHistoryDeleted;
$response['user']['error_msg'] = $msg;
}
Change your code :
if($total_user_count > 0)
{
$tables_data = array("property_for_sale","property_for_rent","cpo_post_requirements");
foreach($tables_data as $table_data)
{
$user_sql = mysql_query("delete from $table_data where user_name='$user_name'");
if($user_sql)
{
$response['success'] = 1;
$response['user']['error_msg'] = 'Clear Successfully All History!';
}
}
}
else
{
$response['success'] = 0;
$response['user']['error_msg'] = 'Record Not Found!';
}
to this one
if($total_user_count > 0)
{
$tables_data = array("property_for_sale","property_for_rent","cpo_post_requirements");
foreach($tables_data as $table_data)
{
$user_sql = mysql_query("delete from $table_data where user_name='$user_name'");
}
$response['success'] = 1;
$response['user']['error_msg'] = 'Clear Successfully All History!';
}

How to display more number of array results in a single array?

I have two tables: loginandfollow`.
Table name: login
Fields: id,email,username,imageurl
Table name: follow
Fields: id:user_id:follow_id
It's like a Twitter follower's concept. I want to get the details of myfollower name and also myfollower's following person's name.
For that I have written the coding as like below.
public function follw ()
{
if( $this->input->get("userid") )
{
extract($this->input->get());
$followers_list = array();
$follower = array();
$query = $this->db->query('select follow_id from follow where user_id = '.$userid.'')->result();
foreach($query as $row)
{
$follower['follower_id'] = $row->follow_id;
if($follower['follower_id'] == "")
{
echo "hi";
}
else
{
$query3 = $this->db->query('select username from login where id = '.$follower['follower_id'].'')->result();
foreach($query3 as $row3)
{
$follower['followuser'] = $row3->username;
}
$query1 = $this->db->query('select follow_id from follow where user_id = '.$follower['follower_id'].'')->result();
foreach($query1 as $row1)
{
$follower['follow_id'] = $row1->follow_id;
if($follower['follow_id'] == "")
{
echo "jeeva";
}
else
{
$query2 = $this->db->query('select username from login where id = '.$follower['follow_id'].'')->result();
foreach($query2 as $row2)
{
$follower['username'] = $row2->username;
}
}//second for each in else loop
}//first foreach in else loop
}//main else
$followers_list[] = $follower;
}
$str = json_encode($followers_list);
echo stripslashes($str);
}
else
{
echo '[{"status":"Failure - Error Occured - Not Enough Details provided"}]';
}
}
I get the output like this:
[{"follower_id":"12","followuser":"janmejoy","follow_id":"24","username":"sarvana"},{"follower_id":"10","followuser":"jeeva","follow_id":"23","username":"selva"},{"follower_id":"6","followuser":"raj","follow_id":"17","username":"jeeva"},{"follower_id":"23","followuser":"selva","follow_id":"22","username":"guru"}]
This output displays myfollower's name and myfollower's following person name, but the problem is it displays only one member of myfollower's following person name.
However, I want to the output like this:
[{"follower_id":"12","followuser":"janmejoy",{"follow_id":"24","username":"sarvana",follow_id":"13","username":"jai",follow_id":"9","username":"raj"}},{"follower_id":"10","followuser":"jeeva","follow_id":"23","username":"selva"},{"follower_id":"6","followuser":"raj","follow_id":"17","username":"jeeva"},{"follower_id":"23","followuser":"selva","follow_id":"22","username":"guru"}]
[{"follower_id":"12","followuser":"janmejoy",{"follow_id":"24","username":"sarvana",follow_id":"13","username":"jai",follow_id":"9","username":"raj"}},{"follower_id":"10","followuser":"jeeva","follow_id":"23","username":"selva"},{"follower_id":"6","followuser":"raj","follow_id":"17","username":"jeeva"},{"follower_id":"23","followuser":"selva","follow_id":"22","username":"guru"}]
This code is invalid JSON variable. i can't solve this question for you. Please update your question.

php mysql check previous row

I have output from a select query as below
id price valid
1000368 69.95 1
1000369 69.94 0
1000370 69.95 0
now in php I am trying to pass the id 1000369 in function. the funciton can execute only if the valid =1 for id 1000368. if it's not 1 then it will throw error. so if the id passed is 1000370, it will check if valid =1 for 1000369.
how can i check this? I think it is logically possible to do but I am not able to code it i tried using foreach but at the end it always checks the last record 1000370 and so it throws error.
regards
Use a boolean variable:
<?php
$lastValid=false;
while($row = mysql_fetch_array($result))
{
if ($lastValid) {
myFunction();
}
$lastValid = $row['valid'];
}
?>
(Excuse possible errors, have no access to a console at the moment.)
If I understand correctly you want to check the if the previous id is valid.
$prev['valid'] = 0;
foreach($input as $i){
if($prev['valid']){
// Execute function
}
$prev = $i;
}
<?php
$sql = "SELECT * FROM tablename";
$qry = mysql_query($sql);
while($row = mysql_fetch_array($qry))
{
if ($row['valid'] == 1)
{
// do some actions
}
}
?>
I really really recommend walking through some tutorials. This is basic stuff man.
Here is how to request a specific record:
//This is to inspect a specific record
$id = '1000369'; //**some specified value**
$sql = "SELECT * FROM data_tbl WHERE id = $id";
$data = mysql_fetch_assoc(mysql_query($sql));
$valid = $data['valid'];
if ($valid == 1)
//Do this
else
//Do that
And here is how to loop through all the records and check each.
//This is to loop through all of it.
$sql = "SELECT * FROM data_tbl";
$res = mysql_query($sql);
$previous_row = null;
while ($row = mysql_fetch_assoc($res))
{
some_action($row, $previous_row);
$previous_row = $row; //At the end of the call the current row becomes the previous one. This way you can refer to it in the next iteration through the loop
}
function some_action($data, $previous_data)
{
if (!empty($previous_data) && $condition_is_met)
{
//Use previous data
$valid = $previous_data['valid'];
}
else
{
//Use data
$valid = $data['valid'];
}
if ($valid == 1)
{
//Do the valid thing
}
else
{
//Do the not valid thing
}
//Do whatever
}
Here are some links to some good tutorials:
http://www.phpfreaks.com/tutorials
http://php.net/manual/en/tutorial.php

Categories