diff --git a/.docker/Dockerfile b/.docker/Dockerfile new file mode 100644 index 0000000..31620ba --- /dev/null +++ b/.docker/Dockerfile @@ -0,0 +1,3 @@ +FROM webdevops/php-nginx:7.2 + +RUN pecl install xdebug-2.9.8 && docker-php-ext-enable xdebug \ No newline at end of file diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml new file mode 100755 index 0000000..b04b4cc --- /dev/null +++ b/.docker/docker-compose.yml @@ -0,0 +1,43 @@ +version: '3.1' +services: + apache2: + container_name: docker_apache2_php + build: . + ports: + - 80:80 + - 443:443 + volumes: + - ../:/app/ + depends_on: + - mariadb + links: + - mariadb + environment: + PHP_IDE_CONFIG: 'serverName=postman' + XDEBUG_CONFIG: 'remote_mode=req remote_enable=1 remote_connect_back=0 remote_autostart=1 remote_host=172.17.0.1 remote_port=9000 idekey=PHPSTORM' + restart: always + networks: + zssn_net: + ipv4_address: 12.7.0.4 + mariadb: + image: mariadb + restart: always + environment: + MYSQL_DATABASE: 'zssn' + MYSQL_ROOT_PASSWORD: 'root' + ports: + - '3307:3306' + expose: + - '3307' + volumes: + - ./db:/var/lib/mysql + - ./dumps/db.sql:/usr/db.sql + networks: + zssn_net: + ipv4_address: 12.7.0.5 +networks: + zssn_net: + driver: bridge + ipam: + config: + - subnet: 12.7.0.0/16 \ No newline at end of file diff --git a/.docker/dumps/db.sql b/.docker/dumps/db.sql new file mode 100644 index 0000000..e4265dd --- /dev/null +++ b/.docker/dumps/db.sql @@ -0,0 +1,101 @@ +/* +SQLyog Ultimate v13.1.2 (64 bit) +MySQL - 10.5.9-MariaDB-1:10.5.9+maria~focal : Database - zssn +********************************************************************* +*/ + +/*!40101 SET NAMES utf8 */; + +/*!40101 SET SQL_MODE=''*/; + +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +CREATE DATABASE /*!32312 IF NOT EXISTS*/`zssn` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; + +USE `zssn`; + +/*Table structure for table `inventory` */ + +DROP TABLE IF EXISTS `inventory`; + +CREATE TABLE `inventory` ( + `id_inventory` int(11) NOT NULL AUTO_INCREMENT, + `id_survivor` int(11) DEFAULT NULL, + `item` text DEFAULT NULL, + `qty` int(11) DEFAULT NULL, + PRIMARY KEY (`id_inventory`), + KEY `id_survivor` (`id_survivor`), + CONSTRAINT `inventory_ibfk_1` FOREIGN KEY (`id_survivor`) REFERENCES `survivors` (`id_survivor`) +) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4; + +/*Data for the table `inventory` */ + +insert into `inventory`(`id_inventory`,`id_survivor`,`item`,`qty`) values +(27,42,'water',6), +(28,42,'food',0), +(29,42,'medication',3), +(30,42,'ammunition',0), +(31,43,'water',2), +(32,43,'food',0), +(33,43,'medication',5), +(34,43,'ammunition',3), +(35,44,'water',0), +(36,44,'food',5), +(37,44,'medication',2), +(38,44,'ammunition',5), +(39,45,'water',8), +(40,45,'food',1), +(41,45,'medication',0), +(42,45,'ammunition',4), +(43,46,'water',1), +(44,46,'food',1), +(45,46,'medication',2), +(46,46,'ammunition',4); + +/*Table structure for table `survivors` */ + +DROP TABLE IF EXISTS `survivors`; + +CREATE TABLE `survivors` ( + `id_survivor` int(11) NOT NULL AUTO_INCREMENT, + `name` text DEFAULT NULL, + `age` int(11) DEFAULT NULL, + `gender` text DEFAULT NULL, + `location` text DEFAULT NULL, + `infected` smallint(6) DEFAULT NULL, + `reported` smallint(6) DEFAULT NULL, + PRIMARY KEY (`id_survivor`) +) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4; + +/*Data for the table `survivors` */ + +insert into `survivors`(`id_survivor`,`name`,`age`,`gender`,`location`,`infected`,`reported`) values +(42,'testerino',12,'male','+1234/+8901',0,0), +(43,'testerina',39,'female','-9298338/+1234900',0,0), +(44,'gigi',17,'female','+12345/-14',0,6), +(45,'gigi2',98,'male','+4321/+9382',0,2), +(46,'franco',24,'male','+0391/+933838',0,0); + +/*Table structure for table `trade_points` */ + +DROP TABLE IF EXISTS `trade_points`; + +CREATE TABLE `trade_points` ( + `item` text DEFAULT NULL, + `points` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +/*Data for the table `trade_points` */ + +insert into `trade_points`(`item`,`points`) values +('water',4), +('food',3), +('medication',2), +('ammunition',1); + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; diff --git a/.env.docker b/.env.docker new file mode 100644 index 0000000..def4cf4 --- /dev/null +++ b/.env.docker @@ -0,0 +1,5 @@ +DB_HOST=mariadb +DB_PORT=3306 +DB_DATABASE=zssn +DB_USERNAME=root +DB_PASSWORD=root \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd59ba4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.docker/db +/.env +/vendor \ No newline at end of file diff --git a/HOW_TO_RUN_PROJECT.md b/HOW_TO_RUN_PROJECT.md new file mode 100644 index 0000000..52b4dc0 --- /dev/null +++ b/HOW_TO_RUN_PROJECT.md @@ -0,0 +1,20 @@ +## How to run project +1. From project root: `composer install` +2. `composer dump-autoload -o` +3. `cp .env.docker .env` +4. `cd .docker/` +5. `docker-compose up -d` +6. Connect to Mariadb Docker image: + `docker exec -it $(docker ps -qf expose=3306) bash` +7. Import db to mariadb: + `mysql -uroot -proot zssn < /usr/db.sql` +8. Once it's done, you can `exit` from machine +9. Import ./ZSSN.postman_collection.json file into your Postman app +10. If it's all done, you can try api calls from postman +11. You can connect to the database using this parameters: + * DB_HOST=127.0.0.1 + * DB_PORT=3307 + * DB_DATABASE=zssn + * DB_USERNAME=root + * DB_PASSWORD=root + \ No newline at end of file diff --git a/ZSSN.postman_collection.json b/ZSSN.postman_collection.json new file mode 100644 index 0000000..6298d6d --- /dev/null +++ b/ZSSN.postman_collection.json @@ -0,0 +1,210 @@ +{ + "info": { + "_postman_id": "b417f438-139c-4071-b6d3-d6c3faf8d2e0", + "name": "ZSSN", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "addSurvivor", + "request": { + "method": "POST", + "header": [ + { + "key": "name", + "value": "ciccio", + "type": "text" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "name", + "value": "franco", + "type": "text" + }, + { + "key": "age", + "value": "24", + "type": "text" + }, + { + "key": "gender", + "value": "male", + "type": "text" + }, + { + "key": "location", + "value": "+0391/+933838", + "type": "text" + }, + { + "key": "water", + "value": "1", + "type": "text" + }, + { + "key": "food", + "value": "1", + "type": "text" + }, + { + "key": "medication", + "value": "2", + "type": "text" + }, + { + "key": "ammunition", + "value": "4", + "type": "text" + } + ] + }, + "url": { + "raw": "http://127.0.0.1/api.php/addSurvivor", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "path": [ + "api.php", + "addSurvivor" + ] + } + }, + "response": [] + }, + { + "name": "tradeItems", + "request": { + "method": "PUT", + "header": [ + { + "key": "name", + "value": "ciccio", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"buyer\": {\n \"name\": \"gigi\",\n \"water\": \"1\"\n }, \n \"seller\": {\n \"name\": \"testerino\",\n \"food\": \"1\",\n \"ammunition\": \"1\"\n }\n}" + }, + "url": { + "raw": "http://127.0.0.1/api.php/tradeItems", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "path": [ + "api.php", + "tradeItems" + ] + } + }, + "response": [] + }, + { + "name": "updateLocation", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\":\"testerina\",\n \"location\":{\n \"longitude\":\"-093245\",\n \"latitude\":\"+101010\"\n }\n}" + }, + "url": { + "raw": "http://127.0.0.1/api.php/updateLocation", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "path": [ + "api.php", + "updateLocation" + ] + } + }, + "response": [] + }, + { + "name": "reportInfected", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\":\"gigi2\"\n}" + }, + "url": { + "raw": "http://127.0.0.1/api.php/reportInfected", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "path": [ + "api.php", + "reportInfected" + ] + } + }, + "response": [] + }, + { + "name": "getInfectedPercentage", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://127.0.0.1/api.php/getInfectedPercentage", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "path": [ + "api.php", + "getInfectedPercentage" + ] + } + }, + "response": [] + }, + { + "name": "getNonInfectedPercentage", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://127.0.0.1/api.php/getNonInfectedPercentage", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "path": [ + "api.php", + "getNonInfectedPercentage" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/api.php b/api.php new file mode 100644 index 0000000..1023d03 --- /dev/null +++ b/api.php @@ -0,0 +1,3 @@ + $value) { + putenv($key . '=' . $value); +} + +$db = new DatabaseConnector; +$dbConnection = $db->getConnection(); + +$requestMethod = $_SERVER["REQUEST_METHOD"]; +$apiController = new ApiController($requestMethod, $uri); diff --git a/src/ApiController/ApiController.php b/src/ApiController/ApiController.php new file mode 100644 index 0000000..72982fb --- /dev/null +++ b/src/ApiController/ApiController.php @@ -0,0 +1,262 @@ +requestMethod = $requestMethod; + $this->uriPath = $uriPath; + $this->helper = new ApiHelper(); + $this->processRequest(); + } + + public function processRequest() + { + $response = []; + switch ($this->requestMethod) { + case 'GET': + $response = $this->getActionCall(); + break; + case 'POST': + $response = $this->_addSurvivor(); + break; + case 'PUT': + $response = $this->getUpdateCall(); + break; + default: + $this->helper->runBadRequest(); + break; + } + + header($response['status_code_header']); + echo $response['body']; + } + + /** + * @return array + */ + public function getActionCall(): array + { + if (!$this->uriPath[2]) { + $this->helper->runBadRequest(); + } + + $result = []; + switch ($this->uriPath[2]) { + case 'getInfectedPercentage': + $result = $this->_getInfectedPercentage(); + break; + case 'getNonInfectedPercentage': + $result = $this->_getNonInfectedPercentage(); + break; + case 'getAverageAllResources': + $this->_getAverageAllResources(); + break; + case 'getLostPoints': + $this->_getLostPoints(); + break; + default: + $this->helper->runBadRequest(); + break; + } + + return $result; + } + + /** + * @return array + */ + public function getUpdateCall(): array + { + if (!$this->uriPath[2]) { + $this->helper->runBadRequest(); + } + $result = []; + switch ($this->uriPath[2]) { + case 'updateLocation': + $result = $this->_updateSurvivor('location'); + breaK; + case 'reportInfected': + $result = $this->_updateSurvivor('reported'); + breaK; + case 'tradeItems': + $result = $this->_tradeItems(); + breaK; + default: + $this->helper->runBadRequest(); + break; + } + + return $result; + } + + /** + * @return array + */ + private function _getInfectedPercentage(): array + { + $infected = 0; + $survivorsQty = 0; + $survivors = $this->helper->getAllSurvivors(); + + foreach ($survivors as $survivor) { + $survivorsQty++; + foreach ($survivor as $key => $value) { + if ($key !== 'infected') { + continue; + } + + if ($value == 0) { + continue; + } + + $infected++; + } + } + $percentage = intval($this->helper->getPercentage($infected, $survivorsQty)); + + $message = "Infected Percentage = " . $percentage . "%"; + + $response['status_code_header'] = $this->helper::STATUS_OK; + $response['infected'] = $infected; + $response['survivorsQty'] = $survivorsQty; + $response['percentage'] = $percentage; + + $response['body'] = json_encode($message); + + return $response; + } + + /** + * @return array + */ + private function _getNonInfectedPercentage(): array + { + $infectedResponse = $this->_getInfectedPercentage(); + $percentage = $infectedResponse['percentage']; + $nonInfectedPercentage = intval(100 - $percentage); + $message = "Non Infected Percentage = " . $nonInfectedPercentage . "%"; + $response['status_code_header'] = $this->helper::STATUS_OK; + $response['nonInfectedPercentage'] = $nonInfectedPercentage; + + $response['body'] = json_encode($message); + + return $response; + } + + /** + * TODO + */ + private function _getAverageAllResources() + { + } + + /** + * TODO + */ + private function _getLostPoints() + { + } + + /** + * @return array + */ + private function _addSurvivor(): array + { + if ($this->uriPath[2] !== 'addSurvivor') { + $this->helper->runBadRequest(); + } + + $survivorData = $this->helper->getSurvivorDataFromPost(); + $this->helper->addNewSurvivor($survivorData); + + $survivorId = $this->helper->getSurvivorIdByName($survivorData['name']); + $inventoryData = $this->helper->setInventoryDataFromPost($survivorId); + + $this->helper->addNewInventory($inventoryData); + + $message = 'Survivor Created!'; + $response['status_code_header'] = $this->helper::STATUS_OK; + $response['body'] = json_encode($message); + + return $response; + } + + /** + * @param $type + * @return array + */ + private function _updateSurvivor($type): array + { + $vars = json_decode(file_get_contents("php://input"), true); + + if (!$vars['name']) { + $this->helper->runBadRequest(); + } + + $isLocationType = $type == 'location'; + + if ($isLocationType && !$vars['location']) { + $this->helper->runBadRequest(); + } + + if($isLocationType){ + $long = $vars['location']['longitude']; + $lat = $vars['location']['latitude']; + $location = sprintf('%s/%s', $long, $lat); + } + + $survivorData = $this->helper->getSurvivorByName($vars['name']); + $survivorData[$type] = $isLocationType ? $location : $survivorData[$type] + 1; + + $this->helper->updateSurvivor($survivorData); + + $message = 'Survivor: ' . $survivorData['name'] . ' Updated! '; + + if (!$isLocationType && $survivorData[$type] >= 3) { + $survivorData['infected'] = 1; + $this->helper->updateSurvivor($survivorData); + $message .= $survivorData['name'] . ' is now infected!!'; + } + + $response['status_code_header'] = $this->helper::STATUS_OK; + $response['body'] = json_encode($message); + + return $response; + } + + /** + * @return array + */ + private function _tradeItems(): array + { + $vars = json_decode(file_get_contents("php://input"), true); + + if (!$vars['buyer'] || !$vars['seller'] || !$vars['buyer']['name'] || !$vars['seller']['name']) { + $this->helper->runBadRequest(); + } + + $isTradeOk = $this->helper->tradeCanBeDone($vars['buyer'], $vars['seller']); + + if ($isTradeOk) { + $this->helper->updateInventoryTraders($vars['buyer'], $vars['seller']); + } + + $message = $isTradeOk ? 'Trade Done' : 'Trade cannot be done'; + + $response['status_code_header'] = $this->helper::STATUS_OK; + $response['body'] = json_encode($message); + + return $response; + } + +} \ No newline at end of file diff --git a/src/ApiHelper/ApiHelper.php b/src/ApiHelper/ApiHelper.php new file mode 100644 index 0000000..a04265b --- /dev/null +++ b/src/ApiHelper/ApiHelper.php @@ -0,0 +1,308 @@ +survivor = new SurvivorHelper(); + $this->inventory = new InventoryHelper(); + $this->tradePoints = new TradePointsHelper(); + } + + /** + * @return array + */ + public function getSurvivorDataFromPost(): array + { + $survivorData = []; + if (!$_POST['name']) { + $this->runBadRequest(); + } + $survivorData['name'] = $_POST['name']; + $survivorData['age'] = $_POST['age']; + $survivorData['gender'] = $_POST['gender']; + $survivorData['location'] = $_POST['location']; + $survivorData['infected'] = 0; + $survivorData['reported'] = 0; + + return $survivorData; + } + + /** + * @param $survivorId + * @return array + */ + public function setInventoryDataFromPost($survivorId): array + { + $inventoryData = []; + array_push($inventoryData, + ['id_survivor' => $survivorId, 'item' => 'water', 'qty' => $_POST['water']], + ['id_survivor' => $survivorId, 'item' => 'food', 'qty' => $_POST['food']], + ['id_survivor' => $survivorId, 'item' => 'medication', 'qty' => $_POST['medication']], + ['id_survivor' => $survivorId, 'item' => 'ammunition', 'qty' => $_POST['ammunition']] + ); + + return $inventoryData; + } + + /** + * @return mixed + */ + public function getAllSurvivors() + { + return $this->survivor->getAllSurvivors(); + } + + /** + * @param $name + * @return mixed + */ + public function getSurvivorByName($name) + { + return $this->survivor->getSurvivorByName($name); + } + + /** + * @param $name + * @return mixed + */ + public function getSurvivorIdByName($name) + { + return $this->getSurvivorByName($name)['id_survivor']; + } + + /** + * @param $survivor + */ + public function addNewSurvivor($survivor) + { + $this->survivor->addNewSurvivor($survivor); + } + + /** + * @param $survivorData + */ + public function updateSurvivor($survivorData) + { + $this->survivor->updateSurvivor($survivorData); + } + + /** + * @param $survivorId + * @return mixed + */ + public function getInventoryBySurvivorId($survivorId) + { + return $this->inventory->getInventoryBySurvivorId($survivorId); + } + + /** + * @param $survivorId + * @return array + */ + public function getInventoryItemsQtyBySurvivorId($survivorId): array + { + $survivorInventory = $this->getInventoryBySurvivorId($survivorId); + + return $this->inventory->getInventoryItemsQty($survivorInventory); + } + + /** + * @param $inventory + * @return mixed + */ + public function addNewInventory($inventory) + { + return $this->inventory->addNewInventory($inventory); + } + + public function updateInventory($inventory) + { + $this->inventory->updateInventory($inventory); + } + + /** + * @return mixed + */ + public function getAllTradePoints() + { + return $this->tradePoints->getAllTradePoints(); + } + + /** + * @param $tablePoints + * @return array + */ + public function getItemPoints($tablePoints): array + { + return $this->tradePoints->getItemPoints($tablePoints); + } + + /** + * @param $tradeBuyer + * @param $tradeSeller + * @return bool + */ + public function tradeCanBeDone($tradeBuyer, $tradeSeller): bool + { + $survivorBuyerId = $this->getSurvivorIdByName($tradeBuyer['name']); + $itemsQtyBuyer = $this->getInventoryItemsQtyBySurvivorId($survivorBuyerId); + + $survivorSellerId = $this->getSurvivorIdByName($tradeSeller['name']); + $itemsQtySeller = $this->getInventoryItemsQtyBySurvivorId($survivorSellerId); + + $tablePoints = $this->getAllTradePoints(); + $itemPoints = $this->getItemPoints($tablePoints); + + $buyerPoints = $this->calculateTradePoints($tradeBuyer, $itemPoints, $itemsQtyBuyer); + $sellerPoints = $this->calculateTradePoints($tradeSeller, $itemPoints, $itemsQtySeller); + + return $buyerPoints == $sellerPoints; + } + + /** + * @param $trader + * @param $itemPoints + * @param $traderInventory + * @return bool|float|int + */ + public function calculateTradePoints($trader, $itemPoints, $traderInventory) + { + $result = 0; + + foreach ($itemPoints as $item => $point) { + foreach ($trader as $key => $value) { + if ($item !== $key) { + continue; + } + if (!$this->checkIfTraderHasItems($traderInventory, $key, $value)) { + return false; + } + $result = ($value * $point) + $result; + } + } + + return $result; + } + + /** + * @param $traderInventory + * @param $traderItem + * @param $itemQty + * @return bool + */ + public function checkIfTraderHasItems($traderInventory, $traderItem, $itemRequestedQty): bool + { + $result = true; + foreach ($traderInventory as $item => $qty) { + if ($item == $traderItem) { + if ($qty < $itemRequestedQty) { + return false; + } + } + } + + return $result; + } + + /** + * @param $buyerTrade + * @param $sellerTrade + */ + public function updateInventoryTraders($buyerTrade, $sellerTrade) + { + $buyerId = $this->getSurvivorIdByName($buyerTrade['name']); + $buyerInventory = $this->getInventoryItemsQtyBySurvivorId($buyerId); + $sellerId = $this->getSurvivorIdByName($sellerTrade['name']); + $sellerInventory = $this->getInventoryItemsQtyBySurvivorId($sellerId); + $toSellerItems = $this->getToTraderItems($buyerInventory, $buyerTrade); + $toBuyerItems = $this->getToTraderItems($sellerInventory, $sellerTrade); + + $this->updateFinalTraderInventory($buyerInventory, $toBuyerItems, $buyerId); + $this->updateFinalTraderInventory($sellerInventory, $toSellerItems, $sellerId); + } + + /** + * @param $traderInventory + * @param $trade + * @return array + */ + public function getToTraderItems(&$traderInventory, $trade): array + { + $result = []; + + foreach ($traderInventory as $itemTrader => $qtyTrader) { + foreach ($trade as $itemTrade => $qtyTrade) { + if ($itemTrader != $itemTrade) { + continue; + } + $traderInventory[$itemTrader] = $traderInventory[$itemTrader] - $qtyTrade; + $result[$itemTrader] = $qtyTrade; + } + } + + return $result; + } + + /** + * @param $inventory + * @param $items + * @param $survivorId + */ + public function updateFinalTraderInventory($inventory, $items, $survivorId) + { + $temporaryInventory = ['id_survivor' => $survivorId]; + foreach ($inventory as $key => $value) { + if ($key == 'name') { + continue; + } + foreach ($items as $item => $qty) { + if ($key == $item) { + $value = $inventory[$key] + $qty; + } + } + $temporaryInventory['item'] = $key; + $temporaryInventory['qty'] = $value; + $this->updateInventory($temporaryInventory); + } + } + + /** + * @param $a + * @param $b + * @return float|int + * + * $a : $b = result : 100 + */ + public function getPercentage( + $a, + $b + ) { + return ($a / $b) * 100; + } + + /** + * Exception Trigger + */ + public function runBadRequest() + { + header(self::STATUS_ERROR); + echo "Bad Request"; + exit(); + } +} + diff --git a/src/DatabaseManager/DatabaseConnector.php b/src/DatabaseManager/DatabaseConnector.php new file mode 100644 index 0000000..29649de --- /dev/null +++ b/src/DatabaseManager/DatabaseConnector.php @@ -0,0 +1,32 @@ +dbConnection = new \PDO( + "mysql:host=$host;port=$port;charset=utf8mb4;dbname=$db", + $user, + $pass + ); + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + + public function getConnection() + { + return $this->dbConnection; + } +} diff --git a/src/DatabaseManager/InventoryConnection.php b/src/DatabaseManager/InventoryConnection.php new file mode 100644 index 0000000..70050db --- /dev/null +++ b/src/DatabaseManager/InventoryConnection.php @@ -0,0 +1,102 @@ +db = $db; + } + + public function selectAll() + { + $stmt = " + SELECT + item, qty + FROM + $this->tbName + "; + + try { + $stmt = $this->db->prepare($stmt); + $stmt->execute(); + + return $stmt->fetchAll(\PDO::FETCH_ASSOC); + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + + /** + * @param $survivorId + * @return mixed + */ + public function selectBySurvivorId($survivorId) + { + $stmt = " + SELECT + item, qty + FROM + $this->tbName + WHERE id_survivor = :id_survivor; + "; + try { + $stmt = $this->db->prepare($stmt); + $stmt->bindParam(':id_survivor', $survivorId, \PDO::PARAM_INT); + $stmt->execute(); + + return $stmt->fetchAll(\PDO::FETCH_ASSOC); + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + + public function insert(array $input) + { + $stmt = " + INSERT INTO $this->tbName (id_survivor, item, qty) + VALUES (:id_survivor, :item, :qty); + "; + try { + $stmt = $this->db->prepare($stmt); + $stmt->execute( + [ + 'id_survivor' => $input['id_survivor'], + 'item' => $input['item'], + 'qty' => $input['qty'], + ] + ); + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + + public function update(array $input) + { + $stmt = " + UPDATE $this->tbName + SET + id_survivor = :id_survivor, + item = :item, + qty = :qty + WHERE + id_survivor = :id_survivor + AND + item = :item; + "; + try { + $stmt = $this->db->prepare($stmt); + $stmt->bindParam(':id_survivor', $input['id_survivor'], \PDO::PARAM_INT); + $stmt->bindParam(':item', $input['item'], \PDO::PARAM_STR); + $stmt->bindParam(':qty', $input['qty'], \PDO::PARAM_INT); + $stmt->execute(); + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + +} diff --git a/src/DatabaseManager/SurvivorConnection.php b/src/DatabaseManager/SurvivorConnection.php new file mode 100644 index 0000000..206b409 --- /dev/null +++ b/src/DatabaseManager/SurvivorConnection.php @@ -0,0 +1,117 @@ +db = $db; + } + + public function selectAll() + { + $stmt = " + SELECT + name, age, gender, location, infected, reported + FROM + $this->tbName + "; + + try { + $stmt = $this->db->prepare($stmt); + $stmt->execute(); + + return $stmt->fetchAll(\PDO::FETCH_ASSOC); + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + + public function selectByName($name) + { + $stmt = " + SELECT + id_survivor, name, age, gender, location, infected, reported + FROM + $this->tbName + WHERE + name = :name; + "; + + try { + $stmt = $this->db->prepare($stmt); + + $stmt->execute( + [ + 'name' => $name + ] + ); + return $stmt->fetchAll(\PDO::FETCH_ASSOC); + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + + public function insert(array $input) + { + $stmt = " + INSERT INTO $this->tbName (name, age, gender, location, infected, reported) + VALUES (:name, :age, :gender, :location, :infected, :reported); + "; + try { + $stmt = $this->db->prepare($stmt); + $stmt->execute( + [ + 'name' => $input['name'], + 'age' => $input['age'], + 'gender' => $input['gender'], + 'location' => $input['location'], + 'infected' => $input['infected'], + 'reported' => $input['reported'], + ] + ); + + return $stmt->rowCount(); + + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + + public function update(array $input) + { + $stmt = " + UPDATE $this->tbName + SET + name = :name, + age = :age, + gender = :gender, + location = :location, + infected = :infected, + reported = :reported + WHERE + name = :name; + "; + try { + $stmt = $this->db->prepare($stmt); + $stmt->execute( + [ + 'name' => $input['name'], + 'age' => $input['age'], + 'gender' => $input['gender'], + 'location' => $input['location'], + 'infected' => $input['infected'], + 'reported' => $input['reported'], + ] + ); + + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + +} diff --git a/src/DatabaseManager/TradePointsConnection.php b/src/DatabaseManager/TradePointsConnection.php new file mode 100644 index 0000000..7717504 --- /dev/null +++ b/src/DatabaseManager/TradePointsConnection.php @@ -0,0 +1,58 @@ +db = $db; + } + + public function selectAll() + { + $stmt = " + SELECT + item, points + FROM + $this->tbName + "; + + try { + $stmt = $this->db->prepare($stmt); + $stmt->execute(); + + return $stmt->fetchAll(\PDO::FETCH_ASSOC); + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } + + public function selectByItem($item) + { + $stmt = " + SELECT + item, points + FROM + $this->tbName + WHERE + item = :item; + "; + + try { + $stmt = $this->db->prepare($stmt); + $stmt->execute( + [ + 'item' => $item + ] + ); + + return $stmt->fetchAll(\PDO::FETCH_ASSOC); + } catch (\PDOException $e) { + exit($e->getMessage()); + } + } +} diff --git a/src/EntityDbHelper/DbHelper.php b/src/EntityDbHelper/DbHelper.php new file mode 100644 index 0000000..4b4112e --- /dev/null +++ b/src/EntityDbHelper/DbHelper.php @@ -0,0 +1,20 @@ +db = $dbClass->getConnection(); + } +} \ No newline at end of file diff --git a/src/EntityDbHelper/DbHelper/InventoryHelper.php b/src/EntityDbHelper/DbHelper/InventoryHelper.php new file mode 100644 index 0000000..6989110 --- /dev/null +++ b/src/EntityDbHelper/DbHelper/InventoryHelper.php @@ -0,0 +1,85 @@ +inventoryConnection = new InventoryConnection($this->db); + } + + /** + * @return mixed + */ + public function getAllInventories() + { + return $this->inventoryConnection->selectAll(); + } + + /** + * @param $survivorId + * @return mixed + */ + public function getInventoryBySurvivorId($survivorId) + { + return $this->inventoryConnection->selectBySurvivorId($survivorId); + } + + /** + * @param $inventory + * @return mixed + */ + public function addNewInventory($inventory) + { + $existInventory = $this->getInventoryBySurvivorId($inventory['id_survivor']); + if ($existInventory) { + header('HTTP/1.1 400 BAD REQUEST'); + echo "Inventory already exists, pick another survivor name"; + exit(); + } + + foreach ($inventory as $item) { + $this->inventoryConnection->insert($item); + } + } + + /** + * @param $inventory + * @return array + */ + public function getInventoryItemsQty($inventory): array + { + $itemQty = []; + foreach ($inventory as $value) { + $item = ''; + foreach ($value as $key => $val) { + if ($key == 'item') { + $item = $val; + } + if ($key == 'qty') { + $itemQty[$item] = $val; + } + } + } + + return $itemQty; + } + + public function updateInventory($inventory) + { + $this->inventoryConnection->update($inventory); + } + +} + diff --git a/src/EntityDbHelper/DbHelper/SurvivorHelper.php b/src/EntityDbHelper/DbHelper/SurvivorHelper.php new file mode 100644 index 0000000..9d9e1a7 --- /dev/null +++ b/src/EntityDbHelper/DbHelper/SurvivorHelper.php @@ -0,0 +1,60 @@ +survivorConnection = new SurvivorConnection($this->db); + } + + /** + * @return mixed + */ + public function getAllSurvivors() + { + return $this->survivorConnection->selectAll(); + } + + /** + * @param $name + * @return mixed + */ + public function getSurvivorByName($name) + { + return $this->survivorConnection->selectByName($name)[0]; + } + + /** + * @param $survivor + * @return mixed + */ + public function addNewSurvivor($survivor) + { + $existSurvivor = $this->getSurvivorByName($survivor['name']); + if ($existSurvivor) { + header('HTTP/1.1 400 BAD REQUEST'); + echo "Survivor already exists, pick another name"; + exit(); + } + + $this->survivorConnection->insert($survivor); + } + + public function updateSurvivor($survivor) + { + $this->survivorConnection->update($survivor); + } +} + diff --git a/src/EntityDbHelper/DbHelper/TradePointsHelper.php b/src/EntityDbHelper/DbHelper/TradePointsHelper.php new file mode 100644 index 0000000..66c3088 --- /dev/null +++ b/src/EntityDbHelper/DbHelper/TradePointsHelper.php @@ -0,0 +1,45 @@ +tradePointsConnection = new TradePointsConnection($this->db); + } + + /** + * @return mixed + */ + public function getAllTradePoints() + { + return $this->tradePointsConnection->selectAll(); + } + + public function getItemPoints($pointsTable) + { + $itemPoints = []; + foreach ($pointsTable as $value) { + $item = ''; + foreach ($value as $key => $val){ + if($key == 'item'){ + $item = $val ; + } + if($key == 'points'){ + $itemPoints[$item] = $val; + } + } + } + return $itemPoints; + } +} \ No newline at end of file