Sixtens hemsida Uppgifter Blogg Om

VED House bokningssystem

Gå till sida

Källkod

api/

database.php

api.php

ved/

monthBookingData.php

openingHoursException.php

bookingData.php

dayTimeframes.php

bookings.php

admin/

revokeToken.php

authorization.php

login.php

modules/

vedDatabase.php

utility.php

gyar/

log.php

auth/

revokeToken.php

authorization.php

login.php

station/

settings.php

log.php

modules/

gyarDatabase.php

databaseConnection.php

database.php

utility.php

credentials.json

weather/

latest.php

old.php

admin/

index.html

changeTimetable.html

login.html

js/

login.js

modules.js

admin.js

header.js

changeTimetable.js

cron/

vedClearExpiredTokens.php

api/ved/bookings.php

1 lines
<?php
# bookings.php
# API endpoint
# Fil för att läsa av, lägga till och ta bort bokningar.

require_once "ved/modules/utility.php";

# Hämtar alla bokningar för den specifierade dagen.
$functionGET = function () {
    require 
"ved/modules/vedDatabase.php";

    
# Hämtar öppettiderna för dagen.
    
$params = array("date" => $_GET["date"]);
    
$dateData $db->query(
        
"SELECT
CONVERT(ROUND(TIME_TO_SEC((CASE WHEN e.exceptionId IS NULL THEN w.openingTime ELSE e.openingTime END))/60), SIGNED) openingTimeMinutes,
CONVERT(ROUND(TIME_TO_SEC((CASE WHEN e.exceptionId IS NULL THEN w.closingTime ELSE e.closingTime END))/60), SIGNED) closingTimeMinutes
FROM weekdayOpenHours w
LEFT JOIN openHoursException e
ON :date >= e.date1 AND :date <= e.date2
WHERE w.weekdayId = WEEKDAY(:date)"
,
        
$params
    
);

    
# Hämtar bokningarna.
    
$bookings $db->queryAll(
        
"SELECT *, ROUND(TIME_TO_SEC(b.datetime)/60) timeMinutes FROM booking b WHERE datetime BETWEEN :date AND ADDDATE(:date, 1) AND NOT removed;",
        
$params
    
);
    
$data $dateData;
    
$data["bookings"] = $bookings;
    return 
$data;
};

# Funktion som kontrollerar POST-metodens parametrar.
# Formatterar även några parametrar som returnas i slutet.
function check_request_POST()
{
    
# Kontrollera namnet.
    
$nameLength strlen($_POST["name"]);
    if (
$nameLength == || $nameLength 32)
        throw new 
APIParameterError(400"name""Length must be between 1 and 32 characters.");

    
# Kontrollera telefonnumret.
    
$cleanPhoneNumber preg_replace("/[-\s]+/"""$_POST["phoneNumber"]);
    if (!
preg_match("/^[0-9]{9,10}$/"$cleanPhoneNumber))
        throw new 
APIParameterError(400"phoneNumber""Invalid format.");
    
$_POST["phoneNumber"] = $cleanPhoneNumber;

    
# Kontrollerar antalet personer.
    
if (!is_int($_POST["adultCount"]) || $_POST["adultCount"] < 0)
        throw new 
APIParameterError(400"adultCount""Parameter must be a positive integer.");
    if (!
is_int(value$_POST["childCount"]) || $_POST["childCount"] < 0)
        throw new 
APIParameterError(400"childCount""Parameter must be a positive integer.");
    if (
$_POST["adultCount"] + $_POST["childCount"] <= 0)
        throw new 
APIParameterError(400, array("adultCount""childCount"), "Both parameters cannot be 0.");

    
# Kontrollerar datumet.
    
try {
        
$date = new DateTime($_POST["datetime"]);
    } catch (
DateMalformedStringException) {
        throw new 
APIParameterError(400"datetime""Invalid date.");
    }
    
$tomorrow = new DateTime();
    
$tomorrow->setTime(00);
    
$tomorrow->add(new DateInterval("P1D"));
    
$diff $tomorrow->diff($date);
    if (
$diff->invert)
        throw new 
APIParameterError(400"datetime""Booking cannot be placed earlier than tomorrow.");

    return array(
"date" => $date"cleanPhoneNumber" => $cleanPhoneNumber);
}

# Lägger till en bokning i systemet.
$functionPOST = function () {
    
$formatted check_request_POST();
    
$date $formatted["date"];
    
$phoneNumber $formatted["cleanPhoneNumber"];

    require_once 
"ved/modules/vedDatabase.php";

    
# Hämtar öppettiderna för dagen.
    
$dateString $date->format("Y-m-d");
    
$dateData $db->query(
        
"SELECT
ROUND(TIME_TO_SEC((CASE WHEN e.exceptionId IS NULL THEN w.openingTime ELSE e.openingTime END))/60) openingTimeMinutes,
ROUND(TIME_TO_SEC(TIMEDIFF((CASE WHEN e.exceptionId IS NULL THEN w.closingTime ELSE e.closingTime END), (CASE WHEN e.exceptionId IS NULL THEN w.openingTime ELSE e.openingTime END)))/60) AS minutesOpen
FROM weekdayOpenHours w
LEFT JOIN openHoursException e
ON :date >= e.date1 AND :date <= e.date2
WHERE w.weekdayId = WEEKDAY(:date)"
,
        array(
"date" => $dateString)
    );

    
# Kollar om dagen är öppen.
    
if (!isset($dateData["minutesOpen"]))
        throw new 
APIParameterError(400"datetime""Restaurant is closed at the specified date.");

    
# Här kontrolleras att bokningen passar in i tidsramarna, och att det inte är fullbokat.
    
$bookings $db->queryAll(
        
"SELECT ROUND(TIME_TO_SEC(b.datetime)/60) timeMinutes, b.adultCount + b.childCount peopleCount FROM booking b WHERE datetime BETWEEN :date AND ADDDATE(:date, 1) AND NOT removed;",
        array(
"date" => $dateString)
    );
    
$settings $db->query("SELECT seatCount, bookingInterval, bookingLength FROM restaurantSettings;");

    
# Delar upp dagen i tidsramar. Varje tidsram lagrar antalet platser som används.
    
$timeframes create_time_frames($dateData$bookings$settings);
    
# Kollar framåt för varje tidsram och beräknar max hur många platser finns tillgängliga en hel bokningslängd framåt.
    
$bookableFrames create_bookable_time_frames($dateData$timeframes$settings);

    
$timeString $date->format("H:i");
    if (!isset(
$bookableFrames[$timeString])) # Kollar ifall den passar in.
        
throw new APIParameterError(400"datetime""The specified time does not fit into the bookings list.");
    if (
$bookableFrames[$timeString] < $_POST["adultCount"] + $_POST["childCount"]) # Kollar ifall det inte är fullbokat.
        
throw new APIError(409"The restaurant is fully booked at the specified time.");

    
# Lägger till en bokning.
    
$_POST["phoneNumber"] = $phoneNumber;
    
$db->query("INSERT INTO booking(name, phoneNumber, adultCount, childCount, datetime, bookedAt) VALUES (:name, :phoneNumber, :adultCount, :childCount, :datetime, NOW())"$_POST);
    
http_response_code(201);
    
$data = array("message" => "Your booking was successful.");
    return 
$data;
};

# Tar bort en bokning. Bokningen tas inte faktiskt bort, utan removed-flaggan sätts till 1.
$functionDELETE = function () {
    require 
"ved/modules/vedDatabase.php";
    
$db->query("UPDATE booking SET removed=1 WHERE bookingId=:bookingId;", array("bookingId" => $_POST["bookingId"]));
    
$data = array("message" => "Booking was successfully removed.");
    return 
$data;
};

$api = new APIEndpoint();
$auth = require_once "ved/admin/authorization.php";

$httpGET = new APIMethod("GET"$functionGET);
$httpGET->setAuthorization($auth);
$httpGET->setRequiredGETParameters(array("date"));
$api->addMethod($httpGET);

$httpPOST = new APIMethod("POST"$functionPOST);
$httpPOST->setRequiredBodyParameters(array("datetime""name""phoneNumber""adultCount""childCount"));
$api->addMethod($httpPOST);

$httpDELETE = new APIMethod("DELETE"$functionDELETE);
$httpDELETE->setAuthorization($auth);
$httpDELETE->setRequiredBodyParameters(array("bookingId"));
$api->addMethod($httpDELETE);

return 
$api;
?>