From bd2e88c2540a40ed3be8d1ded83c7aeddb0883ed Mon Sep 17 00:00:00 2001 From: Frank Schubert Date: Wed, 21 Sep 2022 11:08:04 +0200 Subject: [PATCH] FIX: addressdb/preorder API now uses gemeinde as City --- application/ADBGemeinde/ADBGemeindeModel.php | 7 + application/Api/v1/AddressdbApicontroller.php | 8 +- application/Api/v1/PreorderApicontroller.php | 13 +- lib/mvcfronk/mfBase/mfBaseApicontroller.php | 37 ++++- public/docs/preorder-api.yaml | 132 +++++++++++++++++- 5 files changed, 181 insertions(+), 16 deletions(-) diff --git a/application/ADBGemeinde/ADBGemeindeModel.php b/application/ADBGemeinde/ADBGemeindeModel.php index 02be4a9aa..7cb5e1ad9 100644 --- a/application/ADBGemeinde/ADBGemeindeModel.php +++ b/application/ADBGemeinde/ADBGemeindeModel.php @@ -136,6 +136,13 @@ class ADBGemeindeModel { if(array_key_exists("name", $filter)) { $name = FronkDB::singleton()->escape($filter['name']); + if($name) { + $where .= " AND Gemeinde.`name` = '$name'"; + } + } + + if(array_key_exists("name%", $filter)) { + $name = FronkDB::singleton()->escape($filter['name%']); if($name) { $where .= " AND Gemeinde.`name` like '%$name%'"; } diff --git a/application/Api/v1/AddressdbApicontroller.php b/application/Api/v1/AddressdbApicontroller.php index 7e3866de5..d9252994e 100644 --- a/application/Api/v1/AddressdbApicontroller.php +++ b/application/Api/v1/AddressdbApicontroller.php @@ -36,7 +36,7 @@ class AddressdbApicontroller extends mfBaseApicontroller { return mfResponse::BadRequest(['message' => "Searchstring cannot be empty!"]); } - $results = ADBOrtschaftModel::search(['name%' => $search]); + $results = ADBGemeindeModel::search(['name%' => $search]); $cities = []; @@ -103,7 +103,7 @@ class AddressdbApicontroller extends mfBaseApicontroller { $where .= " AND plz like '%$search_zip%'"; } if($search_city) { - $where .= " AND ortschaft like '%$search_city%'"; + $where .= " AND gemeinde like '%$search_city%'"; } if($search_street) { $where .= " AND strasse like '%$search_street%'"; @@ -113,7 +113,7 @@ class AddressdbApicontroller extends mfBaseApicontroller { } //$res = $this->db()->select("view_wohneinheit_plz", "*", $where); - $sql = "SELECT * FROM view_wohneinheit WHERE $where ORDER BY plz, ortschaft, strasse, LENGTH(hausnummer), hausnummer, block, stiege, stock, LENGTH(tuer), tuer"; + $sql = "SELECT * FROM view_wohneinheit WHERE $where ORDER BY plz, gemeinde, ortschaft, strasse, LENGTH(hausnummer), hausnummer, block, stiege, stock, LENGTH(tuer), tuer"; //echo $sql;exit; $res = $this->db()->query($sql); @@ -121,7 +121,7 @@ class AddressdbApicontroller extends mfBaseApicontroller { while($data = $this->db()->fetch_object($res)) { $addresses[] = [ 'zip' => $data->plz, - 'city' => $data->ortschaft, + 'city' => $data->gemeinde, 'street' => $data->strasse, 'housenumber' => $data->hausnummer, 'block' => $data->block, diff --git a/application/Api/v1/PreorderApicontroller.php b/application/Api/v1/PreorderApicontroller.php index 324fd3cf6..fd24683d1 100644 --- a/application/Api/v1/PreorderApicontroller.php +++ b/application/Api/v1/PreorderApicontroller.php @@ -37,7 +37,7 @@ class PreorderApicontroller extends mfBaseApicontroller { } $type = $this->post['type']; - if($type != "interest" && $type != "provision") { + if($type != "interest" && $type != "provision" && $type != "order") { return mfResponse::BadRequest(["message" => "Unknown type"]); } @@ -59,9 +59,9 @@ class PreorderApicontroller extends mfBaseApicontroller { } $address_search = []; - foreach(['street' => 'strasse','housenumber' => "hausnummer",'zip' => "plz",'city' => "ortschaft"] as $key => $field_name) { + foreach(['street' => 'strasse','housenumber' => "hausnummer",'zip' => "plz",'city' => "gemeinde"] as $key => $field_name) { if(property_exists($this->post['address'], $key)) { - $address_search[$field_name] = trim($this->post['address']->$key); + $address_search[$field_name] = $this->db()->escape(trim($this->post['address']->$key)); } } @@ -150,6 +150,13 @@ class PreorderApicontroller extends mfBaseApicontroller { $preorder_data['price_setup'] = $product->price_setup; } } + if($type == "order") { + $product = $this->campaign->setup_products['activation'][0]; + if($product) { + $preorder_data['setup_product_id'] = $product->id; + $preorder_data['price_setup'] = $product->price_setup; + } + } diff --git a/lib/mvcfronk/mfBase/mfBaseApicontroller.php b/lib/mvcfronk/mfBase/mfBaseApicontroller.php index 3fcfabc01..8f9e53f9e 100644 --- a/lib/mvcfronk/mfBase/mfBaseApicontroller.php +++ b/lib/mvcfronk/mfBase/mfBaseApicontroller.php @@ -79,7 +79,7 @@ class mfBaseApicontroller { private function logRequest() { $this->requestLog->debug("=================================================================="); - $this->requestLog->debug("new API request for ".$_SERVER['REQUEST_URI']); + $this->requestLog->debug("new API request for ".$_SERVER['REQUEST_URI']. " from ".$_SERVER['REMOTE_ADDR']); $this->requestLogstr = ""; foreach($_GET as $key => $value) { $this->requestLogstr .= "; $key='$value'"; @@ -93,6 +93,7 @@ class mfBaseApicontroller { $this->requestLog->debug("POST: ".print_r($_POST, true)); } + // things to log after loadRequest() private function logRequest2() { $this->requestLog->debug("POST Raw: ".$this->raw_post_body); $this->requestLog->debug("POST JSON: ".$this->request_json); @@ -182,13 +183,39 @@ class mfBaseApicontroller { } private function getRequestBody() { - $this->raw_post_body = file_get_contents('php://input'); - if(strtolower($this->headers['content-type']) == "application/json") { - return $this->raw_post_body; + $request_charset = "utf-8"; + if(preg_match('#application/json#i', $_SERVER["CONTENT_TYPE"])) { + // request body is JSON + $request_body = file_get_contents('php://input'); + + $m = []; + + if(preg_match('#charset\s*=\s*["\']?([^ "\']+)["\']?\s*;?#i', $_SERVER["CONTENT_TYPE"], $m)) { + $request_charset = strtolower($m[1]); + } + + if($request_charset != "utf-8") { + $request_body = mb_convert_encoding($request_body, "utf-8", $request_charset); + } + //var_dump(mb_detect_encoding($request_body), $charset); + return $request_body; } - return $_POST; + // Request body is urlencoded or multipart-formdata + if(preg_match('#charset\s*=\s*["\']?([^ "\']+)["\']?\s*;?#i', $_SERVER["CONTENT_TYPE"], $m)) { + $request_charset = strtolower($m[1]); + } + + $post = []; + if($request_charset == "utf-8") { + $post = $_POST; + } else { + foreach($_POST as $key => $value) { + $post[mb_convert_encoding($key, "utf-8", $request_charset)] = mb_convert_encoding($value, "utf-8", $request_charset); + } + } + return $post; } protected function return($response) { diff --git a/public/docs/preorder-api.yaml b/public/docs/preorder-api.yaml index f9affc4b8..b47fc3221 100644 --- a/public/docs/preorder-api.yaml +++ b/public/docs/preorder-api.yaml @@ -139,7 +139,7 @@ paths: result: type: object properties: - streets: + zips: $ref: '#/components/schemas/Zips' '400': description: | @@ -180,7 +180,7 @@ paths: result: type: object properties: - streets: + cities: $ref: '#/components/schemas/Cities' '400': description: | @@ -194,7 +194,7 @@ paths: tags: - preorder summary: Vorbestellung registrieren - description: "Registriert eine Vorbestellung. Parameter `type` bestimmt Vorbestelltyp: 'interest' = Interessensbekundung, 'provision' = Vorsorgeanschluss" + description: "Registriert eine Vorbestellung. Parameter `type` bestimmt Vorbestelltyp: 'interest' = Interessensbekundung, 'provision' = Vorsorgeanschluss, 'order' = Vollanschluss" operationId: submitPreorder requestBody: description: PreorderRequest object @@ -233,6 +233,54 @@ paths: description: Unauthorized '404': description: Adresse oder Wohneinheit nicht gefunden +# /preorder/{code}: +# get: +# tags: +# - preorder +# summary: Details zur Vorbestellung (noch nicht Final) +# description: Gibt Details zum Status der Vorbestellung/Bestellung zurück **(noch nicht Final)** +# operationId: getPreorderStatus +# parameters: +# - name: code +# in: path +# description: code der Vorbestellung +# required: true +# schema: +# type: string +# responses: +# '200': +# description: | +# Successful operation +# +# Mögliche Werte für Rückgabewert `status` +# +# | id | text | description | +# |------|------|-------------| +# | 100 | Aufgenommen | Interessensbekundung/Vorbestellung aufgenommen | +# | 110 | Tiefbau in Planung | | +# | 120 | Tiefbau in Arbeit | | +# | 200 | Tiefbau abgeschlossen | | +# | 210 | Leitungsbau in planung | | +# | 220 | Leitungsbau in Arbeit | | +# | 230 | Leitungsbau abgeschlossen | | +# | 300 | Leitungskonfiguration in Planung | | +# | 310 | Leitungskonfiguration in Arbeit | | +# | 320 | Leitung hergestellt | Produkt bestellbar | +# content: +# application/json: +# schema: +# type: object +# properties: +# status: +# type: string +# description: Status string +# example: OK +# result: +# $ref: '#/components/schemas/preorderStatusDetail' +# '401': +# description: Unauthorized +# '404': +# description: Vorbestellung nicht gefunden components: schemas: addressComponentSearchRequest: @@ -282,13 +330,70 @@ components: description: Ortschaft required: - street + addressResponse: + type: object + properties: + street: + type: string + description: Strasse der Anschlussadresse + housenumber: + type: string + description: Hausnummer der Anschlussadresse + zip: + type: string + description: PLZ der Anschlussadresse + city: + type: string + description: Ort der Anschlussadresse + block: + type: string + description: Block der Anschlussadresse + stock: + type: string + description: Stock der Anschlussadresse + stiege: + type: string + description: Stiege der Anschlussadresse + tuer: + type: string + description: Tür der Anschlussadresse + customerResponse: + type: object + properties: + company: + type: string + description: Firmenname Kunde + uid: + type: string + description: UID (wenn Firmenkunde) + firstname: + type: string + description: Vorname Kunde + lastname: + type: string + description: Nachname Kunde + street: + type: string + description: Straße Kunde + zip: + type: string + description: PLZ Kunde + city: + type: string + description: Ort Kunde + phone: + type: string + description: Telefonnummer Kunde + email: + type: string + description: Emailadresse Kunde preorderRequest: type: object properties: type: type: string enum: [interest, provision] - desciption: Vorbestelltyp (`interest` = Interessensbekundung, `provision` = Vorsorgeanschluss) + description: Vorbestelltyp (`interest` = Interessensbekundung, `provision` = Vorsorgeanschluss) address: type: object properties: @@ -357,6 +462,25 @@ components: - street - zip - city + preorderStatusDetail: + type: object + properties: + address: + $ref: '#/components/schemas/addressResponse' + customer: + $ref: '#/components/schemas/customerResponse' + status: + type: object + properties: + id: + type: int + description: status ID + example: 220 + text: + type: string + description: Statustext + + example: Tiefbau abgeschlossen, Leitungsbau ausständig securitySchemes: api_key_header: type: apiKey