Added basic time record api interface for posting

This commit is contained in:
Maximilian Giller 2020-01-11 17:56:21 +01:00
parent f58e976373
commit 6e3ff52607
8 changed files with 228 additions and 60 deletions

View file

@ -0,0 +1,6 @@
<?php
require_once(__DIR__."/../services/configReader.inc.php");
$config = new ConfigReader();
$config->readPathFile(__DIR__."/config.path");
?>

View file

@ -2,7 +2,6 @@
require_once(__DIR__."/authenticator.inc.php");
require_once(__DIR__."/responses.inc.php");
require_once(__DIR__."/requestTypes.inc.php");
require_once(__DIR__."/dbOperations.inc.php");
require_once(__DIR__."/paramCleaner.inc.php");
abstract class ApiBranch {
@ -13,26 +12,27 @@ abstract class ApiBranch {
}
function execute ($authenticationRequired = true) {
$params = $this->getParams();
if ($authenticationRequired) {
$auth = new Authenticator();
if (!$auth->isAuthenticated($_SESSION, $_REQUEST)) {
$this->authenticationMissing($this->getParams());
if (!$auth->isAuthenticated($params)) {
$this->authenticationMissing($params);
return;
}
}
$currentType = currentRequestType();
if($currentType === RequestType::GET) {
$this->get($this->getParams());
$this->get($params);
} else if ($currentType === RequestType::POST) {
$this->post($this->getParams());
$this->post($params);
}
}
private function getParams() {
$content = json_decode(file_get_contents('php://input'), true);
$contentArray = array("json" => $content);
return new ParamCleaner(array_merge($contentArray, $_REQUEST, $_SESSION, $_FILES));
return new ParamCleaner(array_merge($content, $_REQUEST, $_SESSION, $_FILES));
}
}
?>

View file

@ -1,43 +1,20 @@
<?php
require(__DIR__."/dbOperations.inc.php");
require_once(__DIR__."/dbOperations.inc.php");
class Authenticator {
function isApiKeyAuthenticated($key) {
function isApiKeyAuthenticated($api_key, $user_id) {
$db = new DbOperations();
$db->select("api_keys", array("quota_max", "client_key"));
$db->where("client_key", Comparison::EQUAL, $key);
$db->select("api_keys", ["enabled"]);
$db->where("api_key", Comparison::EQUAL, $api_key);
$db->where("user_id", Comparison::EQUAL, $user_id);
$result = $db->execute();
if (count($result) == 1 && $result[0]['quota_max'] > 0)
return true;
else
return false;
return count($result) == 1 && $result[0]['enabled'];
}
function isSessionAuthenticated($session) {
if (isset($session['stayloggedin'])) {
if($session["stayloggedin"]) {
return true;
}
}
if (!isset($session['until'])) {
return false;
}
if ($session['until'] > time() || $session['until'] == 0)
return true;
else
return false;
}
function isAuthenticated($session, $request) {
if (isset($request['key'])) {
return $this->isApiKeyAuthenticated($request['key']);
} else {
return $this->isSessionAuthenticated($session);
}
function isAuthenticated($params) {
return $this->isApiKeyAuthenticated($params->get('api_key'), $params->get('user_id'));
}
}
?>

View file

@ -3,6 +3,10 @@
class ConfigReader {
private const VALUE_SEPARATOR = '=';
function __construct () {
$this->configuration = array();
}
function readFile ($path) {
if (file_exists($path) == false)
return;
@ -17,6 +21,11 @@ class ConfigReader {
}
}
function readPathFile ($pathToPathFile) {
$this->readFile($pathToPathFile);
$this->readFile(__DIR__."/../".$this->getSetting("relativepath"));
}
function getSetting ($key) {
if (array_key_exists($key, $this->configuration) == false)
return NULL;

View file

@ -1,34 +1,38 @@
<?php
require(__DIR__."/configReader.inc.php");
require(__DIR__."/basicEnum.inc.php");
require_once(__DIR__."/basicEnum.inc.php");
class DbOperations {
function __construct () {
function __construct ($tablePrefix = null) {
$this->resetQuery();
$this->tablePrefix = $tablePrefix;
require(__DIR__."/../config/config.inc.php");
$this->config = $config;
if ($this->tablePrefix == null) {
$this->tablePrefix = $this->config->getSetting("table_prefix");
}
}
function resetQuery() {
$this->query = "";
$this->data = array();
$this->table = "";
$this->tablePrefix = "";
}
private function openConnection () {
$config = new ConfigReader();
$config->readFile(__DIR__."/../config/config.path");
$config->readFile(__DIR__."/../".$config->getSetting("relativepath"));
$host = $config->getSetting('host');
$dbname = $config->getSetting('dbname');
$host = $this->config->getSetting('host');
$dbname = $this->config->getSetting('dbname');
$dsn = "mysql:host=$host;dbname=$dbname";
$options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);
$this->pdo = new PDO($dsn, $config->getSetting('username'), $config->getSetting('password'), $options);
$this->pdo = new PDO($dsn, $this->config->getSetting('username'), $this->config->getSetting('password'), $options);
}
function select (string $table, array $attributes = array()) {
$this->table = $table;
$this->table = $this->tablePrefix.$table;
if (count($attributes) == 0)
$formattedAttributes = "*";
else {
@ -41,7 +45,7 @@ class DbOperations {
$formattedAttributes = implode(', ', $attributes);
}
$this->addToQuery("SELECT $formattedAttributes FROM $table");
$this->addToQuery("SELECT $formattedAttributes FROM $this->tablePrefix$table");
return $this;
}
@ -62,7 +66,7 @@ class DbOperations {
}
function insert (string $table, array $data) {
$this->table = $table;
$this->table = $this->tablePrefix.$table;
$attributes = implode(", ", array_keys($data));
$valuesIds = array();
@ -71,13 +75,40 @@ class DbOperations {
}
$values = implode(" , ", $valuesIds);
$this->addToQuery("INSERT INTO $table ( $attributes ) VALUES ( $values )");
$this->addToQuery("INSERT INTO $this->tablePrefix$table ( $attributes ) VALUES ( $values )");
return $this;
}
function insertMultiple (string $table, array $attributes, array $data) {
$this->table = $this->tablePrefix.$table;
$attributesString = implode(", ", $attributes);
$valueGroups = array();
$groupIndex = 0; // To avoid same value ids
foreach($data as $dataGroup) {
if (sizeof($attributes) != sizeof($dataGroup)) {
continue;
}
$valueIds = array();
// Indexed for used, so that attributes can easily be assigned to the according values
for ($i = 0; $i < sizeof($dataGroup); $i++) {
$valueIds[] = $this->addData($dataGroup[$i], $attributes[$i] . "_" . (string) $groupIndex);
}
$valueGroups[] = "(" . implode(", " ,$valueIds) . ")";
$groupIndex++;
}
$values = implode(", ", $valueGroups);
$this->addToQuery("INSERT INTO $this->tablePrefix$table ( $attributesString ) VALUES $values");
return $this;
}
function update (string $table, array $data) {
$this->table = $table;
$this->table = $this->tablePrefix.$table;
$sets = array();
foreach($data as $attribute => $value) {
@ -86,15 +117,15 @@ class DbOperations {
}
$setString = implode(", ", $sets);
$this->addToQuery("UPDATE $table SET $setString");
$this->addToQuery("UPDATE $this->tablePrefix$table SET $setString");
return $this;
}
function delete (string $table) {
$this->table = $table;
$this->table = $this->tablePrefix.$table;
$this->addToQuery("DELETE FROM $table");
$this->addToQuery("DELETE FROM $this->tablePrefix$table");
return $this;
}
@ -118,12 +149,15 @@ class DbOperations {
return $this;
}
function innerJoin (string $table, string $externAttribute, string $internAttribute, string $internTable = "") {
function innerJoin (string $table, string $externAttribute, string $internAttribute = "", string $internTable = "") {
if ($internTable === "") {
$internTable = $this->table;
$internTable = substr($this->table, sizeof($this->tablePrefix));
}
if ($internAttribute === "") {
$internAttribute = $externAttribute;
}
$innerJoin = "INNER JOIN $table ON $table.$externAttribute = $internTable.$internAttribute";
$innerJoin = "INNER JOIN $this->tablePrefix$table ON $this->tablePrefix$table.$externAttribute = $this->tablePrefix$internTable.$internAttribute";
$this->addToQuery($innerJoin);

View file

@ -24,6 +24,15 @@ class ParamCleaner {
return null;
}
}
function exists (array $props) {
foreach ($props as $prop) {
if(isset($this->selectedParams[$prop]) == false) {
return false;
}
}
return true;
}
function hasErrorOccurred () {
return $this->errorCount > 0;

View file

@ -1,5 +1,7 @@
<?php
session_start();
require_once(__DIR__."/services/apiBranch.inc.php");
require_once(__DIR__."/services/dbOperations.inc.php");
require_once(__DIR__."/services/jsonBuilder.inc.php");
require_once(__DIR__."/services/responses.inc.php");
@ -9,6 +11,97 @@ class TimeTrackingBranch extends ApiBranch {
}
function post (ParamCleaner $params) {
$user_id = $params->get("user_id");
$params->select("request");
// Is id given, should update?
if ($params->exists(["record_id"])) {
$this->updateTimeRecord($user_id, $params);
} else {
if ($params->exists(["start_time", "end_time", "duration"]) == false) {
respondStatus(400, "Missing parameter");
}
$project_id = $params->get("project_id");
if ($this->isProjectValid($project_id, $user_id) == false) {
$project_id = null;
}
$device_id = $params->get("device_id");
if ($this->isDeviceValid($device_id, $user_id) == false) {
$device_id = null;
}
$this->addTimeRecord($user_id, $params, $project_id, $device_id);
}
}
private function isProjectValid ($project_id, $user_id) {
$db = new DbOperations();
$db->select("projects");
$db->where("project_id", Comparison::EQUAL, $project_id);
$db->where("user_id", Comparison::EQUAL, $user_id);
return count($db->execute()) == 1;
}
private function isDeviceValid ($device_id, $user_id) {
$db = new DbOperations();
$db->select("devices");
$db->where("device_id", Comparison::EQUAL, $device_id);
$db->where("user_id", Comparison::EQUAL, $user_id);
return count($db->execute()) == 1;
}
private function addTimeRecord ($user_id, $params, $project_id = null, $device_id = null) {
$data = ["user_id" => $user_id,
"start_time" => $params->get("start_time"),
"end_time" => $params->get("end_time"),
"duration" => $params->get("duration"),
"project_id" => $project_id,
"device_id" => $device_id];
$db = new DbOperations();
$db->insert("time_records", $data);
$db->execute();
}
private function updateTimeRecord ($user_id, $params) {
$data = ["user_id" => $user_id,
"record_id" => $params->get("record_id")
];
$anythingUpdated = false;
if ($params->exists(["start_time"])) {
$data["start_time"] = $params->get("start_time");
$anythingUpdated = true;
}
if ($params->exists(["end_time"])) {
$data["end_time"] = $params->get("end_time");
$anythingUpdated = true;
}
if ($params->exists(["duration"])) {
$data["duration"] = $params->get("duration");
$anythingUpdated = true;
}
if ($params->exists(["project_id"])) {
$data["project_id"] = $params->get("project_id");
$anythingUpdated = true;
}
if ($params->exists(["device_id"])) {
$data["device_id"] = $params->get("device_id");
$anythingUpdated = true;
}
if ($anythingUpdated == false) {
return;
}
$db = new DbOperations();
$db->update("time_records", $data);
$db->execute();
}
}

View file

@ -0,0 +1,40 @@
Juggl Documentation
Goal
Hold information about projects
Timetracking
Invoice generation
Shared files
ToDo
Progress
Shared Workspace for client
Deadlines
API interface
Ticket system
ToDo
High Priority
Time tracking
API interface
Web interface
Low Priority
Timetracking API
Setting null does not work
Web interface
Datbase
Table prefix
ju_
API
timetracking
POST
api_key
user_id
request
start_time (required for insert)
end_time (required for insert)
duration (required for insert)
project_id (optional)
device_id (optional)
record_id (optional, update when given)