I have a MySql Database with peoples' names as varchars and appointment times as DateTime objects. I need to make a function that returns the next available time slot (DateTime format) found in the database, I'll use it to schedule people for that time slot.
Appointments are only on Tuesdays and Wednesdays. Whether it's Tuesday or Wednesday, 4 people can be seen at 9:00am, and 2 people can be seen at 10:30am.
This function returns the number of people that are booked for a given time slot (DateTime).
function getTimeSlotCount($dateTime)
{
// finds out how many people are scheduled for the given datetime
global $db;
$query = "SELECT * FROM appointments
WHERE AppointmentTime = :dateTime
ORDER BY AppointmentTime";
$statement = $db->prepare($query);
$statement->bindValue(':dateTime', $dateTime);
$statement->execute();
$count = $statement->rowCount();
$statement->closeCursor();
#var_dump($count);
return $count;
}
I plan to use a do while loop to iterate through timeslots. But I don't know how to iterate through appointment times that I mentioned using DateTime. Also how to compare the time portion of a datetime to a specific time of day?
function getNextAvailableTimeSlot()
{
$maxFor9am = 4;
$maxFor1030am = 2;
$isAvailableSlotFound = false;
do {
// How Do I: Assign next Timeslot to $AppointmentTime;
$numBooked = getTimeSlotCount($AppointmentTime)
if ($numBooked >= $maxFor9am && $HowdoIGetTimeFromAppointmentTime == 9am)
continue;
else if ($numBooked >= 2 && $HowdoIGetTimeFromAppointmentTime == 1030am)
continue;
else
$isAvailableSlotFound == true;
} while ($isAvailableSlotFound == false);
return $AppointmentTime;
}
EDIT: When an appointment is added to the database table. The person's name and a DateTime is entered for the record of the appointment.
Related
I am trying to sort an array of activities based on their dates. For example:
"Do stuff" 2020-06-06
"Do more stuff" 2020-06-06
"Do even more" 2020-06-07
I now want to place these dates into a new array specifically for one date so an array for 2020-06-06 and an array for 2020-06-07 but the dates differ everytime so there it is no possible to make predifined arrays.
activityArray = CMS_GetActivity("1");
$activityList = array();
foreach ($activityArray as $tempActivity) {
array_push($activityList, $tempActivity);
}
$_SESSION['days'] = $activityList;
This is where i am now but I'm nowhere near where I wanted to be.
function GetActivity2(){
//get all activities from the database belonging to the volunteer
$activityArray = CMS_GetActivity("1");
//make an array for all the days
$dayList = array();
//foreach activity from the database
foreach ($activityArray as $tempActivity){
//set a success meter on fail.
//this success meter is set to success if the activity can be sorted in a day,
//if the activivty can not be classified, the success stays on fail a new day is made.
$sucessBool = false;
//for every day in the daylist
for ($i=0; $i < count($dayList); $i++) {
//if the day is not empty
if($dayList[$i] != NULL){
//grab one activity from the daylist
foreach ($dayList[$i] as $key) {
//if the date corresponds with the date from the activity gotten from the database
if (date("m-d-Y",strtotime($key->Time)) == date("m-d-Y",strtotime($tempActivity->Time))){
//place the activity in that day
array_push($dayList[$i], $tempActivity);
//and set the success meter on success
$sucessBool = true;
//break out of the loop so only one activity of the day has to be checked
break;
}
//break out of the loop to check for days
break;
}
}
}
//check if the success meter is on Fail
if($sucessBool == false){
//empty an array
$activityList = array();
//put the activity in the activitylist
array_push($activityList, $tempActivity);
//put the activitylist in the daylist
array_push($dayList, $activityList);
}
}
$_SESSION['days'] = $dayList;
}
This is my completed code, it is probably not the cleanest code but i'm fine with that.
I have a database which holds two timestamps (date_ticket_reported, date_ticket_resolved), I want to caluclate the average time difference between these times for each resolved_by user_id.
Each row has a (resolved_by) column which corresponds to a user_id.
There will be multiple rows, for each user_id.
I have tried various approaches including the following.
ticket_model.php code
public function get_resolved_time_by_user($user_id){
$query1 = $this->db->select('resolved_date')->from('tickets')->where('resolved_by',$user_id)->get();
$resolved1 = $query1->row();
$query2 = $this->db->select('ticket_date_reported')->from('tickets')->where('resolved_by',$user_id)->get();
$reported1 = $query2->row();
$resolved2 = $resolved1->resolved_date;
$reported2 = $reported1->ticket_date_reported;
foreach($resolved2 as $row){
//Convert them to timestamps
$reported_dateTimestamp = strtotime($resolved2);
$resolved_dateTimestamp = strtotime($reported2);
$diff = $resolved_dateTimestamp - $reported_dateTimestamp;
return $diff;
}
}
Ticket view code
<p> Average Resolve Times <?php echo $this->ticket_model->get_resolved_time_by_user($user_id); ?> </p>
So to summarise; I want to display the average time between date_ticket_reported, date_ticket_resolved. For each user_id specified.
Any help would be awesome!
I have tried Malkhazi Dartsmelidze answer,
$this->db->query("SELECT
AVG(TIMESTAMPDIFF(SECOND, resolved_date, ticket_date_reported)) as timediff,
resolved_by as user
FROM tickets
GROUP BY resolved_by");
I get an error saying Object of class CI_DB_mysqli_result could not be converted to string
Where you say resolved_by as user. Should "user" be the user_id? ie should it say "resolved_by as user_id"?
You Can run only One Query With Myqsl:
SELECT
AVG(TIMESTAMPDIFF(SECOND, resolved_date, ticket_date_reported)) as timediff,
resolved_by as user
FROM tickets
GROUP BY resolved_by
This returns Average Time Difference in Seconds for Each User
Try this
$resolved2 = $resolved1->resolved_date;
$reported2 = $reported1->ticket_date_reported;
$diff = $resolved2 - $reported;
And then echo $diff and check what you are getting in $diff,
I have developed a search page, which is only accessible to logged in users. But I want to limit search for each user to only 20 times in one week. One user will not be able to search for more than 20 times. Please help me how can I achieve this.
Implement two colums in the users table:
column 1 : search_counts -default 0
coumn 2 : search_timestamp -default 0
when a user initiate a search:
inspect the timmstap, if it is older than one week set it to current time (now) and set the counter to one and allow the search , if not, check the counter if its equal maximum allowed searches then abort it otherwise increment the counter and allow the search.
Here is an untested function to do this assuming you pass the couner and timstamp values from the user table to it:
function search_check($counter,$ts,$max=20,$period =7) {
$p = $period * 24 * 60 * 60;
$now = time();
if(($now - $ts) >= $p ){
//set the time stamp to now in DB
//set the counter to 1 in DB
return true;
}else {
if($counter < $max){ //
//increment the counter by 1 in DB
return true;
}else{
return false;
}
}
}
usage:
//retrieve counter and timestamp values from the DB users table
$can_search = search_check($counter,$ts);
if($can_search){
//search and return search result
}else{
echo "Sorry, maximum weekly searches reached"
}
I have a reservation module in codeigniter wherein I limit users to reserve the clubhouse for only 2 hours a day. I am currently creating a validation in codeigniter to limit their reservation. What I did was to select all the reservations, and group them by the rows having the same date in order to properly limit them. The problem is that the model I created is only returning 1 row, and not all the results. This means that my counter is just being changed by only one row, which I expect that all rows should affect the counter.
Below is my database table:
Basically, the second row isn't supposed to be inserted in the database because user '20130123' already has used up his maximum reservation for the day which is two hours. I provided the validation check below on checking whether the user has used up two hours of reservation, and my logic here is that I just subtract the reservation end with the reservation start. Using the table above just as an example and for my explanation, my problem is that in my model, the counter's value becomes only "2" because it only reads the first row (8 - 6 = 2), instead of "3" (result of the first row which is 2, then add the result of second row which is 1 : [(8-6) + (9-8)])
To sum it up, my problem lies on the counter's value, because it is only being added by the first row the query reads.
Here's my code.
Model:
function check_twohours_clubhouse()
{
$query = $this->db->select('*')->from('clubhouse_reservation')->where('username', $this->session->userdata('username'))->group_by('reservation_date')->having('count(reservation_date) > 1')->get();
$result = $query->result();
if($query->num_rows() > 0)
{
$ctr = '0';
foreach($result as $row)
{
$totalhour = $row->reservation_end - $row->reservation_start; // subtract reservation start to reservation end to get the number of hours
$ctr = $ctr + $totalhour;
}
$ctr = $ctr + ($this->input->post('reserveend') - $this->input->post('reservestart')); // add the selected "add reservation" hours to the counter
if($ctr > 2) // counter > 2 hours limit
{
return FALSE;
}
else
{
return TRUE;
}
}
else
{
return TRUE;
}
}
Controller:
function create_reservation_clubhouse()
{
$this->form_validation->set_error_delimiters('<div class="error">','</div>');
$this->form_validation->set_rules('datepick', 'Date', 'required|no_olddate');
$this->form_validation->set_rules('reservestart', 'Reservation Start', 'required|hourselection|unique_reserve_clubhouse|max_twohours');
if ($this->form_validation->run() == FALSE)
{
$this->template->load('user_template', 'view_userreservation_addclubhouse');
}
else
{
if($this->model_reservation_user->check_twohours_courtone())
{
if($query = $this->model_reservation_user->create_reservation_clubhouse())
{
$this->session->set_flashdata('reservefeedback', 'You have successfully reserved a date for the Clubhouse. Please wait for the administrators to accept your reservation.');
redirect('user_reservation/clubhouse');
}
}
else
{
$this->session->set_flashdata('reservefail', 'You cannot reserve more than two hours of Clubhouse per day.');
redirect('user_reservation/clubhouse');
}
}
}
You can calculate all this in sql using time_to_sec() and timediff() functions:
select reservation_date, sum(time_to_sec(timediff(reserveend, reservestart)) / 3600 as reserved_hours
from clubhouse_reservation
where username =...
group by reservation_date
having count(*)>1 --although it is not clear to me why you have this restriction
The above query would sum up for a given user per reservation date, the hours for which the clubhouse is reserved (3600 = number of secs in an hour).
In your php code you only need to check if the reserved_hours in the resultset is >2 or not.
I'm not really an expert with CI, therefore I can't really tell how to convert the above sql to CI. But I'm afraid that you have to use raw sql because of the way it sums the time.
Hi buddies :) I was required to create a php code to handle some workers' data stored in DB. I got the desired result but it takes seconds and seconds (seconds and seconds! >.<) to finish, so I'm afraid I'm not doing something in a right way :(
The workers' data is stored in a mysql table (table1), something like this:
I'm given a pair of dates: initial_date (a) and final_date (b), so my goal is to copy the given workers' data in a new table (table2), day by day from a to b. The expected table should be as shown below (this table will be used later as a basis for further operations, which is not part of the question)
It's a requirement to overwrite any existing data between a and b dates, and 'jump' weekends and holidays.
To get my goal, I'm coding this (let's assume that the connection and all that is done and the checkworkingday function is given):
$initialdate = '2016-10-10';
$finaldate = '2016-10-12';
$x = $initialdate;
do {
if (checkworkingday($x) == true) {
$query = mysqli_query($connection,"SELECT name,task FROM table1");
while($row = mysqli_fetch_array($query)) {
$task = $row['task'];
$worker = $row['name'];
$query2 = mysqli_query($connection,"SELECT task FROM table2 WHERE name = '$worker' AND date = '$x'");
$row2 = mysqli_fetch_array($query2);
$existingtask = $row2['task'];
if (!isset($existingtask)) {
mysqli_query($connection,"INSERT INTO table2 (date,name,task) VALUES('".$x."','".$worker."','".$task."')");
} else {
mysqli_query($connection,"UPDATE table2 SET task = '".$task."' WHERE date = '".$x."' AND worker = '".$name."'");
}
}
}
$x = date('Y-m-d', strtotime($x . "+1 day"));
} while ($x <= $finaldate);
Just for 3 days as shown in the example, it takes a long to end; and for several weeks or months it takes very, very long (even max execution time is exceeded depending on dates range!).
I'm a newbie and I know the code is quite 'rustic', but I've revised and checked the code and info out there without getting a better performance. What am I doing wrong? Thanks :)
Instead of looping through the enitre data, try INSERT.. SELECT :
INSERT INTO table2 (date,name,task)
SELECT date,name,task
FROM Table1
WHERE < >;