diff --git a/index.php b/index.php
index 791c814..0b8dbf4 100644
--- a/index.php
+++ b/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 "
Hello world
";
+$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();
diff --git a/src/Router/Method.php b/src/Router/Method.php
index 2db42ed..eb42d43 100644
--- a/src/Router/Method.php
+++ b/src/Router/Method.php
@@ -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;
+ }
+ }
};
\ No newline at end of file
diff --git a/src/Router/Request.php b/src/Router/Request.php
index 80f4bb0..1447749 100644
--- a/src/Router/Request.php
+++ b/src/Router/Request.php
@@ -8,6 +8,7 @@ class Request {
public readonly string $uri,
public readonly Method $method,
public readonly array $post = [],
+ public readonly array $query = [],
) {}
}
diff --git a/src/Router/Router.php b/src/Router/Router.php
index 388af46..d47ef79 100644
--- a/src/Router/Router.php
+++ b/src/Router/Router.php
@@ -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);
+ }
}
?>
\ No newline at end of file
diff --git a/src/Router/StatusCode.php b/src/Router/StatusCode.php
index effe9a4..057224b 100644
--- a/src/Router/StatusCode.php
+++ b/src/Router/StatusCode.php
@@ -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,
+ };
+ }
}
?>
\ No newline at end of file
diff --git a/src/Webmention.php b/src/Webmention.php
index 9372fc3..078550a 100644
--- a/src/Webmention.php
+++ b/src/Webmention.php
@@ -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;