Displaying a day of bookings for a room - php

i am working on a school room booking system but i am having some trouble outputting the bookings.
Public function displayRoomByDay() {
$query = DB::GetInstance()->query("SELECT B.roomid, B.period, R.roomname, B.bookingdate, B.bookingid FROM booking B INNER JOIN room R on b.roomid = r.roomid WHERE bookingdate = '2016-11-03' and b.roomid=1 ORDER BY b.period"); //Inner join
$count = $query->count();
$freeCount = 0;
for($periods=1;$periods<=6;$periods++) {
for($x=0;$x<$count-1;$x++) {
$outputted=false;
$freeCount=0;
do {
if($query->results()[$x]->period == $periods) {
echo $query->results()[$x]->period . '<br>';
$outputted=true;
} else {
echo 'FREE' . '<br>';
$freeCount = 1;
}
} while($outputted = false and $freeCount=0);
}
}
}
This is the function that i use to output my data. My SQL query returns two items, a booking in period 5 and a booking in period 1 (i have tested this through PHPMyAdmin). I am trying to use nested for loops and a do while loop to loop through the periods available in a day (6). From there i loop through the two bookings that my sql query returns which is this code:
for($x=0;$x<$count-1;$x++) {
$outputted=false;
$freeCount=0;
do {
if($query->results()[$x]->period == $periods) {
echo $query->results()[$x]->period . '<br>';
$outputted=true;
} else {
echo 'FREE' . '<br>';
$freeCount = 1;
}
} while($outputted = false and $freeCount=0);
}
However when i run my page, i get 1 FREE FREE FREE FREE FREE, when i am trying to get 1 FREE FREE FREE FREE 5 as they are when the bookings are.

Your logic is very complicated for this task. You can simplify it like:
public function displayRoomByDay()
{
$query = DB::GetInstance()->query("
SELECT B.roomid,
B.period,
R.roomname,
B.bookingdate,
B.bookingid
FROM booking B
INNER JOIN room R
ON b.roomid = r.roomid
WHERE bookingdate = '2016-11-03'
AND b.roomid=1 ORDER BY b.period"); //Inner join
$results = array_reduce($query->results(), function ($carry, $item) {
$carry[$item->period] = $item;
return $carry;
}, []);
$periods = range(1, 6);
foreach ($periods as $period) {
if (isset($results[$period]) {
echo $period . '<br />';
} else {
echo 'FREE' . '<br />';
}
}
}
I think that's all you need.

Related

mySQL report php problems

I am havin trouble with mySQL reports.
What I have:
My report now
What I need:My future report
I need to get total price of group for example screen size with 12.5', then total price of screens with their size 13.3' and so on...
I tried this:
public function getGroupPrice($priceFrom, $priceTo) {
$whereClauseString = "";
if(!empty($priceFrom)) {
$whereClauseString .= " WHERE `{$this->pc_table}`.`price`>='{$priceFrom}'";
if(!empty($priceTo)) {
$whereClauseString .= " AND `{$this->pc_table}`.`price`<='{$priceTo}'";
}
} else {
if(!empty($priceTo)) {
$whereClauseString .= " WHERE `{$this->pc_table}`.`price`<='{$priceTo}'";
}
}
$query = " SELECT `{$this->screen_table}`.`size`,
sum(`{$this->pc_table}`.`price`) AS `total_price`
FROM `{$this->pc_table}`
INNER JOIN `{$this->screen_table}`
ON `{$this->pc_table}`.`fk_Screenid_Screen`=`{$this->screen_table}`.`id_Screen`
GROUP BY `{$this->screen_table}`.`size`";
$data = mysql::select($query);
return $data;
}
And I get some nonsense data. What could I be doing wrong?

php code to search multiple words in varchar

From my application, I send a list of users that I want to search the group they are subscribed:
$selectedUsers = ["John", "Carlos", "Anna", "Julia"]
I have in my database many different groups with many different users in
each of them:
$football = ["**John**" ,"**Carlos**" ,"Daniel" ,"Rob" ,"Frank" ,"Bob"]
$cooking = ["**John**" , "**Anna**" , "**Julia**" , "Claudia" , "Rob" , "Adriana"]
$startups = ["**John**", "**Carlos**", "**Anna**", "**Julia**", "Rob", "Adriana"]
The output I want to have is the sorted list of groups with the amount of the selectedUsers in it:
$returnArray[0] = $startups //4 users inside group
$returnArray[1] = $cooking //3 users inside group
$returnArray[2] = $football //2 users inside group
Here is the code I have so far, but the loop I'm using is based on the group_id I've stored and I want to change that:
<?php
//fetch groups with users
$returnValue = array();
$groupUsersNumber = 0;
$selectedUsers = htmlentities($_REQUEST["selectedUsers"]);
$lastGroupID = htmlentities($_REQUEST["lastGroupID"]); //remove
if($lastGroupID == ""){
$lastGroupID = getLastGroupID();
$lastGroupID = $lastGroupID + 1;
}
if($selectedUsers == ""){
//return all groups ordered by ID desc
$group = getGroupWithID($lastGroupID);
} else{
$usersArray = explode(', ', $selectedUsers);
$foundGroup = false;
while($foundGroup == false){
$group = getGroupWithID($lastGroupID);
$fetchedGroupUsers = explode(', ', $group["users"]);
for($i = 0; $i < count($usersArray); $i++){
if(in_array($usersArray[$i], $fetchedGroupUsers)){
$foundGroup = true;
break;
} else{
$lastGroupID = $group["group_id"];
}
}
}
}
for($i = 0; $i < count($usersArray); $i++){
if(in_array($usersArray[$i], $fetchedGroupUsers)){
$groupUsersNumber = $groupUsersNumber + 1;
}
}
if(empty($group))
{
$returnValue["status"]="403";
$returnValue["message"]="No more groups with that users.";
echo json_encode($returnValue);
return;
} else{
$returnValue=$group;
$returnValue["groupUsersNumber"]=$groupUsersNumber;
}
echo json_encode($returnValue);
?>
Is there any other way to have a better/ more efficient way to search into my database? Appreciated!
It seems that your database is not normalized. A normalized database may be the more efficient way. Do not store users in a describing varchar. Instead establish a many to many relation.
Beside that the FilterIterator class of PHP is something for you. It is reusable and a bit more efficient at iterating over arrays.
Here 's a short example.
class NameFilterIterator extends FilterIterator {
protected $filter = null;
public function __construct(Iterator $iterator, $filter) {
parent::__construct($iterator);
$this->filter = $filter;
}
public function accept() {
$current = $this->getInnerIterator()->current();
if (strpos($current, $this->filter) !== false) {
return true;
}
return false;
}
}
// Usage
$aUsers = [ 'John', 'Carlos', 'Anna', 'Julia' ];
$oFootball = new ArrayIterator(["**John**" ,"**Carlos**" ,"Daniel" ,"Rob" ,"Frank" ,"Bob"]);
foreach ($aUsers as $sUser) {
$oFilter = new NameFilterIterator($oFootball, $sUser);
foreach ($oFilter as $sName) {
var_dump($sName); // outputs: John, Carlos
}
}
The internal memory usage of the FilterIterator object is way more efficient.
You appear to be mixing up php and mysql, and it would be better to redesign your database.
However as a basic idea you can do roughly what you want in MySQL. It is not nice, and not efficient but something like this:-
SELECT a.group_description ,
GROUP_CONCAT(b.wanted_name)
FROM some_table a
LEFT OUTER JOIN
(
SELECT "John" AS wanted_name UNION SELECT "Carlos" UNION SELECT "Anna" UNION SELECT "Julia"
) b
ON FIND_IN_SET(b.wanted_name, a.group_users)
GROUP BY a. group_description

codeigniter mysql query output data display with specific condition

here are the following codes:
controller.php
function getchart() {
$prac = $this->input->post('prac_name');
$datee = $this->input->post('datee');
$this->load->model('appoint');
$results['appoint'] = $this->appoint->getappoint($prac , $datee);
$this->load->view('ajax/getappchart' , $results);
}
model.php
function getappoint($prac , $datee) {
$this->db->select('rdv.id as rdvid, startTime, endTime, day, firstname, lastname');
$this->db->from('rdv');
$this->db->join('contact', 'contact.id = rdv.contact_id');
$this->db->where('people_id',$practicien);
$this->db->where('DATE(day)', $datee);
$this->db->order_by('TIME(startTime)', 'ASC');
$query = $this->db->get();
//print_r($this->db->last_query());
return $query;
}
view.php
if ($appoint->num_rows() > 0) {
foreach($appoint->result() as $sub_row)
{
// display output.
}
} else {
echo 'No Appointments on Above Date.';
}
?>
what i need is, there are appointments with sametime and day(mostly 2 same).
if there is morethan 2, i need to set two different class style for both the appointment.
how can i achieve this ?
Thanks.
Final answer: done it with the help of #minhaz-ahmed
if ($appoint->num_rows() > 0) {
$appoint_counter = array();
foreach ($appoint->result() as $sub_row) {
//i am assuming your startTime is H:M:S, and day Y-M-D format
$key = strtotime($sub_row['day'] . ' ' . $sub_row['startTime']);
if (!isset($appoint_counter[$key])) {
$appoint_counter[$key] = 0;
}
$appoint_counter[$key] ++;
$style_class = 'YOUR_1ST_CLASS';
if ($appoint_counter[$key] > 2) {
$style_class = 'YOUR_2ND_CLASS';
}
//REST VIEW CODE
}
}
else {
echo 'No Appointments on Above Date.';
}
You can do like this
if ($appoint->num_rows() > 0) {
$appoint_counter = array();
foreach ($appoint->result() as $sub_row) {
//i am assuming your startTime is H:M:S, and day Y-M-D format
$key = strtotime($sub_row['day'] . ' ' . $sub_row['startTime']);
if (!isset($appoint_counter[$key])) {
$appoint_counter[$key] = 0;
}
$appoint_counter[$key] ++;
}
foreach ($appoint->result() as $sub_row) {
//i am assuming your startTime is H:M:S, and day Y-M-D format
$key = strtotime($sub_row['day'] . ' ' . $sub_row['startTime']);
$style_class = 'YOUR_1ST_CLASS';
if ($appoint_counter[$key] > 2) {
$style_class = 'YOUR_2ND_CLASS';
}
//YOUR REST VIEW
}
} else {
echo 'No Appointments on Above Date.';
}
What do you mean by class style? Anyway, the code below assumes you will put the results in a datagrid.
$prev_date = "";
$prev_time = "";
$results = $query->result();
foreach($results as $appointment) {
if ($prev_date != $appointment->day) // Assuming "day" is tables date
# Display output here
if ($prev_time != $appointment->startTime) // Logically, display should sort appointments by their starting time
# Display output here
# Display appointment rows here
$prev_date = $appointment->day;
$prev_time = $appointment->startTime;
}
if (empty($results)) {
# Display "no appointments found" output here
}

Echo return mulitiple variables

I have a problem with an mysql query, I need to extract all data from my table and use him as another sql query.
This is the code I am using:
<?php
function toateMhz() {
require ('SQL.php');
$sql = "SELECT DISTINCT(performanta_cpu) FROM modele ORDER BY CAST(performanta_cpu AS UNSIGNED) DESC";
foreach ($dbh->query($sql) as $linie)
{
$mhz[] = $linie['performanta_cpu'];
}
if(isset($mhz['1']))
{
$mhz1 = "$mhz[0] OR ";
}
else $mhz['0'];
if(isset($mhz['2']))
{
$mhz2 = "$mhz[1] OR ";
}
else $mhz['1'];
if(isset($mhz['3']))
{
$mhz3 = "$mhz[2] OR ";
}
else $mhz['2'];
if(isset($mhz['4']))
{
$mhz4 = "$mhz[3] OR ";
}
else $mhz['3'];
if(isset($mhz['5']))
{
$mhz5 = "$mhz[4] OR ";
}
else $mhz['4'];
if(isset($mhz['6']))
{
$mhz6 = "$mhz[5] OR ";
}
else $mhz['5'];
if(isset($mhz['7']))
{
$mhz7 = "$mhz[6] OR ";
}
else $mhz['6'];
if(isset($mhz['8']))
{
$mhz8 = "$mhz[7] OR ";
}
else $mhz['7'];
if(isset($mhz['9']))
{
$mhz9 = "$mhz[8] OR ";
}
else $mhz['8'];
if(isset($mhz['10']))
{
$mhz10 = "$mhz[9] OR ";
}
else $mhz['9'];
if(isset($mhz['11']))
{
$mhz11 = "$mhz[10] OR ";
}
else $mhz['10'];
if(isset($mhz['12']))
{
$mhz12 = "$mhz[11] OR ";
}
else $mhz['11'];
if(isset($mhz['13']))
{
$mhz13 = "$mhz[12] OR ";
}
else $mhz['12'];
if(isset($mhz['14']))
{
$mhz14 = "$mhz[13] OR ";
}
else $mhz['13'];
if(isset($mhz['15']))
{
$mhz14 = "$mhz[14] OR ";
}
else $mhz['14'];
$frecvente = "$mhz1 $mhz2 $mhz3 $mhz4 $mhz5 $mhz6 $mhz7 $mhz8 $mhz9 $mhz10 $mhz11 $mhz12 $mhz13 $mhz14";
return $frecvente;
}
echo toateMhz();
?>
And this is the result from code:
2000 OR 1600 OR 1500 OR 1400 OR 1000 OR 800 OR
But the correct result is 2000 OR 1600 OR 1500 OR 1400 OR 1000 OR 800 OR 200
Last word must not be OR
Not quite sure but this might do the trick
foreach ($dbh->query($sql) as $linie) {
// append value of this record to the array $mhz
$mhz[] = $linie['performanta_cpu'];
}
// return the concatenation of all elements in $mhz with ' OR ' as "glue" between elements
return join(' OR ', $mhz);
join($s, $arr) is an alias of implode($s, $arr) which concatenates all (string) elements of the given array $arr and putting $s "between" the elements. E.g.
$x = array('a','b', 'c');
echo join(' - ', $x);
prints a - b - c
Use implode to join your array values into a string :
function toateMhz() {
require ('SQL.php');
$sql = "SELECT DISTINCT(performanta_cpu) FROM modele ORDER BY CAST(performanta_cpu AS UNSIGNED) DESC";
foreach ($dbh->query($sql) as $linie)
{
$mhz[] = $linie['performanta_cpu'];
}
return implode(" OR ", $mzh);
}
echo toateMhz();

PHP while loop within a while loop works once

I have two queries sent to a database bring back posts (op_ideas 16 cols) followed by another which holds the votes per post (op_idea_vote cols 4) with matching idea_id's
Example of Data:
Query: op_ideas:
[{"idea_id":"2211","author_id":"100000", "date":"2012-09-06
10:02:28","idea_title":"Another test","4" etc etc
Query: op_idea_votes:
idea_id = 2211, agree=3, disagree=1, abstain=0
The code below ought to look at op_ideas, and then cycle over op_ideas_vote until it finds a match under 'idea_id'. Then it goes to the next record under op_ideas, and again using that idea_id search for it within the op_idea_vote list, find a match, and add it to the array.
This works for only the first record, not for the other three. I am testing, so I have 3 rows in each that match idea_id with different results in the op_idea_vote.
$votes = mysql_query($commentVotes);
$result = mysql_query($gl_query);
while ($gce_result = mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
while($allvotes= mysql_fetch_array($votes)) {
if($voteid = $allvotes['idea_id'])
{
//echo $voteid . " main idea and the votes: " . $allvotes;
$gce_result["agree"] = $allvotes['agree'];
$gce_result["disagree"] = $allvotes['disagree'];
$gce_result["abstain"] = $allvotes['obstain'];
}
else
{
$gce_result["agree"] = 0;
$gce_result["disagree"] = 0;
$gce_result["abstain"] = 0;
}
//print_r($gce_result);
}
$data_result[] = $gce_result;
}
echo json_encode($data_result);
If I use print_f(&gce_result) it works fine in phpfiddle. But when i use the code above, it works for the first record, but it's complete missing the second two. It seems to be missing the second while, as it does not even give me the 0 0 0 results.
Query for op_ideas:
$gl_query = "SELECT DISTINCT * FROM heroku_056eb661631f253.op_ideas INNER JOIN op_organs ORDER BY date ASC;";
if (!mysql_query($gl_query)) {
die('Error: ' . $gl_query . " " . mysql_error());
}
$result = mysql_query($gl_query);
Query For op_idea_vote :
$commentVotes = "SELECT v.idea_id, COUNT(v.agree = 1 or null) as agree, COUNT(v.disagree = 1 or null) as disagree, COUNT(v.obstain = 1 or null) as obstain FROM op_idea_vote v GROUP BY v.idea_id";
if (!mysql_query($commentVotes)) {
die('Error: ' . $commentVotes . " " . mysql_error());
}
$votes = mysql_query($commentVotes);
You can scan a resource only once.
So the inner while will be run only one time.
use == instead of = for checking condition of if & while
in the while loop ,you have to assign the value of $allvotes ,but you never assigned,
while ($gce_result == mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
while($allvotes== mysql_fetch_array($votes)) {
if($voteid == $allvotes['idea_id'])
{
//echo $voteid . " main idea and the votes: " . $allvotes;
$gce_result["agree"] = $allvotes['agree'];
$gce_result["disagree"] = $allvotes['disagree'];
$gce_result["abstain"] = $allvotes['obstain'];
}
else
{
$gce_result["agree"] = 0;
$gce_result["disagree"] = 0;
$gce_result["abstain"] = 0;
}
$data_result[] = $gce_result;
}
}
Your problem is trying to scan over the $votes result more than once.
You should store the result of that query first.
Eg.
while ($vote = mysql_fetch_array($votes)) {
$allvotes['idea_id'] = $vote;
}
while ($gce_result = mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
if (array_key_exists[$voteid, $allvotes]) {
//assign results
} else {
//default
}
}
Another option would be to do the query with a join, so you can do everything in one query. Then just loop over that result.

Categories