commit 5608e5fe322f05e1379fa457ee9b463c9b453ae6
parent c220652b75a698e3dc5ac80a017455035d6a8131
Author: Gerco van Woudenbergh <[email protected]>
Date: Wed, 28 Jun 2023 15:32:18 +0200
basic api
Diffstat:
12 files changed, 611 insertions(+), 20 deletions(-)
diff --git a/Model/Contract.php b/Model/Contract.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Model {
+ class Contract extends \Lollipop\DatabaseObject
+ {
+ public static function get_table(): string
+ {
+ return "contract";
+ }
+
+ public static function get_primary(): string
+ {
+ return "contract_id";
+ }
+ public static function get_schema(): string
+ {
+ return "wap2";
+ }
+ }
+}
+\ No newline at end of file
diff --git a/Model/ContractStation.php b/Model/ContractStation.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Model {
+ class ContractStation extends \Lollipop\DatabaseObject
+ {
+ public static function get_table(): string
+ {
+ return "contract_station";
+ }
+
+ public static function get_primary(): string
+ {
+ return "contract_id";
+ }
+ public static function get_schema(): string
+ {
+ return "wap2";
+ }
+ }
+}
+\ No newline at end of file
diff --git a/Model/Key.php b/Model/Key.php
@@ -0,0 +1,243 @@
+<?php
+class Key
+{
+
+ protected array $data;
+ function retrieveData($key)
+ {
+ $validKeys = [
+ ':3jvl7yb5sRr80s6lTdeOyxV9VTQZkCPRp7bKOWKFWxfL2vhsU4Hhpgcmz9qe0zEk' => 'retrieveZooData',
+ ':ae9c50dc5cd58c538a0d6aedb17fffedcaffd568d22381dab3ae72baaeb24684' => 'retrieveRBData',
+ ];
+ if (array_key_exists($key['data'], $validKeys)) {
+ $method = $validKeys[$key['data']];
+ $this->$method($key);
+ } else {
+ echo "You have no access here!";
+ }
+ }
+
+ function retrieveZooData($key)
+ {
+ $db = new mysqli("86.92.67.21", "friedel", "hailiwa", "wap2");
+ $weather_data = [];
+ $query = "SELECT distinct temperature, wind_speed, nl.name as city, co.country as country
+ FROM weather_data wd
+ JOIN station s ON wd.station_name = s.name
+ JOIN contract_station cs ON cs.station_name = s.name
+ JOIN nearestlocation nl ON nl.station_name = s.name
+ JOIN country co ON co.country_code = nl.country_code
+ JOIN geolocation geo ON geo.country_code = co.country_code
+ JOIN contract c ON cs.contract_id = c.contract_id
+ WHERE c.token = '3jvl/yb?sRr80s6lTdeOyxV9VTQZkCPRp/bKOWKFWxfL2vhsU4Hhpgcmz9qe0zEk'
+ AND date(wd.date_time) = date(curdate())
+ GROUP BY nl.name
+ ";
+
+ $stmt = mysqli_prepare($db, $query);
+ $stmt->execute();
+ $data = $stmt->get_result();
+
+ while ($row = $data->fetch_assoc()) {
+ $wind_chill = windchill($row["temperature"], $row["wind_speed"]);
+ $weather_data[] = [
+ 'windchill' => $wind_chill,
+ 'location' => $row['city'],
+ 'country' => $row['country']
+ ];
+ }
+ header('Content-Type: application/json');
+ echo json_encode($weather_data);
+ }
+
+ function retrieveRBData($key)
+ {
+ $db = new mysqli("86.92.67.21", "friedel", "hailiwa", "wap2");
+ $weather_data = [];
+ $query = "SELECT distinct temperature, dew_point, nl.name as city, date_time
+ FROM weather_data wd
+ JOIN station s ON wd.station_name = s.name
+ JOIN contract_station cs ON cs.station_name = s.name
+ JOIN nearestlocation nl ON nl.station_name = s.name
+ JOIN country co ON co.country_code = nl.country_code
+ JOIN geolocation geo ON geo.country_code = co.country_code
+ JOIN contract c ON cs.contract_id = c.contract_id
+ WHERE c.token = 'ae9c50dc5cd58c538a0d6aedb17fffedcaffd568d22381dab3ae72baaeb24684'
+ ";
+ $stmt = mysqli_prepare($db, $query);
+ $stmt->execute();
+ $data = $stmt->get_result();
+
+ while ($row = $data->fetch_assoc()) {
+ $humidity = humid($row["temperature"], $row["dew_point"]);
+ $weather_data[] = [
+ 'humidity' => $humidity,
+ 'location' => $row['city'],
+ 'datetime' => $row['date_time']
+ ];
+
+ }
+
+ header('Content-Type: application/json');
+ echo json_encode($weather_data);
+ }
+
+
+ function retrieveHumidityTable($key, $generateXml = false)
+ {
+ $html = '<table>';
+ $db = new mysqli("86.92.67.21", "friedel", "hailiwa", "wap2");
+ $query = "SELECT distinct temperature, dew_point, nl.name as city, date_time
+ FROM weather_data wd
+ JOIN station s ON wd.station_name = s.name
+ JOIN contract_station cs ON cs.station_name = s.name
+ JOIN nearestlocation nl ON nl.station_name = s.name
+ JOIN country co ON co.country_code = nl.country_code
+ JOIN geolocation geo ON geo.country_code = co.country_code
+ JOIN contract c ON cs.contract_id = c.contract_id
+ WHERE c.token = ?
+ ORDER BY date_time DESC";
+ $stmt = mysqli_prepare($db, $query);
+ $stmt->bind_param("s", $key);
+ $stmt->execute();
+ $data = $stmt->get_result();
+
+ $results = array();
+
+ $table1 = '<tr><th id="tabledate" colspan="4">Chengdu Humidity Data</th></tr>';
+ $table1 .= '<tr><th>Date</th><th>Humidity</th></tr>';
+ $table2 = '<tr><th id="tabledate" colspan="4">Kangding Humidity Data</th></tr>';
+ $table2 .= '<tr><th>Date</th><th>Humidity</th></tr>';
+ $xml1 = '<location name="Chengdu">';
+ $xml2 = '<location name="Kangding">';
+ while ($row = $data->fetch_assoc()) {
+ $humidity = humid($row["temperature"], $row["dew_point"]);
+ $current_date = $row['date_time'];
+ $correct_date = date("d M Y H:i:s", strtotime($current_date));
+ $city = $row['city'];
+
+ $results[$city] = array();
+
+ $results[$city][] = array(
+ 'date' => $correct_date,
+ 'humidity' => $humidity
+ );
+
+ // Table and Generate XML
+ if ($city == 'Chengdu') {
+ $table1 .= '<tr><td>' . $correct_date . '</td><td>' . $humidity . '</td></tr>';
+ $xml1 .= '<data>' . '<date>' . $correct_date . '</date><humidity>' . $humidity . '</humidity>' . '</data>';
+ } else {
+ $table2 .= '<tr><td>' . $correct_date . '</td><td>' . $humidity . '</td></tr>';
+ $xml2 .= '<data>' . '<date>' . $correct_date . '</date><humidity>' . $humidity . '</humidity>' . '</data>';
+ }
+ }
+ $xml1 .= '</location>';
+ $xml2 .= '</location>';
+ $xml = $xml1 . $xml2;
+ $html .= $table1 . $table2;
+ if ($generateXml) {
+ return $xml; // Return SimpleXMLElement object
+ }
+ return $html;
+ }
+
+
+ function retrieveHData($key, $generateXml = false)
+ {
+ $html = '';
+ $citycity = '';
+ $db = new mysqli("86.92.67.21", "friedel", "hailiwa", "wap2");
+ $query = "SELECT distinct temperature, wind_speed, dew_point, DATE(date_time) AS date, nl.name as city
+ FROM weather_data wd
+ JOIN station s ON wd.station_name = s.name
+ JOIN contract_station cs ON cs.station_name = s.name
+ JOIN nearestlocation nl ON nl.station_name = s.name
+ JOIN country co ON co.country_code = nl.country_code
+ JOIN geolocation geo ON geo.country_code = co.country_code
+ JOIN contract c ON cs.contract_id = c.contract_id
+ WHERE c.token = ?
+ ORDER BY date DESC, temperature, wind_speed
+ ";
+
+ $stmt = mysqli_prepare($db, $query);
+ $stmt->bind_param("s", $key);
+ $stmt->execute();
+ $data = $stmt->get_result();
+ $xml = '<WCTPD name="Windchill corrected temperature per day">';
+
+ $results = array();
+ $locations = array();
+
+ while ($row = $data->fetch_assoc()) {
+ $wind_chill = windchill($row["temperature"], $row["wind_speed"]);
+ $current_date = $row['date'];
+ $city = $row['city'];
+
+ if (!isset($results[$current_date])) {
+ $results[$current_date] = array();
+ $locations[$current_date] = array();
+ }
+
+ if (!in_array($city, $locations[$current_date]) && count($results[$current_date]) < 5) {
+ $results[$current_date][] = array(
+ 'city' => $city,
+ 'windchill' => $wind_chill,
+ );
+
+ $locations[$current_date][] = $city;
+ }
+ }
+ $html .= $this->retrieveHumidityTable('ae9c50dc5cd58c538a0d6aedb17fffedcaffd568d22381dab3ae72baaeb24684');
+
+ $html .= '<table id="htmlTable">';
+ $html .= '<div class="space"></div>';
+ $html .= '<div class="content-title"><h2>Windchill corrected temperature per day</h2></div>';
+
+ foreach ($results as $date => $entries) {
+ $html .= '<tr><th id="tabledate" colspan="4">' . date("d M Y", strtotime($date)) . '</th></tr>';
+ $html .= '<tr><th>Location</th><th>Windchill</th></tr>';
+
+ foreach ($entries as $entry) {
+ $xml .= '<data city="' . $entry['city'] . '">' . '<wind_chill>' . $entry['windchill'] . '</wind_chill>' . '</data>';
+ $html .= '<tr>';
+ $html .= '<td>' . $entry['city'] . '</td>';
+ $html .= '<td>' . $entry['windchill'] . '</td>';
+ $html .= '</tr>';
+ }
+ }
+
+ $html .= '</table>';
+ $html .= '<a href="?downloadXml=true" class="download-button">Download XML</a>';
+ $xml .= '</WCTPD>';
+ if ($generateXml) {
+ return $xml; // Return SimpleXMLElement object
+ }
+ return $html;
+ }
+}
+
+function windchill($temp, $wind): float
+{
+ $result = 13.12 + 0.6215 * $temp - 11.37 * pow($wind, 0.16) + 0.3965 * $temp * pow($wind, 0.16);
+ return round($result, 2);
+}
+
+function humid($temp, $dewp): float|int
+{
+ $specific_humidity = exp((17.625 * $dewp) / (243.04 + $dewp));
+ $saturation_point = exp((17.625 * $temp) / (243.04 + $temp));
+
+ return round(($specific_humidity / $saturation_point) * 100, 2);
+}
+
+function checkHumid($temp, $dewp): string
+{
+ $humidity = humid($temp, $dewp);
+ if ($humidity < 50) {
+ return "warning";
+ } else {
+ return "dontchu worry";
+ }
+}
+?>
+\ No newline at end of file
diff --git a/Model/Permission.php b/Model/Permission.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Model {
+ class Permission extends \Lollipop\DatabaseObject
+ {
+ public static function get_table(): string
+ {
+ return "permission";
+ }
+
+ public static function get_primary(): string
+ {
+ return "id";
+ }
+ public static function get_schema(): string
+ {
+ return "lollipop";
+ }
+ public function get_checkboxes(): array
+ {
+ $all_permissions = $this->db->all($this::class);
+ $html = "<div class='check_this_box'>";
+ foreach($all_permissions as $permission) {
+ $html .= '<input type="checkbox" id="'. $permission->name .'" name="permissions[]" value="'. $permission->id .'"';
+ if($permission->id == 0) {
+ $html .= ' checked';
+ }
+ $html .= '>';
+ $html .= '<label for="'. $permission->name .'">'. $permission->name .'</label>';
+ }
+ $html .= "</div>";
+ return [0 => $html];
+ }
+ }
+}
diff --git a/Model/PermissionUser.php b/Model/PermissionUser.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Model {
+ class PermissionUser extends \Lollipop\DatabaseObject
+ {
+ public static function get_table(): string
+ {
+ return "permission_user";
+ }
+
+ public static function get_primary(): string
+ {
+ return 'email';
+ }
+ public static function get_schema(): string
+ {
+ return "lollipop";
+ }
+ public function add_permissions(User $user): bool
+ {
+ if(array_key_exists('permissions', $_POST)) {
+ foreach($_POST['permissions'] as $permission) {
+ $this->{$user->get_primary()} = $user->{$user->get_primary()};
+ $this->id = $permission;
+ $this->add();
+ }
+ return true;
+ }
+ return false;
+ }
+ public function update_permissions(User $user): bool
+ {
+ foreach($this->db->all_where(PermissionUser::class, [$this->get_primary() => $_POST[$this->get_primary()]]) as $permission) {
+ $permission->delete();
+ }
+ if(array_key_exists('permissions', $_POST)) {
+ foreach($_POST['permissions'] as $permission) {
+ $this->{$user->get_primary()} = $user->{$user->get_primary()};
+ $this->id = $permission;
+ $this->add();
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/Model/Station.php b/Model/Station.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Model {
+ class Station extends \Lollipop\DatabaseObject
+ {
+ public static function get_table(): string
+ {
+ return "station";
+ }
+
+ public static function get_primary(): string
+ {
+ return "name";
+ }
+ public static function get_schema(): string
+ {
+ return "wap2";
+ }
+ }
+}
+\ No newline at end of file
diff --git a/Model/User.php b/Model/User.php
@@ -0,0 +1,152 @@
+<?php
+
+namespace Model {
+ class User extends \Lollipop\DatabaseObject
+ {
+ public static function get_table(): string
+ {
+ return "user";
+ }
+
+ public static function get_primary(): string
+ {
+ return "email";
+ }
+
+ public static function get_password_field(): string
+ {
+ return "password";
+ }
+ public static function get_schema(): string
+ {
+ return "lollipop";
+ }
+
+ public function login_fields(): string
+ {
+ $html = "";
+ $html .= '<input type="text" name="' . $this->get_primary(). '" placeholder="' . $this->get_primary() . '">';
+ $html .= '<input type="password" name="' . $this->get_password_field() . '" placeholder="password">';
+ return $html;
+ }
+
+ public function all_fields(array $res = []): string
+ {
+ $html = "";
+ foreach($this->column_names as $field) {
+ if($field == $this->get_password_field()) {
+ $html .= '<input type="password" name="' . $field . '" placeholder="' . $field . '">';
+ } else {
+ $html .= '<input type="text" name="' . $field . '" placeholder="' . $field . '">';
+ }
+ $miss_key = 'missing_'.$field;
+ if(array_key_exists($miss_key, $res)) {
+ $html .= '<div class="form-response"><p style="color:red;"> Field: '. $field . ' cannot be empty</p></div>';
+ }
+ }
+ return $html;
+ }
+
+ public function login(): array
+ {
+ if([$this->get_primary() != "" && !$this->get_password_field() == ""]) {
+ return $this->authenticate();
+ } else {
+ return ["response" => ""];
+ }
+ }
+ public function authenticate(): array
+ //this function return true when user is autheticated uses set_globals to set $_SESSION variables
+ {
+ //check if the email exists in db
+ if(!$this->load($_POST[$this->get_primary()])) {
+ //email does not exist
+ return ["response" => "{$this->get_primary()}: {$_POST[$this->get_primary()]} does not exists in db"];
+ } else {
+ if(password_verify($_POST[$this->get_password_field()], $this->{$this->get_password_field()})) {
+ //authenticated -> set $_SESSION variables
+ $this->set_globals();
+ return [];
+ } else {
+ //password did not match
+ return ["response" => "incorrect password"];
+ }
+ }
+ }
+
+ private function set_globals()
+ //this function sets Session variables
+ {
+ $user_permissions = [];
+ //foreach field in database which is not password add to session
+ foreach($this->getData() as $key => $data) {
+ if($key != $this->get_password_field()) {
+ $_SESSION[$key] = $data;
+ }
+ }
+ //get permissions form db and set sessions_permissions
+ $p = $this->db->all_where(PermissionUser::class, [$this->get_primary() => $this->{$this->get_primary()}]);
+ foreach($p as $permission) {
+ $user_permissions[] = $permission->id;
+ }
+ $_SESSION['user_permissions'] = $user_permissions;
+ }
+
+ public function add_user(): array
+ {
+ $missing_fields = \Lollipop\Utils::missing_fields($this->notNullable());
+
+ if(sizeof($missing_fields) == 0) {
+ return $this->add_data_db();
+ } else {
+ return $missing_fields;
+ }
+ }
+
+ private function add_data_db(): array
+ {
+ $user_credentials = [];
+ $response["success"] = false;
+ if($this->load($_POST[$this->get_primary()])) {
+ $response["response"] = "<p style=\"color:red;\">this email address is already taken: {$_POST[$this->get_primary()]} </p>";
+ return $response;
+ } else {
+ if($_POST[$this->get_password_field()]) {
+ $_POST[$this->get_password_field()] = password_hash($_POST[$this->get_password_field()], PASSWORD_DEFAULT);
+ }
+ foreach($this->get_col_names_no_ai() as $col) {
+ if($_POST[$col] != "") {
+ $this->$col = $_POST[$col];
+ $user_credentials[$col] = $_POST[$col];
+ }
+ }
+ if($this->add()) {
+ $response["response"] = "<p style=\"color:green;\">succes</p>";
+ $response += $user_credentials;
+ $response["success"] = true;
+ return $response;
+ } else {
+ $response["response"] = "<p style=\"color:red;\">could not add user to database</p>";
+ return $response;
+ }
+ }
+ }
+ public function update_user(): bool
+ {
+ $missing_fields = \Lollipop\Utils::missing_fields_sans_pw($this->notNullable());
+ if(sizeof($missing_fields) == 0) {
+ foreach($_POST as $key => $post) {
+ if(in_array($key, $this->get_column_names())) {
+ if($key == $this->get_password_field()) {
+ $this->{$key} = password_hash($_POST[$key], PASSWORD_DEFAULT);
+ } else {
+ $this->{$key} = $post;
+ }
+ }
+ }
+ return $this->save();
+ }
+ return false;
+ }
+ }
+}
diff --git a/Model/WeatherData.php b/Model/WeatherData.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Model {
+ class WeatherData extends \Lollipop\DatabaseObject
+ {
+ public static function get_table(): string
+ {
+ return "weather_data";
+ }
+
+ public static function get_primary(): string
+ {
+ return "data_id";
+ }
+ public static function get_schema(): string
+ {
+ return "wap2";
+ }
+ }
+}
+\ No newline at end of file
diff --git a/api/api.php b/api/api.php
@@ -1,12 +0,0 @@
-<?php
-
-$api = function(&$vars){
- global $db;
- $json = "";
- foreach(headers_list() as $header){
- $json .= $header;
- }
- $json .= "blablab";
- echo $json;
-};
-?>
-\ No newline at end of file
diff --git a/apii/api.php b/apii/api.php
@@ -0,0 +1,44 @@
+<?php
+
+$api_windchill = function(&$vars){
+ $headers = getallheaders();
+ $token = $headers["X-Token"];
+
+ $db = new mysqli("86.92.67.21", "friedel", "hailiwa", "wap2");
+ $weather_data = [];
+ $query = " SELECT distinct temperature, wind_speed, dew_point, DATE(date_time) AS date, nl.name as city
+ FROM weather_data wd
+ JOIN station s ON wd.station_name = s.name
+ JOIN contract_station cs ON cs.station_name = s.name
+ JOIN nearestlocation nl ON nl.station_name = s.name
+ JOIN country co ON co.country_code = nl.country_code
+ JOIN geolocation geo ON geo.country_code = co.country_code
+ JOIN contract c ON cs.contract_id = c.contract_id
+ WHERE c.token = ?
+ AND date(date_time) = CURDATE()
+ ORDER BY date DESC, temperature, wind_speed
+
+ ";
+
+ $stmt = $db->prepare($query);
+ $stmt->execute([0 => $token]);
+ $result = $stmt->get_result();
+ while ($row = $result->fetch_assoc()) {
+ $wind_chill = windchill($row["temperature"], $row["wind_speed"]);
+ $weather_data[] = [
+ 'city' => $row['city'],
+ 'date' => $row['date'],
+ 'windchill' => $wind_chill
+ ];
+ }
+
+ echo json_encode($weather_data);
+};
+
+function windchill($temp, $wind): float
+{
+ $result = 13.12 + 0.6215 * $temp - 11.37 * pow($wind, 0.16) + 0.3965 * $temp * pow($wind, 0.16);
+ return round($result, 2);
+}
+
+?>
+\ No newline at end of file
diff --git a/api/request.php b/apii/request.php
diff --git a/index.php b/index.php
@@ -1,19 +1,16 @@
<?php
use Lollipop\TemplateMethods;
require_once "utils/autoloader.php";
-require_once "api/api.php";
+require_once "apii/api.php";
$template = new Lollipop\Template(new TemplateMethods);
$router = new Lollipop\Router($template);
-$db = new Lollipop\SQLDatabase("86.92.67.21", "friedel", "hailiwa", "lollipop");
+$db = new Lollipop\SQLDatabase("86.92.67.21", "friedel", "hailiwa", "wap2");
$router->addRoute(['GET'], '/', 'views/homepage.php');
-//Api all data
-$router->addRoute(['GET', 'POST'], '/data', $api);
-
-//api graph data
-$router->addRoute(['GET'], '/data/graph', $api);
+//all data
+$router->addRoute(['GET', 'POST'], '/api/windchill', $api_windchill);
//add contract
$router->addRoute(['GET', 'POST'], '/add_contract', 'views/add_contract.php');