From d156725bf7f9476759c47e9e9372c06934975eeb Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Sun, 7 Jun 2020 20:47:02 -0600 Subject: [PATCH] Add machine editing APIs --- action.php | 23 +++-- api/.htaccess | 1 - api/actions/lookup.php | 21 ----- api/actions/machine.php | 69 ++++++++++++++ api/apisettings.php | 31 ++++++- api/login/index.php | 148 +++++++++++++++++++++++++++++ langs/en/components.json | 4 + langs/en/events.json | 4 + lib/Client.lib.php | 9 +- lib/Clients.lib.php | 9 ++ lib/Component.lib.php | 56 ++++++++++- lib/Event.lib.php | 195 +++++++++++++++++++++++++++++++++++++++ lib/Machine.lib.php | 61 ++++++++---- pages/viewmachine.php | 12 +-- public/index.php | 6 +- required.php | 5 +- static/img/logo.png | Bin 10466 -> 8223 bytes static/img/logo.svg | 43 ++++++--- 18 files changed, 617 insertions(+), 80 deletions(-) delete mode 100644 api/actions/lookup.php create mode 100644 api/actions/machine.php create mode 100644 api/login/index.php create mode 100644 langs/en/components.json create mode 100644 langs/en/events.json create mode 100644 lib/Event.lib.php diff --git a/action.php b/action.php index c1413a8..bceda74 100644 --- a/action.php +++ b/action.php @@ -97,20 +97,19 @@ switch ($VARS['action']) { returnToSender("invalid_parameters"); } - $machine = new Machine($VARS['machine']); - - $machine->addEvent( - date( - "Y-m-d H:i:s", - strtotime($VARS['date'] . " " . $VARS['time']) - ), - $VARS['event'], - $user->getUID(), - $VARS['publicnotes'], - $VARS['privatenotes'] + $evt = Event::create( + $VARS['machine'], + date( + "Y-m-d H:i:s", + strtotime($VARS['date'] . " " . $VARS['time']) + ), + $VARS['event'], + $user->getUID(), + $VARS['publicnotes'], + $VARS['privatenotes'] ); - returnToSender("event_added", $machine->getID()); + returnToSender("event_added", $VARS['machine']); case "editclient": $user = new User($_SESSION['uid']); if (!$user->hasPermission("MACHINEMANAGER_EDIT")) { diff --git a/api/.htaccess b/api/.htaccess index 9a4efe4..c26f042 100644 --- a/api/.htaccess +++ b/api/.htaccess @@ -1,4 +1,3 @@ -# Rewrite for Nextcloud Notes API RewriteEngine on RewriteRule ([a-zA-Z0-9]+) index.php?action=$1 [PT] diff --git a/api/actions/lookup.php b/api/actions/lookup.php deleted file mode 100644 index 6231c21..0000000 --- a/api/actions/lookup.php +++ /dev/null @@ -1,21 +0,0 @@ -hasPermission("MACHINEMANAGER_EDIT")) { + http_response_code(403); + sendJsonResp("You don't have permission to edit.", "ERROR"); + } + + if (!empty($VARS["model"])) { + $machine->setModel($VARS['model']); + } + if (!empty($VARS["client"])) { + $machine->setClientID($VARS['client']); + } + if (!empty($VARS["os"])) { + $machine->setOS($VARS['os']); + } + if (!empty($VARS["serial"])) { + $machine->setSerial($VARS['serial']); + } + if (!empty($VARS["manufacturer"])) { + $machine->setManufacturer($VARS['manufacturer']); + } + if (!empty($VARS["condition"])) { + $machine->setCondition($VARS['condition']); + } + if (!empty($VARS["price"])) { + $machine->setPrice($VARS['price']); + } + if (!empty($VARS["privatenotes"])) { + $machine->setPrivateNotes($VARS['privatenotes']); + } + if (!empty($VARS["publicnotes"])) { + $machine->setPublicNotes($VARS['publicnotes']); + } + + $machine->save(); +} + +header("Content-Type: application/json"); + +$output = $machine->toArray(); +$output["editable"] = $user->hasPermission("MACHINEMANAGER_EDIT"); + +exit(json_encode($output)); diff --git a/api/apisettings.php b/api/apisettings.php index 8d34b16..97dc943 100644 --- a/api/apisettings.php +++ b/api/apisettings.php @@ -13,9 +13,38 @@ $APIS = [ ] ], "lookup" => [ - "load" => "lookup.php", + "load" => "machine.php", "vars" => [ "id" => "/^[0-9a-z]+$/" ] + ], + "editmachine" => [ + "load" => "machine.php", + "vars" => [ + "id" => "/^[0-9a-z]+$/", + "model (optional)" => "string", + "client (optional)" => "string", + "os (optional)" => "string", + "serial (optional)" => "string", + "manufacturer (optional)" => "string", + "condition (optional)" => "numeric", + "price (optional)" => "numeric", + "privatenotes (optional)" => "string", + "publicnotes (optional)" => "string" + ] + ], + "addmachine" => [ + "load" => "machine.php", + "vars" => [ + "model (optional)" => "string", + "client (optional)" => "string", + "os (optional)" => "string", + "serial (optional)" => "string", + "manufacturer (optional)" => "string", + "condition (optional)" => "numeric", + "price (optional)" => "numeric", + "privatenotes (optional)" => "string", + "publicnotes (optional)" => "string" + ] ] ]; diff --git a/api/login/index.php b/api/login/index.php new file mode 100644 index 0000000..667654e --- /dev/null +++ b/api/login/index.php @@ -0,0 +1,148 @@ + + + + + + + <?php echo $SETTINGS['app_name']; ?> + + + + + + +
+
+
+ +
+ +
+

+
+ + +
+
+
+

+ +

+
+
+
+ + + +
+
+
+ +
+
+
+ +
+
+ $_SESSION["login_code"]]); + + if ($uidinfo["status"] == "ERROR") { + throw new Exception(); + } + if (is_numeric($uidinfo['uid'])) { + $user = new User($uidinfo['uid'] * 1); + + $addpassresp = AccountHubApi::get( + "addapppassword", + [ + "desc" => $SETTINGS["app_name"], + "username" => $user->getUsername() + ], + true + ); + + $_SESSION["login_code"] = null; + + $redirecturl = "https://apploginhelper.netsyms.net/?user:" . htmlentities($user->getUsername()) . "&password:" . htmlentities($addpassresp["pass"]); + + header("Location: $redirecturl"); + showHTML("Continue", "Click Here", $redirecturl); + } else { + throw new Exception(); + } + } catch (Exception $ex) { + $redirecttologin = true; + } +} + +if ($redirecttologin) { + try { + $codedata = AccountHubApi::get("getloginkey", ["appname" => $SETTINGS["app_name"], "appicon" => $iconurl], true); + + if ($codedata['status'] != "OK") { + throw new Exception("There was a problem. Try again later."); + } + + $_SESSION["login_code"] = $codedata["code"]; + + $locationurl = $codedata["loginurl"] . "?code=" . htmlentities($codedata["code"]) . "&redirect=" . htmlentities($thisurl); + + header("Location: $locationurl"); + showHTML("Continue", "Continue", $locationurl); + die(); + } catch (Exception $ex) { + showHTML("Error", "", "", $ex->getMessage()); + } +} \ No newline at end of file diff --git a/langs/en/components.json b/langs/en/components.json new file mode 100644 index 0000000..db23641 --- /dev/null +++ b/langs/en/components.json @@ -0,0 +1,4 @@ +{ + "Type": "Type", + "Tested": "Tested" +} diff --git a/langs/en/events.json b/langs/en/events.json new file mode 100644 index 0000000..ed44fad --- /dev/null +++ b/langs/en/events.json @@ -0,0 +1,4 @@ +{ + "Date": "Date", + "Technician": "Technician" +} diff --git a/lib/Client.lib.php b/lib/Client.lib.php index f8a4ffb..be98587 100644 --- a/lib/Client.lib.php +++ b/lib/Client.lib.php @@ -10,7 +10,7 @@ use InvoiceNinja\Config as NinjaConfig; use InvoiceNinja\Models\Client as NinjaClient; -class Client { +class Client implements JsonSerializable { private $local = true; private $exists = false; @@ -54,6 +54,13 @@ class Client { } } + public function jsonSerialize() { + return [ + "id" => $this->id, + "name" => $this->name + ]; + } + /** * Fill in all the client data from the InvoiceNinja API. */ diff --git a/lib/Clients.lib.php b/lib/Clients.lib.php index 6ce99f5..c8c8dee 100644 --- a/lib/Clients.lib.php +++ b/lib/Clients.lib.php @@ -41,6 +41,15 @@ if (!empty($SETTINGS["apis"]["invoiceninja"]["token"])) { return $list; } + public static function getAllAsIDNameArray(): array { + $clients = Clients::getAll(); + $arr = []; + foreach ($clients as $c) { + $arr[$c->getID()] = $c->getName(); + } + return $arr; + } + public static function getClient($id): Client { return new Client($id, false); } diff --git a/lib/Component.lib.php b/lib/Component.lib.php index fef9f10..db10907 100644 --- a/lib/Component.lib.php +++ b/lib/Component.lib.php @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -class Component { +class Component implements JsonSerializable { private $componentid = ""; private $component = []; @@ -39,6 +39,60 @@ class Component { return $list; } + public function toArray() { + global $Strings; + if ($this->exists) { + return [ + "info" => [ + "id" => $this->getID(), + "machineid" => $this->getMachineID(), + "serial" => $this->getSerial(), + "type" => $this->getTypeID(), + "tested" => $this->getTestedDate(), + "capacity" => $this->getCapacity(), + "model" => $this->getModel(), + "price" => $this->getPrice(), + "manufacturer" => $this->getManufacturer(), + "publicnotes" => $this->getPublicNotes(), + "privatenotes" => $this->getPrivateNotes() + ], + "formdata" => [ + "types" => $this->getTypes(), + "inputtypes" => [ + "machineid" => "text", + "serial" => "text", + "type" => "number", + "tested" => "datetime", + "capacity" => "text", + "model" => "text", + "price" => "number", + "manufacturer" => "text", + "privatenotes" => "textarea", + "publicnotes" => "textarea" + ], + "labels" => [ + "machineid" => $Strings->get("Machine ID", false), + "serial" => $Strings->get("Serial", false), + "type" => $Strings->get("Type", false), + "tested" => $Strings->get("Tested", false), + "capacity" => $Strings->get("Capacity", false), + "model" => $Strings->get("Model", false), + "price" => $Strings->get("Price", false), + "manufacturer" => $Strings->get("Manufacturer", false), + "privatenotes" => $Strings->get("Private Notes", false), + "publicnotes" => $Strings->get("Public Notes", false) + ], + "icons" => [] + ] + ]; + } + return []; + } + + public function jsonSerialize() { + return $this->toArray(); + } + public function save() { global $database; if ($this->exists) { diff --git a/lib/Event.lib.php b/lib/Event.lib.php new file mode 100644 index 0000000..ec5a12c --- /dev/null +++ b/lib/Event.lib.php @@ -0,0 +1,195 @@ +id = $eventid; + if (\Event::exists($eventid)) { + $this->exists = true; + $this->event = $database->get('events', ['machineid', 'eventid', 'techuid', 'date', 'privatenotes', 'publicnotes'], ['historyid' => $eventid]); + } + } + + public static function create(string $machineid = "", string $date = "", int $event = 0, string $techuid = "", string $publicnotes = "", string $privatenotes = ""): Event { + if ($machineid == "" || $date == "" || $event == 0) { + return new Event(""); + } else { + if (!Machine::exists($machineid)) { + throw new Exception("Invalid machine ID $machineid"); + } + if (strtotime($date) === false) { + throw new Exception("Invalid date."); + } + $date = date("Y-m-d H:i:s", strtotime($date)); + if (!array_key_exists($event, \Event::getTypes())) { + throw new Exception("Invalid event type."); + } + $evt = new Event(""); + + $evt->setMachineID($machineid); + $evt->setTypeID($event); + $evt->setDate($date); + $evt->setTechUID($techuid); + $evt->setPrivateNotes($privatenotes); + $evt->setPublicNotes($publicnotes); + $evt->save(); + + return $evt; + } + } + + public static function exists($id): bool { + global $database; + return $database->has('events', ['historyid' => $id]); + } + + public static function getTypes() { + global $database; + $types = $database->select("event_types", ["eventid (id)", "eventname (name)"]); + + $list = []; + foreach ($types as $t) { + $list[$t['id']] = $t['name']; + } + return $list; + } + + public function toArray() { + global $Strings; + if ($this->exists) { + return [ + "info" => [ + "id" => $this->getID(), + "machineid" => $this->getMachineID(), + "type" => $this->getTypeID(), + "date" => $this->getDate(), + "techuid" => $this->getTechUID(), + "publicnotes" => $this->getPublicNotes(), + "privatenotes" => $this->getPrivateNotes() + ], + "formdata" => [ + "types" => $this->getTypes(), + "inputtypes" => [ + "machineid" => "text", + "type" => "number", + "date" => "datetime", + "techuid" => "text", + "privatenotes" => "textarea", + "publicnotes" => "textarea" + ], + "labels" => [ + "machineid" => $Strings->get("Machine ID", false), + "type" => $Strings->get("Type", false), + "date" => $Strings->get("Date", false), + "techuid" => $Strings->get("Technician", false), + "privatenotes" => $Strings->get("Private Notes", false), + "publicnotes" => $Strings->get("Public Notes", false) + ], + "icons" => [] + ] + ]; + } + return []; + } + + public function jsonSerialize() { + return $this->toArray(); + } + + public function save() { + global $database; + if ($this->exists) { + $database->update("events", $this->event, ["historyid" => $this->id]); + } else { + $database->insert("events", $this->event); + $this->id = $database->id(); + $this->exists = true; + } + } + + public function getID(): string { + return $this->id . ""; + } + + public function getMachineID(): string { + if (!empty($this->event["machineid"])) { + return $this->event["machineid"]; + } + return ""; + } + + public function getTypeID(): int { + if (!empty($this->event["eventid"])) { + return $this->event["eventid"] * 1; + } + return 0; + } + + public function getName(): string { + return $this->getTypes()[$this->getTypeID()] ?? ""; + } + + public function getDate(): string { + if (!empty($this->event["date"])) { + return $this->event["date"]; + } + return ""; + } + + public function getTechUID(): string { + if (!empty($this->event["techuid"])) { + return $this->event["techuid"]; + } + return ""; + } + + public function getPublicNotes(): string { + if (!empty($this->event["publicnotes"])) { + return $this->event["publicnotes"]; + } + return ""; + } + + public function getPrivateNotes(): string { + if (!empty($this->event["privatenotes"])) { + return $this->event["privatenotes"]; + } + return ""; + } + + public function setMachineID($id) { + $this->event["machineid"] = $id; + } + + public function setTypeID(int $id) { + if (!empty($this->getTypes()[$id])) { + $this->event["eventid"] = $id; + } + } + + public function setTechUID($uid) { + $this->event["techuid"] = $uid; + } + + public function setDate(string $date) { + $this->event["date"] = date("Y-m-d H:i:s", strtotime($date)); + } + + public function setPrivateNotes(string $notes) { + $this->event["privatenotes"] = $notes; + } + + public function setPublicNotes(string $notes) { + $this->event["publicnotes"] = $notes; + } + +} diff --git a/lib/Machine.lib.php b/lib/Machine.lib.php index 170ca93..826de86 100644 --- a/lib/Machine.lib.php +++ b/lib/Machine.lib.php @@ -18,7 +18,10 @@ class Machine implements JsonSerializable { if (Machine::exists($machineid)) { $this->exists = true; $this->machine = $database->get('machines', ['model', 'condition', 'price', 'os', 'serial', 'manufacturer', 'clientid', 'privatenotes', 'publicnotes'], ['machineid' => $machineid]); - $this->events = $database->select('events', ['[>]event_types' => 'eventid'], ['historyid', 'date', 'event_types.eventname', 'techuid', 'privatenotes', 'publicnotes'], ['machineid' => $machineid, "ORDER" => ["date" => "DESC"]]); + $events = $database->select('events', 'historyid', ['machineid' => $machineid, "ORDER" => ["date" => "DESC"]]); + foreach ($events as $e) { + $this->events[] = new Event($e); + } $components = $database->select("components", "compid", ["machineid" => $machineid]); foreach ($components as $c) { $this->components[] = new Component($c); @@ -26,19 +29,52 @@ class Machine implements JsonSerializable { } } - public function jsonSerialize() { + public function toArray() { + global $Strings; if ($this->exists) { return [ "status" => "OK", "id" => $this->machineid, "info" => $this->machine, "events" => $this->events, - "components" => $this->components + "components" => $this->components, + "formdata" => [ + "options" => [ + "clientid" => Clients::getAllAsIDNameArray() + ], + "inputtypes" => [ + "model" => "text", + "condition" => "number", + "price" => "number", + "os" => "text", + "serial" => "text", + "manufacturer" => "text", + "clientid" => "select", + "privatenotes" => "textarea", + "publicnotes" => "textarea" + ], + "labels" => [ + "model" => $Strings->get("Model", false), + "condition" => $Strings->get("Condition", false), + "price" => $Strings->get("Price", false), + "os" => $Strings->get("OS/Software", false), + "serial" => $Strings->get("Serial", false), + "manufacturer" => $Strings->get("Manufacturer", false), + "clientid" => $Strings->get("Client", false), + "privatenotes" => $Strings->get("Private Notes", false), + "publicnotes" => $Strings->get("Public Notes", false) + ], + "icons" => [] + ] ]; } return []; } + public function jsonSerialize() { + return $this->toArray(); + } + public static function create(): Machine { return new Machine(Machine::generateId()); } @@ -204,22 +240,9 @@ class Machine implements JsonSerializable { } public function addEvent(string $date, int $event, string $techuid = "", string $publicnotes = "", string $privatenotes = "") { - global $database; - if (strtotime($date) === false) { - throw new Exception("Invalid date."); - } - $date = date("Y-m-d H:i:s", strtotime($date)); - if (!$database->has('event_types', ['eventid' => $event])) { - throw new Exception("Invalid event type."); - } - $event = (int) $event; - if (empty($publicnotes)) { - $publicnotes = ""; - } - if (empty($privatenotes)) { - $privatenotes = ""; - } - $database->insert('events', ['date' => $date, 'eventid' => $event, 'techuid' => $techuid, 'machineid' => $this->machineid, 'publicnotes' => $publicnotes, 'privatenotes' => $privatenotes]); + $evt = Event::create($this->machineid, $date, $event, $techuid, $publicnotes, $privatenotes); + + $this->events[] = $evt; } /** diff --git a/pages/viewmachine.php b/pages/viewmachine.php index 5750a8c..1dec957 100644 --- a/pages/viewmachine.php +++ b/pages/viewmachine.php @@ -96,13 +96,13 @@ $machine = new Machine($machineid); \n"; - echo "$h[eventname] on " . date($SETTINGS["datetime_format"], strtotime($h['date'])) . "
\n"; - echo "Technician: " . htmlspecialchars((new User($h['techuid']))->getName()) . "
\n"; - if (!empty($h['publicnotes'])) { - echo "
Public Notes:
" . htmlspecialchars($h['publicnotes']) . "
"; + echo "" . $h->getName() . " on " . date($SETTINGS["datetime_format"], strtotime($h->getDate())) . "
\n"; + echo "Technician: " . htmlspecialchars((new User($h->getTechUID()))->getName()) . "
\n"; + if (!empty($h->getPublicNotes())) { + echo "
Public Notes:
" . htmlspecialchars($h->getPublicNotes()) . "
"; } - if (!empty($h['privatenotes'])) { - echo "
Private Notes:
" . htmlspecialchars($h['privatenotes']) . "
"; + if (!empty($h->getPrivateNotes())) { + echo "
Private Notes:
" . htmlspecialchars($h->getPrivateNotes()) . "
"; } echo "\n\n"; } diff --git a/public/index.php b/public/index.php index 9e0dbe6..c8191db 100644 --- a/public/index.php +++ b/public/index.php @@ -321,9 +321,9 @@ if (isset($_GET["backgroundcolor"]) && !empty($_GET["backgroundcolor"]) && preg_ \n"; - echo "$h[eventname] on " . date($SETTINGS["datetime_format"], strtotime($h['date'])) . "
\n"; - if (!empty($h['publicnotes'])) { - echo "
Notes:
" . htmlspecialchars($h['publicnotes']) . "
"; + echo "" . $h->getName() . " on " . date($SETTINGS["datetime_format"], strtotime($h->getDate())) . "
\n"; + if (!empty($h->getPublicNotes())) { + echo "
Notes:
" . htmlspecialchars($h->getPublicNotes()) . "
"; } echo "\n\n"; } diff --git a/required.php b/required.php index 97cc2fc..788bcd7 100644 --- a/required.php +++ b/required.php @@ -106,7 +106,10 @@ try { 'server' => $SETTINGS['database']['server'], 'username' => $SETTINGS['database']['user'], 'password' => $SETTINGS['database']['password'], - 'charset' => $SETTINGS['database']['charset'] + 'charset' => $SETTINGS['database']['charset'], + 'option' => [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION + ] ]); } catch (Exception $ex) { //header('HTTP/1.1 500 Internal Server Error'); diff --git a/static/img/logo.png b/static/img/logo.png index 8c956b827b01d1bc59d547a6ec410275852d8bb6..c916515d130a55bba2dfa1bfe32f8fae35c46b5e 100644 GIT binary patch literal 8223 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 X;E#5Wll}xX^8xaT+0O+(IX?Oizow-% literal 10466 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 diff --git a/static/img/logo.svg b/static/img/logo.svg index 410fb09..6c9f6a4 100644 --- a/static/img/logo.svg +++ b/static/img/logo.svg @@ -14,11 +14,11 @@ viewBox="0 0 512.00001 512.00001" id="svg2" version="1.1" - inkscape:version="0.91 r13725" + inkscape:version="0.92.3 (2405546, 2018-03-11)" sodipodi:docname="logo.svg" - inkscape:export-filename="/home/skylar/Documents/Projects/Sources/WebAppTemplate/static/img/logo.png" - inkscape:export-xdpi="90" - inkscape:export-ydpi="90"> + inkscape:export-filename="/home/skylar/Documents/Projects/Sources/Apps/Native/MachineManager/resources/icon.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + units="px" + inkscape:window-width="1920" + inkscape:window-height="1013" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" /> @@ -51,7 +56,7 @@ image/svg+xml - + @@ -69,10 +74,20 @@ y="540.36218" rx="50" ry="50" /> - + + + +