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";
|
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\Router;
|
||||||
use Lewisdale\Webmentions\Router\Response;
|
use Lewisdale\Webmentions\Router\Response;
|
||||||
|
use Lewisdale\Webmentions\Router\StatusCode;
|
||||||
use Lewisdale\Webmentions\Webmention;
|
use Lewisdale\Webmentions\Webmention;
|
||||||
|
|
||||||
$mentioner = new Webmention();
|
$mentioner = new Webmention();
|
||||||
|
|
||||||
// $mentioner->sendForPage("https://lewisdale.dev/post/bringing-my-omg-lol-now-page-into-eleventy/");
|
|
||||||
|
|
||||||
$router = new Router();
|
$router = new Router();
|
||||||
|
|
||||||
$router->get("/send", function($req, Response $response) {
|
$router->post("/send", function(Request $req, Response $response) use ($webmention) {
|
||||||
return "<h1>Hello world</h1>";
|
$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();
|
$router->dispatch();
|
||||||
|
@ -8,4 +8,14 @@ enum Method {
|
|||||||
|
|
||||||
// Fallback method
|
// Fallback method
|
||||||
case UNKNOWN;
|
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 string $uri,
|
||||||
public readonly Method $method,
|
public readonly Method $method,
|
||||||
public readonly array $post = [],
|
public readonly array $post = [],
|
||||||
|
public readonly array $query = [],
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,33 @@
|
|||||||
|
|
||||||
namespace Lewisdale\Webmentions\Router;
|
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 {
|
class Router {
|
||||||
private array $routes;
|
private array $routes;
|
||||||
|
|
||||||
@ -25,30 +52,16 @@ class Router {
|
|||||||
$this->routes[] = new Route(Method::POST, $this->format_route($route), $fn);
|
$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 {
|
private function get_params(array $matches): array {
|
||||||
array_shift($matches);
|
return array_map(
|
||||||
$results = array();
|
function($match) { return $match[0]; },
|
||||||
|
array_shift($matches)
|
||||||
foreach ($matches as $match) {
|
);
|
||||||
$results[] = $match[0];
|
|
||||||
}
|
|
||||||
return $results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function dispatch() {
|
public function dispatch() {
|
||||||
$uri = $_SERVER['REQUEST_URI'];
|
$uri = $_SERVER['REQUEST_URI'];
|
||||||
$method = $this->method_to_enum($_SERVER['REQUEST_METHOD']);
|
$method = Method::from($_SERVER['REQUEST_METHOD']);
|
||||||
|
|
||||||
$num_matched = 0;
|
$num_matched = 0;
|
||||||
|
|
||||||
@ -61,8 +74,13 @@ class Router {
|
|||||||
$num_matched++;
|
$num_matched++;
|
||||||
$fn = $route->fn;
|
$fn = $route->fn;
|
||||||
$params = $this->get_params($matches);
|
$params = $this->get_params($matches);
|
||||||
$response->status_code = StatusCode::Ok;
|
$response->status_code = StatusCode::Ok; // Default status code to OK for the "average" route
|
||||||
$response->body .= $fn(new Request($params, $uri, $method, $_POST), $response);
|
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);
|
$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) {
|
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;
|
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 Redirect;
|
||||||
case InternalError;
|
case InternalError;
|
||||||
case BadRequest;
|
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;
|
namespace Lewisdale\Webmentions;
|
||||||
|
|
||||||
use Lewisdale\Webmentions\Gateways\WebmentionGatewayInterface;
|
|
||||||
use Symfony\Component\DomCrawler\Crawler;
|
use Symfony\Component\DomCrawler\Crawler;
|
||||||
use Symfony\Component\HttpClient\HttpClient;
|
use Symfony\Component\HttpClient\HttpClient;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
Loading…
Reference in New Issue
Block a user