Draft of API, including a DOCS-page

master
Eirik Th S 2021-08-06 00:24:44 +02:00
parent 1479893234
commit f5581d2490
5 changed files with 269 additions and 0 deletions

16
www/api/v1/.htaccess Normal file
View File

@ -0,0 +1,16 @@
#RewriteBase /
RewriteEngine On
#RewriteRule ^/v1/?([*a-zA-Z0-9_-]+)$ /api/index.php?slug1=$1 [L]
RewriteRule ^([*a-zA-Z0-9_-]+)(?:\/|)$ index.php?fi=$1 [L]
#RewriteRule ^([a-zA-Z0-9_-]+)/$ index.php?slug=$1 [L]
#RewriteRule ^project/$ projects/index.php [L]
#RewriteRule ^projects/$ projects/index.php [L]
#RewriteRule ^v1/?([a-zA-Z0-9_-]+)$ index.php?project=$1 [L]
#RewriteRule ^project/?([a-zA-Z0-9_-]+)/$ projects/index.php?project=$1 [L]
#RewriteRule ^project/?([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ projects/index.php?project=$1&item=$2 [L]
#RewriteRule ^project/?([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/$ projects/index.php?project=$1&item=$2 [L]
#RewriteRule ^project/?([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ projects/index.php?project=$1&item=$2&ID=$3 [L]
#RewriteRule ^project/?([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/$ projects/index.php?project=$1&item=$2&ID=$3 [L]

41
www/api/v1/api-init.php Normal file
View File

@ -0,0 +1,41 @@
<?php
require '../../webdata/init.php';
header("Content-Type: application/json");
if(!checkLogin()){
returns("Not logged in",2);
}
$user_id = $_SESSION['user_id'];
function returns($content = 'Success', $code = 0){
if($code != 0 || $content == 'Success'){
$returns['status'] = $code;
$returns['message'] = $content;
}
else {
$returns['data'] = $content;
}
echo json_encode($returns);
die();
}
function sanitize(): array{
global $_GET, $_POST;
$data = array();
foreach([$_GET, $_POST] as $request){
if(!empty($request)){
foreach($request as $key => $value){
if(($data[$key] = filter($value)) === false){
print_r($value);
echo "Failed to sanitize: `".$key."`: ".$value." \t-\t type: ".gettype($value)."\n";
}
}
}
}
return $data;
}

123
www/api/v1/docs.php Normal file
View File

@ -0,0 +1,123 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$docs['general'][] = array("method"=>'GET', "href"=>"/", "name"=>"Nothing", "body"=>"{}");
$docs['recipe'][] = array("method"=>'GET', "href"=>"/recipe", "name"=>"Get all available recipes", "body"=>"{}");
$docs['recipe'][] = array("method"=>'POST', "href"=>"/recipe", "name"=>"Create recipe", "body"=>"{\n \"name\": \"string\",\n \"portions\": \"integer\",\n \"public\": \"boolean\" \n}");
function capitalizeFirst($input){
$input[0] = strtoupper($input[0]);
return $input;
}
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<link rel='stylesheet' href='/css/bootstrap.min.css' type='text/css' />
<link rel='stylesheet' href='/css/index.css' type='text/css' />
<script src='/js/jquery-3.5.1.min.js'></script>
<script src='/js/popper.min.js'></script>
<script src='/js/bootstrap.min.js'></script>
<!--<script src='//cdn.jsdelivr.net/npm/marked/marked.min.js'></script>-->
<script src='/js/hammer.js'></script>
<script src='/js/hammer.jquery.js'></script>
<title>PaperBag API Docs</title>
</head>
<body>
<div class="container-md">
<h1>PaperBag API Docs</h1>
<div class="accordion mb-2" id="apiContents">
<?php
$count = 0;
foreach ($docs as $group=>$rows){
echo "<div><h2>".capitalizeFirst($group)."</h2></div>";
foreach ($rows as $k => $row){
$i = $count;
$count++;
switch ($row['method']){
case 'GET':
$methodClass = "bg-primary";
break;
case 'POST':
$methodClass = "bg-success";
break;
default:
$methodClass = "bg-warning";
}
?>
<div class="accordion-item">
<h2 class="accordion-header" id="heading<?=$i;?>">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapse<?=$i;?>" aria-expanded="true" aria-controls="collapse<?=$i;?>">
<div class="badge <?=$methodClass;?>" style="margin-right: 5px;"><?=$row['method'];?></div>
<div style="font-family: var(--bs-font-monospace); margin-right: 5px;"><?=$row['href'];?></div>
<div><strong><?=$row['name'];?></strong></div>
</button>
</h2>
<div id="collapse<?=$i;?>" class="accordion-collapse collapse" aria-labelledby="heading<?=$i;?>" data-bs-parent="#apiContents">
<div class="accordion-body">
<div class="apiBodyHolder" style="display: none;"><?=$row['body'];?></div>
<form class="apiExec">
<div class="row row-cols-2">
<div>
<input class="form-control" type="hidden" id="url" name="url" value="<?=$row['href'];?>">
<textarea class="form-control" class="apiBody" name="apiBody"><?=$row['body'];?></textarea>
<input type="submit">
</div>
<div class="apiExecResponse"></div>
</div>
</form>
</div>
</div>
</div>
<?php }
} ?>
</div>
</div>
<script>
$(".apiExec").on('submit', ev=>{
ev.preventDefault();
let formElem = $(ev.currentTarget);
let params = formElem.serializeArray();
let url = "."+params[0].value;
let body = JSON.parse( params[1].value );
if(url.length > 0 && typeof body === "object"){
$.post(url, body, resp => {
console.log(resp);
let response = JSON.stringify(resp, null, 4);
formElem.find(".apiExecResponse").html("<pre><code>"+response+"</code></pre>");
});
}
});
$('.accordion-collapse').on('show.bs.collapse', ev=>{
let currElem = $(ev.currentTarget);
let textarea = currElem.find('textarea');
textarea.val( currElem.find('.apiBodyHolder').html() );
setTimeout(()=> {
textarea.height( (textarea[0].scrollHeight)-12 );
}, 10);
});
</script>
</body>
</html>

47
www/api/v1/index.php Normal file
View File

@ -0,0 +1,47 @@
<?php
require 'api-init.php';
$db = database();
$data = sanitize();
$group = "";
if(isset($data['fi'])){
$group = $data['fi'];
}
elseif(isset($data['recipes'])){
$group = "recipe";
}
switch ($group){
case "recipe":
include 'recipes.php';
if(!empty($_POST)){
// CREATE RECIPE
if(isset($data['name']) && $data['name'] != "string"){
if($newID = Recipes::createRecipe($data['name'], $data['portions'], $data['public'])){
returns("OK: ".$newID);
}
else {
returns($db->error, 1);
}
}
}
else {
returns(Recipes::getAll());
}
break;
case "plan":
returns("Coming soon...");
break;
default:
returns('Nothing to do');
}
returns('Failed.',2);
$docs['recipe'][] = array("method"=>'POST', "href"=>"/recipe", "name"=>"Create recipe", "body"=>"{\n \"name\": \"string\",\n \"public\": \"boolean\" \n}");

42
www/api/v1/recipes.php Normal file
View File

@ -0,0 +1,42 @@
<?php
class Recipes {
// function __construct($recipeID = 0){
static function getAll(): array{
global $user_id, $db;
$return = array();
$sql = "SELECT * FROM recipe WHERE public = 1 OR author = $user_id;";
$res = $db->query($sql);
while($row = $res->fetch_assoc()){
$return[$row['recipe_id']] = $row;
// $return[$row['recipe_id']]['items'] = ;
}
if(empty($return)){
$return[] = "No recipes found";
}
return $return;
}
static function createRecipe($name, $portions = 1, $public = 0) {
global $user_id, $db;
if($portions == null){
$portions = 1;
}
if(strlen($name) <= 200 && is_numeric($public)){
$createRecipeSQL = "INSERT INTO `recipe` (name, author, portions, public) VALUES ('$name', $user_id, $portions, $public);";
if($db->query($createRecipeSQL)){
return $db->insert_id;
}
}
return false;
}
}