I'm using foreach loops to access records in a nested array.
I need to nest 3 arrays (so the first array contains an array, which also contains an array). I'm having success with 2 arrays but I can't get 3 to work.
I had my code working with 2 arrays (which worked just fine) but I can't get 3 arrays to be nested.
This is the result that I want:
[
{
"site_id": "1",
"user_plants": [
{
"user_plant_id": "1",
"site_id": "1",
"plant_id": "1",
"plant_images": [
{
"plant_image_id": "1"
},
{
"plant_image_id": "2"
},
{
"plant_image_id": "3"
},
]
}
]
}
]
My current code:
$query = "SELECT A.site_id FROM sites A WHERE A.user_id='".$user_id."' GROUP BY A.site_id";
$result = $this->conn->query($query);
$json_response = array();
$sites = array();
if ($result-> num_rows > 0) {
while ($item = $result->fetch_object())
$sites[] = $item;
foreach($sites as $item) {
$row_array = (array)$item;
$site_id = $item->site_id;
$user_plants = "SELECT A.user_plant_id, A.site_id, A.plant_id FROM user_plants A RIGHT JOIN sites B ON A.site_id ='".$site_id."'
JOIN plants C ON A.plant_id = C.plant_id GROUP BY A.user_plant_id";
$resultSet = $this->conn->query($user_plants);
$user_plants = array();
if ($resultSet-> num_rows > 0) {
while ($item = $resultSet->fetch_object())
$user_plants[] = $item;
foreach ($user_plants as $item) {
$row_array['user_plants'][] = (array)$item;
$plant_id = $item->plant_id;
$user_plant_id = $item->user_plant_id;
$plant_images = "SELECT A.plant_image_id FROM plants_images A WHERE A.plant_id ='".$plant_id."' UNION SELECT B.plant_image_id FROM user_plant_image B JOIN user_plants C ON B.user_plant_id ='".$user_plant_id."' WHERE C.user_id ='".$user_id."' GROUP BY B.plant_image_id ORDER BY plant_image_id";
$resultSet = $this->conn->query($plant_images);
$plant_images = array();
if ($resultSet->num_rows > 0) {
while ($item = $resultSet->fetch_object())
$plant_images[] = $item;
foreach ($plant_images as $item) {
$row_array['user_plants'][]['plant_images'][] = $item;
}
} else if ($resultSet->num_rows == 0) {
$row_array['plant_images'] = [];
}
}
$json_response[] = $row_array;
}
}
}
return $json_response;
The result of above code:
[
{
"site_id": "1",
"user_plants": [
{
"user_plant_id": "1",
"site_id": "1",
"plant_id": "1"
},
{
"plant_images": [
{
"plant_image_id": "1"
},
{
"plant_image_id": "2"
},
{
"plant_image_id": "3"
},
]
}
]
}
]
How should I adjust the foreach loops above to cater for this?
There's plenty of room for improvement in this code but I've ignored that and tried to keep the code matching yours in this example.
The main changes are:
Create a temporary variable $user_plant_array which we store "plant_images" against
Push that temporary variable to the $site_array at the end of the loop
Rename some loop variables to making it easier to identify what you're referencing
$json_response = array();
$sites = array();
if ($result->num_rows > 0) {
while ($site = $result->fetch_object()) {
$sites[] = $site;
}
foreach ($sites as $site) {
$site_array = (array)$site;
$site_id = $site->site_id;
$user_plants = "SELECT A.user_plant_id, A.site_id, A.plant_id FROM user_plants A RIGHT JOIN sites B ON A.site_id ='" . $site_id . "'
JOIN plants C ON A.plant_id = C.plant_id GROUP BY A.user_plant_id";
$resultSet = $this->conn->query($user_plants);
$user_plants = array();
if ($resultSet->num_rows > 0) {
while ($user_plant = $resultSet->fetch_object())
$user_plants[] = $user_plant;
foreach ($user_plants as $user_plant) {
// create a temporary variable here that we will map
// all "plant_images" to
$user_plant_array = (array)$user_plant;
$plant_id = $user_plant->plant_id;
$user_plant_id = $user_plant->user_plant_id;
$plant_images = "SELECT A.plant_image_id FROM plants_images A WHERE A.plant_id ='" . $plant_id . "' UNION SELECT B.plant_image_id FROM user_plant_image B JOIN user_plants C ON B.user_plant_id ='" . $user_plant_id . "' WHERE C.user_id ='" . $user_id . "' GROUP BY B.plant_image_id ORDER BY plant_image_id";
$resultSet = $this->conn->query($plant_images);
$plant_images = array();
if ($resultSet->num_rows > 0) {
while ($plant_image = $resultSet->fetch_object())
$plant_images[] = $plant_image;
foreach ($plant_images as $plant_image) {
$user_plant_array['plant_images'][] = $plant_image;
}
} else if ($resultSet->num_rows == 0) {
$user_plant_array['plant_images'] = [];
}
// the temporary variable now contains all "plant_images"
// now we can push that to the site array
$site_array['user_plants'][] = $user_plant_array;
}
$json_response[] = $site_array;
}
}
}
return $json_response;
Creating a separate answer as an alternate solution with some code improvements.
"Improvements" being more readability and/or more performant.
A few of the main changes I would suggest as "improvements" have been implemented in this example. The main ones being:
Using prepared SQL statements (not always required but good practice to use, especially in anything accepting user input, also can make for cleaner code)
Reducing the amount of loops (in a few places you were looping just to create an array and then looping again)
Returning/continuing early where possible (helps to prevent unnecessary nesting)
Removing unnecessary if statements (e.g. most of the while loops will be skipped if the results are empty - checking beforehand isn't entirely necessary)
More readable variable names (it's common for new coders to try and abbreviate a lot of variables and often take it too far - making them readable will save you a lot of time when debugging)
The code using mysqli might not be the best as I generally work with PDO.
function getSitesData() {
// assumes that $user_id is set somewhere before this
// assumes that $this->conn references a valid database connection
$sql = "SELECT A.site_id FROM sites A WHERE A.user_id = ? GROUP BY A.site_id";
$query = $this->conn->prepare($sql);
$query->bind_param("i", $user_id);
$query->execute();
$site_result = $query->get_result();
$sites = [];
while ($site = $site_result->fetch_assoc()) {
// using fetch_assoc gives us an associative array
// initialise empty array
$site["user_plants"] = [];
// get user_plants
$sql = "SELECT A.user_plant_id, A.site_id, A.plant_id FROM user_plants A RIGHT JOIN sites B ON A.site_id = ?
JOIN plants C ON A.plant_id = C.plant_id GROUP BY A.user_plant_id";
$query = $this->conn->prepare($sql);
$query->bind_param("i", $site["site_id"]);
$query->execute();
$user_plant_result = $query->get_result();
while ($user_plant = $user_plant_result->fetch_assoc()) {
// intialise empty array
$user_plant["plant_images"] = [];
// get plant images
$sql = "SELECT A.plant_image_id FROM plants_images A WHERE A.plant_id = ? UNION SELECT B.plant_image_id FROM user_plant_image B JOIN user_plants C ON B.user_plant_id = ? WHERE C.user_id = ? GROUP BY B.plant_image_id ORDER BY plant_image_id";
$query = $this->conn->prepare($sql);
$query->bind_param("iii", $user_plant["plant_id"], $user_plant["user_plant_id"], $user_id);
$query->execute();
$plant_image_result = $query->get_result();
while ($plant_image = $plant_image_result->fetch_assoc()) {
$user_plant["plant_images"][] = $plant_image;
}
$sites["user_plants"][] = $user_plant;
}
$sites[] = $site;
}
return $sites;
}
Related
I have two database tables that contain information about land contracts. They are related with land_contract_annual_price.land_contract_id -> land_contract.land_contract_id.
Table 'land_contract'
Table 'land_contract_annual_price'
If a land contract has the value "Rörligt pris" in the field land_contract_price_type, there are related values in the table
land_contract_annual_price. At the moment I'm doing two queries, one to each table. I then merge the results and present the land contract as a nested JSON array like this:
Version 1
[
{
"land_contract_id":118,
"land_contract_name":"Avtalsnamn",
"location_id":71,
"land_contract_link":"",
"land_contract_notes":"",
"land_owner_id":2,
"land_contract_start_date":"2019-07-25",
"land_contract_end_date":"2023-07-25",
"land_contract_terminated":"false",
"land_contract_payment_interval":"Halv\u00e5rsvis",
"land_contract_price_type":"R\u00f6rligt \u00e5rspris",
"land_contract_fixed_annual_price":null,
"land_contract_annual_prices":[
{"year":1, "price":873.00},
{"year":2, "price":77289.00},
{"year":3, "price":8.00},
{"year":4, "price":0.00},
{"year":5, "price":8729.00}
]
}
]
If a land contract has the value "Fast pris" in the field land_contract_price_type, there are no related values in the table
land_contract_annual_price. In that case I present the land contract like this (without the extra array at the end):
Version 2
[
{
"land_contract_id":13,
"land_contract_name":null,
"location_id":null,
"land_contract_link":"https:\/\/www.something.com\/preview\/Sl%C3%A4pvdam%20Edda\/Kddal\/Bddkta\/Besika%20Markavtal%20%20Halmstad%202016-03-08.pdf?role=personal",
"land_contract_notes":"",
"land_owner_id":null,
"land_contract_start_date":"2016-03-08",
"land_contract_end_date":"2026-03-08",
"land_contract_terminated":"true",
"land_contract_payment_interval":"\u00c5rsvis",
"land_contract_price_type":"Fast \u00e5rspris",
"land_contract_fixed_annual_price":"6000.00"
}
]
What I didn't think of, is that this solution is bad when I'm fetchin ALL the land contracts. If I'm going to do a second query to another table whenever a land contract has the value "Rörligt pris" in the field land_contract_price_type, I'm going to do hundreds of extra queries.
Is there a way to create the nested JSON array with one (1) query when a land contract has the value "Rörligt pris" in the field land_contract_price_type?
Thanks!
Below is my current code.
function read($pdo, $Id = null, $ResponseMessage = null) {
$params = [];
$array = [];
$sql = "SELECT lc.Id, lc.Name, lc.LocationId, l.Name AS LocationName, lc.Notes, lc.LandOwnerId, lo.Name AS LandOwnerName, lc.StartDate, lc.EndDate, lc.IsTerminated, lc.PaymentInterval, lc.PriceType, lc.FixedAnnualPrice, lc.Link, lc.Created, lc.Updated, lcap.AnnualPriceYear AS Year, lcap.AnnualPriceAmount AS Amount
FROM LandContract lc
LEFT JOIN Location l ON l.Id = lc.LocationId
LEFT JOIN LandOwner lo ON lo.Id = lc.LandOwnerId
LEFT JOIN LandContractAnnualPrice lcap ON lcap.LandContractId = lc.Id
ORDER BY lc.Id DESC, lcap.AnnualPriceYear DESC
";
if ($Id) {
$sql .= 'WHERE lc.Id = ?';
$params[] = $Id;
}
echo $sql;
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
while ($row = $stmt->fetch()) {
// Fields we want to extract from the select statement into the array
$select_fields = ['Id', 'Name', 'LocationId', 'LocationName', 'Link', 'Notes', 'LandOwnerId', 'LandOwnerName',
'StartDate', 'EndDate', 'IsTerminated', 'PaymentInterval',
'PriceType', 'FixedAnnualPrice ', 'Created', 'Updated'];
if (!isset($array[$row['Id']])) {
// initialize the subarray if it has not been set already
$array[$row['Id']] = array_intersect_key($row, array_flip($select_fields));
if ($row['Year'] != null) {
$array[$row['Id']]['AnnualPrices'] = [];
} else {
$array[$row['Id']]['AnnualPrice'] = $row['FixedAnnualPrice'];
}
}
if ($row['Year'] != null) {
$array[$row['Id']]['AnnualPrices'][] = ['Year' => $row['Year'], 'Amount' => $row['Amount']];
}
}
if (empty($array)) {
$ResponseMessage = new ResponseMessage();
$ResponseMessage->Status = 'Error';
$ResponseMessage->Message = 'No results';
echo json_encode($ResponseMessage, JSON_UNESCAPED_UNICODE);
exit;
}
$Response = array();
if ($ResponseMessage) {
$Response['Status'] = $ResponseMessage->Status;
$Response['Message'] = $ResponseMessage->Message;
}
$Response['LandContracts'] = array_values($array);
echo json_encode($Response, JSON_UNESCAPED_UNICODE);
$stmt = null;
}
You are better off using a JOIN query, and then structure your array from the result - having a query within a loop is often a very bad idea, and an indicator that you can use a JOIN instead.
You want to use a LEFT JOIN, joining them on the land_contract_id in both tables.
Then loop your results, and construct your array, which you can end up encoding into a JSON string once done.
$params = [];
$array = [];
$sql = "SELECT lc.*,
py.land_contract_annual_price_year AS `year`,
py.land_contract_annual_price_amount AS `amount`
FROM land_contract AS lc
LEFT JOIN land_contract_annual_price AS py
ON py.land_contract_id = lc.land_contract_id
";
if (isset($_POST['land_contract_id'])) {
$sql .= 'WHERE lc.land_contract_id = ?';
$params[] = $_POST["land_contract_id"];
}
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
while ($row = $stmt->fetch()) {
// Fields we want to extract from the select statement into the array
$select_fields = ['land_contract_id', 'land_contract_name', 'location_id', 'land_contract_link', 'land_contract_notes', 'land_owner_id',
'land_contract_start_date', 'land_contract_end_date', 'land_contract_terminated', 'land_contract_payment_interval',
'land_contract_price_type', 'land_contract_fixed_annual_price '];
if (!isset($array[$row['land_contract_id']])) {
// initialize the subarray if it has not been set already
$array[$row['land_contract_id']] = array_intersect_key($row, array_flip($select_fields));
if ($row['year'] != null) {
$array[$row['land_contract_id']]['land_contract_annual_prices'] = [];
} else {
$array[$row['land_contract_id']]['land_contract_annual_price'] = $row['land_contract_fixed_annual_price'];
}
}
if ($row['year'] != null) {
$array[$row['land_contract_id']]['land_contract_annual_prices'][] = ['year' => $row['year'], 'amount' => $row['amount']];
}
}
if (empty($array)) {
echo "No results";
exit;
}
echo json_encode($array, JSON_UNESCAPED_UNICODE);
I have two lists of check boxes. I am checking which check box is selected and based on that I am trying to get an array.
Let's say the two lists are size which have small, medium, large boxes checked and the other one is color which have red, green, blue boxes checked. The array should look something like:
array[['small', 'medium', 'large']['red', 'green', 'blue']]
But I am getting this:
array[["small"],["medium"],["large"]] [["red"],["green"],["blue"]]
This is the code:
$counter = 0;
$attributes_list = [];
foreach($features_cuts_list as $k => $features_cut) {
$inner_counter = 0;
if ($features_cut["selectedid"] != "") {
$attributes_list[$counter] = [];
$title_to_get = $features_cut["features_cuts_id"];
/* Gets the name of the box that is checked */
$query = "SELECT title FROM features_cuts_translations WHERE lang = '$lang' AND features_cuts_id = '$title_to_get' LIMIT 1;";
$result = mysql_query($query) or die("Cannot query");
$attribute_name = mysql_fetch_row($result);
foreach ($attribute_name as $q) {
array_push($attributes_list[$counter], $q);
}
$counter++;
} else {
}
}
EDIT:
This is the deceleration process for $features_cuts_list:
function getListValuesSql($sql){
global $link; //Database connection
$data=array();
$subData{0}=array();
$res=mysql_query($sql,$link);
if(mysql_num_rows($res)>0){
$i=0;
while($row=mysql_fetch_array($res)){
for($j=0;$j<mysql_num_fields($res);$j++){
$field=mysql_field_name($res, $j);
$subData{$i}[$field]=$row[$field];
}
$data[$i]=$subData{$i};
$i++;
}
return $data;
}else{
return 0;
}
}
$feature_id = $feature["features_id"];
$features_cuts_list = $data->getListValuesSql("
SELECT DISTINCT fct.*, fc.sort, fc.inner_id, fc.price,
fcp.features_cuts_id AS selectedid, IFNULL(fcpv.price,fc.price)
AS price, fcpv.sku
FROM `features_cuts` as fc
JOIN `features_cuts_translations` as fct ON fct.features_cuts_id=fc.id
LEFT JOIN `features_cuts_product_values` as fcpv ON fc.id=fcpv.features_cuts_id AND fcpv.product_id='$pageid'
LEFT JOIN `features_cuts_products` as fcp ON fc.id=fcp.features_cuts_id AND fcp.product_id='$pageid'
WHERE fc.features_id='$feature_id' AND fct.lang='$lang'
Order by fc.sort
");
Hopes this is helpful
From reading your code I think you have unnecessarily provided the $counter variable.Try this modified code:
$attributes_list = [];
foreach($features_cuts_list as $k => $features_cut) {
$inner_counter = 0;
if ($features_cut["selectedid"] != "") {
$title_to_get = $features_cut["features_cuts_id"];
/* Gets the name of the box that is checked */
$query = "SELECT title FROM features_cuts_translations WHERE lang = '$lang' AND features_cuts_id = '$title_to_get' LIMIT 1;";
$result = mysql_query($query) or die("Cannot query");
$attribute_name = mysql_fetch_row($result);
foreach ($attribute_name as $q) {
array_push($attributes_list, $q);
}
$counter++;
} else {
}
}
If not completely, it will mostly solve your issue.
Let me know what the result are , after running this piece of code.
Im trying get a list of userIds from the videos table. This table contains the media files that get uploaded the users. This is my code
$this->db->select("videos.user_id as userId");
$this->db->limit('10', $document['offset']);
$this->db->group_by('userId');
$this->db->order_by('id','desc');
$recentUploads = $this->db->get('videos')->result_array();
if (!empty($recentUploads))
{
foreach ($recentUploads as $record)
{
$totalPostMedia = $obj->totalPostMedia($record);
$record['totalPostMedia'] = $totalPostMedia;
$resData = $this->db->select("username, profileImage")->from('users')->where('id', $record['userId'])->get()->row_array();
$record['uploadBy'] = $resData['username'];
$record['profileImage'] = "http:...com/profileImage/".$resData['profileImage'];
$Mydata[] = $record;
}
}
The result get is missing some of the userIds from the table. I have tried $this->db->distinct() as well. Still got the same result. The only way i get a result with no duplicates is when i remove $this->db->order_by('id','desc'); or make it asc instead of desc. But i want to get the latest records from the table. how do i do this? Am i doing something wrong? any help would be much appreciated.
try this
$this->db->select("videos.user_id as userId");
$this->db->from("videos");
$this->db->group_by('userId');
$this->db->order_by('id','desc');
$this->db->limit('10', $document['offset']);
$recentUploads = $this->db->get()->result_array();
if (count($recentUploads)>0)
{
foreach ($recentUploads as $record)
{
$totalPostMedia = $obj->totalPostMedia($record);
$record['totalPostMedia'] = $totalPostMedia;
$resData = $this->db->select("username, profileImage")->from('users')->where('id', $record['userId'])->get()->row_array();
$record['uploadBy'] = $resData['username'];
$record['profileImage'] = "http:...com/profileImage/".$resData['profileImage'];
$Mydata[] = $record;
}
}
in your request (i mean select videos.user_id as userId) in the group_by ligne you make userId to do the group by traitement. your userId alias is not knowing as colum name that can do any traitement of it.
for that replace your userId by videos.user_id in your group by ligne.
your code will be like this to work for you
$this->db->select("videos.user_id as userId");
$this->db->limit('10', $document['offset']);
$this->db->group_by('videos.user_id');
$this->db->order_by('id','desc');
$recentUploads = $this->db->get('videos')->result_array();
if (!empty($recentUploads))
{
foreach ($recentUploads as $record)
{
$totalPostMedia = $obj->totalPostMedia($record);
$record['totalPostMedia'] = $totalPostMedia;
$resData = $this->db->select("username, profileImage")->from('users')->where('id', $record['userId'])->get()->row_array();
$record['uploadBy'] = $resData['username'];
$record['profileImage'] = "http:...com/profileImage/".$resData['profileImage'];
$Mydata[] = $record;
}
}
use max(id)
as in $this->db->select("videos.user_id as userId,max(id)");`
so you might try:
$this->db->select("videos.user_id as userId, max(id)");
$this->db->limit('10', $document['offset']);
$this->db->group_by('userId');
$this->db->order_by('id','desc');
$recentUploads = $this->db->get('videos')->result_array();
if (!empty($recentUploads))
{
foreach ($recentUploads as $record)
{
$totalPostMedia = $obj->totalPostMedia($record);
$record['totalPostMedia'] = $totalPostMedia;
$resData = $this->db->select("username, profileImage")->from('users')->where('id', $record['userId'])->get()->row_array();
$record['uploadBy'] = $resData['username'];
$record['profileImage'] = "http:...com/profileImage/".$resData['profileImage'];
$Mydata[] = $record;
}
}
https://stackoverflow.com/a/14770936/1815624
Afternoon all,
I am working through a tutorial from MASTERING EXT JS and am stuck on retrieving data from db.
The book has been using examples using PHP and MYSQL... which I do not know. I use a .net web server and SQL, so I'm trying to convert this example from the tutorial, to how I would do it on my .net webserver.
the result in JSON format should be something like this
{
"data"[
{
"id":1",
"text" : "menu1",
"items": [
{"id": 2",
"text: "submenu2
},
{
"id":"3",
"text":"submenu3"
}
the php code they give me is this
php file 1
$permissions = retrievePermissions($userName); $modules =
retrieveModules($permissions); $result = retrieveMenuOptions($modules,
$permissions);
php file 2
function retrievePermissions($userName){
require('../db/db.php');
$sqlQuery = "SELECT p.menu_id menuId FROM User u ";
$sqlQuery .= "INNER JOIN permissions p ON u.groups_id = p.groups_id ";
$sqlQuery .= "INNER JOIN menu m ON p.menu_id = m.id ";
$sqlQuery .= "WHERE u.username = '$userName' ";
$permissions = [];
if ($resultDb = $mysqli->query($sqlQuery)) {
while($user = $resultDb->fetch_assoc()) {
$permissions[] = $user['menuId'];
}
}
$resultDb->free();
$mysqli->close();
return $permissions; }
function retrieveModules($permissions){
require('../db/db.php');
$inClause = '(' . join(',',$permissions) . ')';
$sqlQuery = "SELECT id, text, iconCls FROM menu WHERE menu_id IS NULL AND id in $inClause";
$modules = [];
if ($resultDb = $mysqli->query($sqlQuery)) {
while($module = $resultDb->fetch_assoc()) {
$modules[] = $module;
}
}
$resultDb->free();
$mysqli->close();
return $modules; }
function retrieveMenuOptions($modules, $permissions){
require('../db/db.php');
$inClause = '(' . join(',',$permissions) . ')';
$result = [];
foreach ($modules as $module) {
$sqlQuery = "SELECT * FROM menu WHERE menu_id = '";
$sqlQuery .= $module['id'] ."' AND id in $inClause";
// check if have a child node
if ($resultDb = $mysqli->query($sqlQuery)) {
// determine number of rows result set
$count = $resultDb->num_rows;
if ($count > 0){
$module['items'] = array();
while ($item = $resultDb->fetch_assoc()) {
$module['items'][] = $item;
}
}
$result[] = $module;
}
}
$resultDb->close();
$mysqli->close();
return $result;
I'm trying to figure out how to return the same json format using my .net webservice/SQL instead of php/MySQL.
It seems like it does 3 separate functions. And the result array is used as a parameter for the next query.
The basics seem easy... like for retreivePermissions... it is a simple SELECT WHERE statement.
retrieveModules seems to be an INNER JOIN with the first results.
But the last one... retrieveMenuOptions, it pulls in both results as parameters, and It returns results.
That is what I don't understand... how can I pull the results from SQL in the same JSON result format.
Am I making sense?
I have an example that uses a .NET Web API controller. Not exactly a web service, but you'll get the idea. Check it out here: http://jorgeramon.me/2015/ext-js-grid-search-with-net-and-mysql-backend/
I want to sort highest to lowest cip and also lowest to highest cip, but cip value is not stored in database, it is calculated as soon as query is fired.
Here is html code to select sorting:
<select name="cip">
<option>Select CIP percentage</option>
<option value="1">Highest To Lowest</option>
<option value="2">Lowest To Highest</option>
</select>
And here is the query that I fired!
$select_applicant = "SELECT j.*, u.id, u.gender
FROM job_apply j
LEFT JOIN users u
ON u.id = j.user_id
WHERE j.job_id = '".$jid."'";
$result_applicant = mysqli_query($con, $select_applicant);
while($row_applicant = mysqli_fetch_assoc($result_applicant))
{
$user_id = $row_applicant["user_id"];
$user_info = get_user_profile_info($user_id);
$ratings_dist = get_skill_ratings_stats($user_id);
$got_it_total_rating = 0;
foreach($ratings_dist as $category=>$rating)
{
$got_it_total_rating = $got_it_total_rating + $rating['score'];
}
$got_it_total_category = count($ratings_dist);
$total_cip = ceil($got_it_total_rating / $got_it_total_category);
echo $total_cip;
}
Function "get_skill_ratings_stats" in php is as below:
function get_skill_ratings_stats($user_id){
global $con;
$items = array();
if($user_id>0)
{
$sql = "SELECT
s.category_id category_id,
c.name as category,
COALESCE(r.score_quality, 0.0) quality,
COALESCE(r.score_timing, 0.0) timing,
COALESCE(r.score_budget, 0.0) budget,
COALESCE(r.score_resp, 0.0) resp,
COALESCE(r.score_pro, 0.0) pro
FROM `user_skills` s
LEFT JOIN `skill_categories` c
ON c.category_id=s.category_id
LEFT JOIN `skill_ratings` r
ON r.skill_id=s.skill_id
WHERE s.user_id = '".(int)$user_id."'
AND s.status = 'active'
ORDER BY category ASC";
$prev_cat = '';
$result = mysqli_query($con, $sql);
// die(mysqli_error($con));
while($row = mysqli_fetch_assoc($result))
{
// print_r($row);
if(!$row['category']) continue;
if($row['category']!=$prev_cat)
{
if(isset($items[$prev_cat]['score']) && $items[$prev_cat]['score']>0 && count($items[$prev_cat])>1)
{
$items[$prev_cat]['score'] = floor(($items[$prev_cat]['score']*20)/(count($items[$prev_cat])-1));
}
$prev_cat = $row['category'];
}
if(!isset($items[$prev_cat]['score'])) $items[$prev_cat]['score'] = 0;
$items[$prev_cat][] = $row;
$items[$prev_cat]['score'] += ($row['quality']+$row['timing']+$row['budget']+$row['resp']+$row['pro'])/5;
}
}
// print_r($items);
// die();
if(isset($items[$prev_cat]['score']) && $items[$prev_cat]['score']>0 && count($items[$prev_cat])>1)
{
$items[$prev_cat]['score'] = floor(($items[$prev_cat]['score']*20)/(count($items[$prev_cat])-1));
}
$tmp = array();
foreach($items as $cat=>$item) {
$tmp[$item['score'].'-'.$cat] = $item;
}
krsort($tmp);
$items = array();
foreach($tmp as $k=>$v) {
$k = preg_replace('#^\d+-#is', '', $k);
$items[$k] = $v;
}
// print_r($tmp);
// print_r($items);
// die();
return $items;
}
Please help me! Having hard time with this!
Assuming that you are using a html table to display this I would just go with http://datatables.net/ , it will give you a lot of sorting options very easily...
Otherwise usort():
function cip($a, $b)
{
if ($a['cip'] == $b['cip']) {
return 0;
}
return ($a['cip'] < $b['cip']) ? -1 : 1;
}
$data = array(
[0] => array('cip' => 1)
[1] => array('cip' => 5)
[2] => array('cip' => 2)
);
usort($data, "cip");
foreach ($a as $key => $value) {
echo "$key: $value\n";
}
Assuming your array looks something like this:
array(
[0] => array('cip' => 1)
[1] => array('cip' => 5)
[2] => array('cip' => 2)
)
It basically loops til everything is sorted, all you do in the call back function is tell it which values to compare...
EDIT:
$total_cips[] = array('user_id' => $user_id, 'cip' => ceil($got_it_total_rating / $got_it_total_category));
Ok So now you have all the total cips in an array with there user_id right?
And outside for loop you call usort($total_cips, "cip");
Then you have a sorted array, if you wish to change the sorting direction just change the greater than to a less than in the cip function
as We0 said,
$total_cips[] = array('user_id' => $user_id, 'cip' => ceil($got_it_total_rating / $got_it_total_category));
but then i used multisort function:
function multi_sort($array, $akey)
{
function compare($a, $b)
{
global $key;
return strcmp($a[$key], $b[$key]);
}
usort($array, "compare");
return $array;
}
And then I call the function as below:
$total_cips = multi_sort($total_cips, $key = 'cip');
Finally this one worked!
Anyways thanks We0 & Ankit
Here:
$select_applicant = "SELECT j.*, u.id, u.gender
FROM job_apply j
LEFT JOIN users u
ON u.id = j.user_id
WHERE j.job_id = '".$jid."";
You are missing closing quote for $jid. It should be:
$select_applicant = "SELECT j.*, u.id, u.gender
FROM job_apply j
LEFT JOIN users u
ON u.id = j.user_id
WHERE j.job_id = '".$jid."'";
This might be one of the cause of your problem.