mirror of
https://github.com/sigmasternchen/drnk.me
synced 2025-03-15 09:48:54 +00:00
feat: Add endpoint for adding new URLs
This commit is contained in:
parent
1f7932d505
commit
411491f7f5
4 changed files with 90 additions and 9 deletions
53
controllers/manage/POST.php
Normal file
53
controllers/manage/POST.php
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(ROOT . "/utils/error.php");
|
||||||
|
|
||||||
|
const CANDIDATES_PER_ITERATION = 10;
|
||||||
|
const MIN_LENGTH = 3;
|
||||||
|
const MAX_LENGTH = 20;
|
||||||
|
|
||||||
|
function generate_candidate($length) {
|
||||||
|
$charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
|
||||||
|
return join("",
|
||||||
|
array_map(
|
||||||
|
fn($_) => $charset[rand(0, strlen($charset) - 1)],
|
||||||
|
range(1, $length)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return function (array &$context) {
|
||||||
|
$url = $_POST["url"] ?? "";
|
||||||
|
|
||||||
|
if (!$url) {
|
||||||
|
setStatusCode(400);
|
||||||
|
echo json_encode(
|
||||||
|
errorResponse("URL missing", "Please provide a URL.")
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$repository = $context[REPOSITORIES]->urls;
|
||||||
|
|
||||||
|
$candidates = [];
|
||||||
|
for ($length = MIN_LENGTH; count($candidates) == 0 || $length > MAX_LENGTH; $length++) {
|
||||||
|
$candidates = $repository->getUnusedSlugs(
|
||||||
|
array_map(
|
||||||
|
fn($_) => generate_candidate($length),
|
||||||
|
range(1, CANDIDATES_PER_ITERATION)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$slug = $candidates[0];
|
||||||
|
$accessKey = sha1($url . "-" . $url . "-" . microtime() . "-" . rand());
|
||||||
|
|
||||||
|
$result = $context[REPOSITORIES]->urls->add(new URL(
|
||||||
|
$slug,
|
||||||
|
$url,
|
||||||
|
$accessKey
|
||||||
|
));
|
||||||
|
|
||||||
|
echo json_encode($result);
|
||||||
|
};
|
|
@ -13,6 +13,7 @@ function fromController(string $path, string $endpoint = null) {
|
||||||
|
|
||||||
return function(Router $router) {
|
return function(Router $router) {
|
||||||
$router->addRoute(GET, "/", fromController("/GET"));
|
$router->addRoute(GET, "/", fromController("/GET"));
|
||||||
|
$router->addRoute(POST, "/manage", fromController("/manage/POST"));
|
||||||
|
|
||||||
$router->addRoute(GET, "/.*", fromController("/slug/GET"));
|
$router->addRoute(GET, "/.*", fromController("/slug/GET"));
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,6 +22,40 @@ class URLs {
|
||||||
$entry->url,
|
$entry->url,
|
||||||
$entry->accessKey,
|
$entry->accessKey,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
return $this->getById($this->connection->lastInsertId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUnusedSlugs(array $slugs) {
|
||||||
|
$placeholderList = join(",", array_map(fn($_) => "?", $slugs));
|
||||||
|
|
||||||
|
$statement = $this->connection->prepare(<<<EOF
|
||||||
|
SELECT `slug` FROM `$this->table`
|
||||||
|
WHERE `slug` IN ($placeholderList)
|
||||||
|
EOF);
|
||||||
|
$statement->execute($slugs);
|
||||||
|
|
||||||
|
$existing = $statement->fetchAll(PDO::FETCH_COLUMN, 0);
|
||||||
|
|
||||||
|
return array_values(array_diff($slugs, $existing));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function entityFromRow($row) {
|
||||||
|
$url = new URL($row["slug"], $row["url"], $row["access_key"]);
|
||||||
|
$url->id = $row["id"];
|
||||||
|
$url->created = new DateTime($row["created"]);
|
||||||
|
$url->updated = new DateTime($row["updated"]);
|
||||||
|
$url->deleted = ($row["deleted"]) ? new DateTime($row["deleted"]) : null;
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getById(int $id) {
|
||||||
|
$statement = $this->connection->prepare(<<<EOF
|
||||||
|
SELECT * FROM `$this->table` WHERE `id` = ?
|
||||||
|
EOF);
|
||||||
|
$statement->execute([$id]);
|
||||||
|
return $this->entityFromRow($statement->fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBySlug(string $slug) {
|
public function getBySlug(string $slug) {
|
||||||
|
@ -34,14 +68,7 @@ class URLs {
|
||||||
if ($statement->rowCount() == 0) {
|
if ($statement->rowCount() == 0) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
$row = $statement->fetch();
|
return $this->entityFromRow($statement->fetch());
|
||||||
$url = new URL($row["slug"], $row["url"], $row["access_key"]);
|
|
||||||
$url->id = $row["id"];
|
|
||||||
$url->created = new DateTime($row["created"]);
|
|
||||||
$url->updated = new DateTime($row["updated"]);
|
|
||||||
$url->deleted = ($row["deleted"]) ? new DateTime($row["deleted"]) : null;
|
|
||||||
|
|
||||||
return $url;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ require(__DIR__ . "/../layout/top.php");
|
||||||
<img class="bottle" src="/static/img/bottle.png" alt="picture of a vile with a tag 'Drnk Me'" />
|
<img class="bottle" src="/static/img/bottle.png" alt="picture of a vile with a tag 'Drnk Me'" />
|
||||||
|
|
||||||
<div class="center-panel">
|
<div class="center-panel">
|
||||||
<form action="?create" method="POST">
|
<form action="/manage" method="POST">
|
||||||
<input type="text" name="url" placeholder="<?php echo $data["url"] ?? "URL" ?>">
|
<input type="text" name="url" placeholder="<?php echo $data["url"] ?? "URL" ?>">
|
||||||
<input type="submit" value="Submit">
|
<input type="submit" value="Submit">
|
||||||
</form>
|
</form>
|
||||||
|
|
Loading…
Reference in a new issue