function() { exit(file_get_contents('editor.html')); }, 'renderList' => function ($id = NULL) { global $storage; if ( $storage['library'] === "" ) exit("No data yet!"); $library = json_decode($storage['library'], true); $listIds = array_column($library['lists'], 'id'); if ( array_search($id, $listIds) === false ) { header('Location: /list/'.$library['defaultListId']); exit(); } $tpl = new Mustache_Engine(['loader' => new Mustache_Loader_FilesystemLoader(PATH.'/templates')]); $minifier = new TinyHtmlMinifier([]); $templateData = new LibraryRenderer($library, (int) $id); exit($minifier->minify($tpl->render('view', $templateData))); }, 'exportCSV' => function ($id) { global $storage; if ( !isset($_COOKIE['lp']) || $_COOKIE['lp'] !== $storage['sessionCookie'] ) { response(401, 'Invalid session'); } else { $mgToWeight = function(int $value, string $unit) { if ( $unit === 'g' ) { return number_format(($value / 1000), 0); } elseif ( $unit === 'kg' ) { return number_format(($value / 1000000), 2); } }; $library = json_decode($storage['library'], true); $categoryIds = array_column($library['categories'], 'id'); $itemIds = array_column($library['items'], 'id'); $listIds = array_column($library['lists'], 'id'); $listId = array_search($id, $listIds); if ( $listId === false ) exit('List not found!'); $output = fopen('php://output', 'w'); $list = $library['lists'][$listId]; header('Content-type: text/csv'); fputcsv($output, ['name','category', 'description', 'qty', 'weight', 'unit', 'url', 'price', 'isWorn', 'isConsumable']); foreach ( $list['categoryIds'] as $id ) { $categoryId = array_search($id, $categoryIds); $category = $library['categories'][$categoryId]; foreach ( $category['categoryItems'] as $item ) { $itemId = array_search($item['itemId'], $itemIds); $item = array_merge($item, $library['items'][$itemId]); fputcsv($output, [ $item['name'], $category['name'], $item['description'], $item['qty'], $mgToWeight($item['weight'], $item['authorUnit']), $item['authorUnit'], $item['url'], $item['price'], (bool)$item['worn'], (bool)$item['consumable'], ]); } } fclose($output); } }, 'getLibrary' => function () { global $storage, $requestBody; if ( isset($_COOKIE['lp']) && $_COOKIE['lp'] === $storage['sessionCookie'] ) { response(200, NULL, [ 'library' => $storage['library'], 'syncToken' => $storage['syncToken'], ]); } if ( !isset($requestBody['password']) || md5($requestBody['password']) !== $storage['password'] ) { response(404, 'Incorrect credentials!'); } else { $storage['sessionCookie'] = bin2hex(random_bytes(40)); setcookie("lp", $storage['sessionCookie'], [ 'expires' => time() + 3600, 'path' => "/", 'domain' => $_SERVER['HTTP_HOST'], 'secure' => true ]); file_put_contents(STORAGE_PATH.'/storage.json', json_encode($storage)); response(200, NULL, [ 'library' => $storage['library'], 'syncToken' => $storage['syncToken'], ]); } }, 'saveLibrary' => function () { global $storage, $requestBody; if ( !isset($_COOKIE['lp']) || $_COOKIE['lp'] !== $storage['sessionCookie'] ) { response(401, 'Invalid session'); } else { if ( isset($requestBody['library']) && isset($requestBody['syncToken']) ) { if ( $storage['syncToken'] === $requestBody['syncToken'] ) { $storage['syncToken']++; $storage['library'] = $requestBody['library']; file_put_contents(STORAGE_PATH.'/storage.json', json_encode($storage)); response(200, 'success', [ 'syncToken' => $storage['syncToken'], ]); } else { response(400, 'Your list is out of date - please refresh your browser.'); } } else { response(400, 'Missing arguments!'); } } }, 'changePassword' => function () { global $storage, $requestBody; if ( !isset($_COOKIE['lp']) || $_COOKIE['lp'] !== $storage['sessionCookie'] ) { response(401, 'Invalid session'); } else { if ( isset($requestBody['currentPassword']) && isset($requestBody['newPassword']) ) { if ( md5($requestBody['currentPassword']) === $storage['password'] ) { $storage['password'] = md5($requestBody['newPassword']); file_put_contents(STORAGE_PATH.'/storage.json', json_encode($storage)); } else { response(400, 'Incorrect credentials!'); } } else { response(400, 'Missing arguments!'); } } }, ]; $requestBody = json_decode(file_get_contents('php://input'), true); if ( !file_exists(STORAGE_PATH . '/storage.json') ) { $storage = [ 'password' => 'ae2d699aca20886f6bed96a0425c6168', 'sessionCookie' => '', 'library' => "", 'syncToken' => 0, ]; } else { $storage = json_decode(file_get_contents(STORAGE_PATH . '/storage.json'), true); } Router::add('GET', '/', $endpoints['renderList']); Router::add('GET', '/list/([0-9]*)', $endpoints['renderList']); Router::add('GET', '/editor', $endpoints['editor']); Router::add('GET', '/login', $endpoints['editor']); Router::add('GET', '/csv/([0-9]*)', $endpoints['exportCSV']); Router::add('POST', '/getLibrary', $endpoints['getLibrary']); Router::add('POST', '/saveLibrary', $endpoints['saveLibrary']); Router::add('POST', '/changePassword', $endpoints['changePassword']); Router::pathNotFound(function() { header("Loctaion: /"); }); Router::run('/');