diff --git a/homepage/participo/.vscode/launch.json b/homepage/participo/.vscode/launch.json new file mode 100644 index 0000000..b2fddbf --- /dev/null +++ b/homepage/participo/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "post", + "type": "python", + "request": "launch", + "program": "testApi.py", + "console": "integratedTerminal", + "justMyCode": true, + "args": [ + "POST", + "--input", "testShiai.json" + ] + } + ] +} \ No newline at end of file diff --git a/homepage/participo/api/shiai.php b/homepage/participo/api/shiai.php index e024153..54d199c 100644 --- a/homepage/participo/api/shiai.php +++ b/homepage/participo/api/shiai.php @@ -3,14 +3,52 @@ require_once("inc/bootstrap.php"); require_once("participoLib/shiai.php"); +$method = $_SERVER['REQUEST_METHOD']; + // Sending Response -// - setting header -// - we send a json-formatted response +// - we send a json-formatted response header("Content-Type: application/json"); -// - sending body payload -echo( - json_encode( - Shiai::dbSelect() - ) -); +// - check if an valid api key was send +authorize(); +// - depending on the method we perform different actions +switch($method){ + // Create + case 'POST': + $postData = json_decode(file_get_contents('php://input'), true); + if(!$postData){ + die(json_encode([ + 'error'=>$postData . " not valid json data!" + ])); + } + die(json_encode( + Shiai::fromArray($postData)->asArray() + )); + break; + // Read + case 'GET': + echo(json_encode( + Shiai::dbSelect() + )); + break; + // Update + case 'PUT': + die(json_encode([ + 'success'=>false, + 'reason'=>$method.".not supported yet." + ])); + break; + // Delete + case 'DELETE': + die(json_encode([ + 'success'=>false, + 'reason'=>$method.".not supported yet." + ])); + break; + // all other methods not supported + default: + die(json_encode([ + 'success'=>false, + 'reason'=>$method.".not supported." + ])); +} ?> diff --git a/homepage/participo/lib/participoLib/participo.php b/homepage/participo/lib/participoLib/participo.php index 42fca1d..00de3a1 100644 --- a/homepage/participo/lib/participoLib/participo.php +++ b/homepage/participo/lib/participoLib/participo.php @@ -55,7 +55,7 @@ class participo /** lazy loading of the session user */ public static function sessionUser(bool $forceLoading = true) { - if (is_null($sessionUser) || $forceLoading) { + if (is_null(self::$sessionUser) || $forceLoading) { self::$sessionUser = User::loadFromDb(self::getSessionUserId()); } return self::$sessionUser; diff --git a/homepage/participo/lib/participoLib/shiai.php b/homepage/participo/lib/participoLib/shiai.php index ab59543..1419556 100644 --- a/homepage/participo/lib/participoLib/shiai.php +++ b/homepage/participo/lib/participoLib/shiai.php @@ -21,10 +21,10 @@ class Shiai */ private static $tableName = "wettkampfkalender"; - public function __construct($id, $date, $name, $ageclasses, $place, $announcementUrl, $routeUrl, $galleryUrl, $promoImgUrl) + public function __construct($id, $date, $name, $ageclasses, $place, $announcementUrl, $routeUrl, $galleryUrl=null, $promoImgUrl=null) { //! @todo input validation and sanitation - $this->id = (int) $id; + $this->id = filterId($id); $this->date = DateTime::createFromFormat('Y-m-d', $date); $this->name = $name; $this->ageclasses = $ageclasses ? self::akListString2jgArray($ageclasses) : null; @@ -35,6 +35,32 @@ class Shiai $this->promoImgUrl = $promoImgUrl; } + public static function fromArray(array $shiai){ + $id = $shiai['id'] ?? null; + $date = $shiai['date'] ?? null; + $name = $shiai['name'] ?? null; + $ageclasses = $shiai['ageclasses'] ?? null; + $place = $shiai['place'] ?? null; + $announcementUrl = $shiai['announcementUrl'] ?? null; + $routeUrl = $shiai['routeUrl'] ?? null; + // gallery stuff removed for now + + return new Shiai($id, $date, $name, $ageclasses, $place, $announcementUrl, $routeUrl); + } + + public function asArray(){ + return [ + 'id'=>$this->id, + 'date'=>$this->date->format('Y-m-d'), + 'name'=>$this->name, + // @todo at least in theory this should again hold age categories + 'ageclasses'=>implode(" ", $this->ageclasses), + 'place'=>$this->place, + 'announcementUrl'=>$this->announcementUrl, + 'routeUrl'=>$this->announcementUrl + ]; + } + public function getId() { return $this->id; diff --git a/homepage/participo/lib/participoLib/user.php b/homepage/participo/lib/participoLib/user.php index e736c40..17656db 100644 --- a/homepage/participo/lib/participoLib/user.php +++ b/homepage/participo/lib/participoLib/user.php @@ -75,6 +75,26 @@ class User return dbConnector::getLastInsertId(); } + public static function dbSelectWithAttribute(int $attributeId) + { + $query = + "SELECT DISTINCT" . + " `wkParticipo_Users`.* " . + " FROM `wkParticipo_Users`" . + " JOIN `wkParticipo_user<=>userAttributes`" . + " ON `wkParticipo_user<=>userAttributes`.`userId` = `wkParticipo_Users`.`id`" . + " WHERE `wkParticipo_user<=>userAttributes`.`attributeId` = :attributeId". + " ORDER BY `wkParticipo_Users`.`id` ASC;"; + + $params = [ + ':attributeId' => ['value' => $attributeId, 'data_type' => PDO::PARAM_INT] + ]; + + $response = dbConnector::query($query, $params); + + return $response; + } + /** Name of the table with all the Users * * @var string diff --git a/homepage/participo/testApi.py b/homepage/participo/testApi.py index b31824e..a43325c 100755 --- a/homepage/participo/testApi.py +++ b/homepage/participo/testApi.py @@ -12,7 +12,10 @@ class TestApi: argParser = argparse.ArgumentParser( "testApi" ) - + argParser.add_argument( + "method", + choices=['GET', 'POST'] + ) argParser.add_argument( "--endpoint", default="shiai" @@ -40,6 +43,11 @@ class TestApi: choices=_LOG_LEVEL, default="WARNING" ) + argParser.add_argument( + "--input", "-i", + type=argparse.FileType("r"), + default="-" + ) return argParser.parse_args() @@ -59,33 +67,47 @@ class TestApi: def apiCall(self): return apiCall.call( + method=self.config.method, host=self.config.host, url="/".join([self.config.path, self.config.endpoint]), headers={ "Authorization": f"Basic {self.config.key}" - } + }, + input=load_json(self.config.input) ) +def load_json(jsonFile): + import json + with jsonFile as f: + return json.load(f) + class apiCall: @staticmethod def call( + method: str, host: str, url: str, - headers: dict = None + headers: dict = None, + input: dict = None, ) -> dict: import requests - r = requests.get( - url=f"http://{host}/{url}", - # @todo The client always awaits this timeout. Even when the - # meaningful body is already received.params= - # - I don't see any of the examples out there do it different from - # me. - # - The browser doesn't seem to have this problem. - timeout=10, - headers=headers - ) + if(method=="GET"): + r = requests.get( + url=f"http://{host}/{url}", + timeout=10, + headers=headers + ) + elif(method=="POST"): + r = requests.post( + json=input, + url=f"http://{host}/{url}", + timeout=10, + headers=headers + ) + else: + logging.error("This line should never been reached!") try: return r.json()