Extend router a little, add routes for sending and receiving webmentions
This commit is contained in:
parent
10b6ace85a
commit
83ec00c8a0
31
index.php
31
index.php
@ -2,18 +2,41 @@
|
||||
|
||||
require_once __DIR__ . "/vendor/autoload.php";
|
||||
|
||||
use Lewisdale\Webmentions\Endpoint;
|
||||
use Lewisdale\Webmentions\Exceptions\InvalidTargetException;
|
||||
use Lewisdale\Webmentions\Exceptions\InvalidUrlException;
|
||||
use Lewisdale\Webmentions\Router\Request;
|
||||
use Lewisdale\Webmentions\Router\Router;
|
||||
use Lewisdale\Webmentions\Router\Response;
|
||||
use Lewisdale\Webmentions\Router\StatusCode;
|
||||
use Lewisdale\Webmentions\Webmention;
|
||||
|
||||
$mentioner = new Webmention();
|
||||
|
||||
// $mentioner->sendForPage("https://lewisdale.dev/post/bringing-my-omg-lol-now-page-into-eleventy/");
|
||||
|
||||
$router = new Router();
|
||||
|
||||
$router->get("/send", function($req, Response $response) {
|
||||
return "<h1>Hello world</h1>";
|
||||
$router->post("/send", function(Request $req, Response $response) use ($webmention) {
|
||||
$source = $req->query["source"];
|
||||
$webmention->sendForPage($source);
|
||||
});
|
||||
|
||||
$router->post("/endpoint", function(Request $req, Response $response) {
|
||||
$source = $req->post['source'];
|
||||
$target = $req->post['target'];
|
||||
|
||||
$endpoint = new Endpoint();
|
||||
|
||||
try {
|
||||
$endpoint->receiveWebmention($source, $target);
|
||||
} catch (InvalidUrlException $e) {
|
||||
$response->status_code = StatusCode::BadRequest;
|
||||
return "Source and target must be valid URLs";
|
||||
} catch (InvalidTargetException $e) {
|
||||
$response->status_code = StatusCode::BadRequest;
|
||||
return "Target must be on the domain lewisdale.dev";
|
||||
}
|
||||
|
||||
$response->status_code = StatusCode::Created;
|
||||
});
|
||||
|
||||
$router->dispatch();
|
||||
|
@ -8,4 +8,14 @@ enum Method {
|
||||
|
||||
// Fallback method
|
||||
case UNKNOWN;
|
||||
|
||||
public static function from(string $str) : self
|
||||
{
|
||||
switch ($str)
|
||||
{
|
||||
case "GET": return Method::GET;
|
||||
case "POST": return Method::POST;
|
||||
default: return METHOD::UNKNOWN;
|
||||
}
|
||||
}
|
||||
};
|
@ -8,6 +8,7 @@ class Request {
|
||||
public readonly string $uri,
|
||||
public readonly Method $method,
|
||||
public readonly array $post = [],
|
||||
public readonly array $query = [],
|
||||
) {}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,33 @@
|
||||
|
||||
namespace Lewisdale\Webmentions\Router;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* This is a dumb, custom Router I slapped together as a way of reminding myself how to PHP.
|
||||
*
|
||||
* It's not great, and currently on supports two methods: GET and POST.
|
||||
*
|
||||
* Usage is as follows:
|
||||
*
|
||||
* ```
|
||||
* $router = new Lewisdale\Webmentions\Router\Router();
|
||||
* $router->get('/a/get/route', function($request, $response) {
|
||||
* $response->status_code = StatusCode::OK;
|
||||
* return "Hello world!";
|
||||
* });
|
||||
*
|
||||
* $router->get('/a/json/route', function($request, $response) {
|
||||
* return $response->json(new MyClass());
|
||||
* });
|
||||
*
|
||||
* $router->dispatch();
|
||||
* ```
|
||||
*
|
||||
* TL;DR? Don't use this. There are some good routing libraries already.
|
||||
*
|
||||
* But if you're reading this, it's already too late.
|
||||
*/
|
||||
class Router {
|
||||
private array $routes;
|
||||
|
||||
@ -25,30 +52,16 @@ class Router {
|
||||
$this->routes[] = new Route(Method::POST, $this->format_route($route), $fn);
|
||||
}
|
||||
|
||||
private function method_to_enum(string $method): Method {
|
||||
switch ($method) {
|
||||
case "GET":
|
||||
return Method::GET;
|
||||
case "POST":
|
||||
return Method::POST;
|
||||
default:
|
||||
return Method::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private function get_params(array $matches): array {
|
||||
array_shift($matches);
|
||||
$results = array();
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$results[] = $match[0];
|
||||
}
|
||||
return $results;
|
||||
return array_map(
|
||||
function($match) { return $match[0]; },
|
||||
array_shift($matches)
|
||||
);
|
||||
}
|
||||
|
||||
public function dispatch() {
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
$method = $this->method_to_enum($_SERVER['REQUEST_METHOD']);
|
||||
$method = Method::from($_SERVER['REQUEST_METHOD']);
|
||||
|
||||
$num_matched = 0;
|
||||
|
||||
@ -61,8 +74,13 @@ class Router {
|
||||
$num_matched++;
|
||||
$fn = $route->fn;
|
||||
$params = $this->get_params($matches);
|
||||
$response->status_code = StatusCode::Ok;
|
||||
$response->body .= $fn(new Request($params, $uri, $method, $_POST), $response);
|
||||
$response->status_code = StatusCode::Ok; // Default status code to OK for the "average" route
|
||||
try {
|
||||
$response->body .= $fn($this->construct_request_object($params), $response);
|
||||
} catch (Exception) {
|
||||
$response->status_code = StatusCode::InternalError;
|
||||
// TODO: Log the error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,28 +93,22 @@ class Router {
|
||||
$this->respond($response);
|
||||
}
|
||||
|
||||
private function map_status_code(StatusCode $code): int {
|
||||
switch ($code) {
|
||||
case StatusCode::NotFound:
|
||||
return 404;
|
||||
case StatusCode::Ok:
|
||||
return 200;
|
||||
case StatusCode::InternalError:
|
||||
return 500;
|
||||
case StatusCode::Redirect:
|
||||
return 300;
|
||||
case StatusCode::BadRequest:
|
||||
return 400;
|
||||
default:
|
||||
return 501;
|
||||
}
|
||||
}
|
||||
|
||||
private function respond(Response $response) {
|
||||
http_response_code($this->map_status_code($response->status_code));
|
||||
http_response_code($response->status_code->code());
|
||||
|
||||
echo $response->body;
|
||||
}
|
||||
|
||||
private function construct_request_object(array $params)
|
||||
{
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
$method = Method::from($_SERVER['REQUEST_METHOD']);
|
||||
$query = $_GET;
|
||||
$post = $_POST;
|
||||
|
||||
return new Request($params, $uri, $method, $post, $query);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -8,6 +8,19 @@ enum StatusCode {
|
||||
case Redirect;
|
||||
case InternalError;
|
||||
case BadRequest;
|
||||
case Created;
|
||||
|
||||
public function code() : int
|
||||
{
|
||||
return match($this) {
|
||||
StatusCode::NotFound => 404,
|
||||
StatusCode::Ok => 200,
|
||||
StatusCode::InternalError => 500,
|
||||
StatusCode::Redirect => 301,
|
||||
StatusCode::BadRequest => 400,
|
||||
StatusCode::Created => 201,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace Lewisdale\Webmentions;
|
||||
|
||||
use Lewisdale\Webmentions\Gateways\WebmentionGatewayInterface;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
Loading…
Reference in New Issue
Block a user