diff --git a/.gitignore b/.gitignore index 2085207..e6a4b2d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /vendor/ /.phpunit.result.cache .idea +/*.db diff --git a/index.php b/index.php index e64d476..794f850 100644 --- a/index.php +++ b/index.php @@ -17,6 +17,9 @@ use Lewisdale\Webmentions\Webmention; use Symfony\Component\HttpClient\HttpClient; $router = new Router(); +$gateway = new SqliteGateway("webmentions.db"); + +$apiController = new \Lewisdale\Webmentions\Api\WebmentionApi($gateway); $router->post("/send", function (Request $req, Response $response) { $mentioner = new Webmention(); @@ -30,11 +33,11 @@ $router->post("/send", function (Request $req, Response $response) { } }); -$router->post("/endpoint", function (Request $req, Response $response) { +$router->post("/endpoint", function (Request $req, Response $response) use ($gateway) { $source = $req->post['source']; $target = $req->post['target']; - $endpoint = new Endpoint(HttpClient::create(), new SqliteGateway("webmentions.db")); + $endpoint = new Endpoint(HttpClient::create(), $gateway); try { $endpoint->receiveWebmention($source, $target); @@ -57,4 +60,8 @@ $router->post("/endpoint", function (Request $req, Response $response) { }); $router->get('/', fn($req, $res) => "

Webmention server

"); + +$router->get('/api/webmentions', [$apiController, "list"]); +$router->get('/api/webmentions/(\d+)', [$apiController, "get"]); + $router->dispatch(); \ No newline at end of file diff --git a/src/Api/WebmentionApi.php b/src/Api/WebmentionApi.php new file mode 100644 index 0000000..d17d2b2 --- /dev/null +++ b/src/Api/WebmentionApi.php @@ -0,0 +1,43 @@ +query) ? $request->query["post"] : null; + $mentions = !empty($target) ? $this->gateway->getByPost($target) : $this->gateway->list(); + return $response->json($mentions); + } + + // Get a webmention by ID + public function get(Request $request, Response $response) + { + $id = (int)$request->params[0]; + + if ($id) { + $mention = $this->gateway->get($id); + + if ($mention) { + $response->status_code = StatusCode::Ok; + return $response->json($mention); + } + } + + $response->status_code = StatusCode::NotFound; + } +} \ No newline at end of file diff --git a/src/Gateways/SqliteGateway.php b/src/Gateways/SqliteGateway.php index 0bd34e0..361dd2f 100644 --- a/src/Gateways/SqliteGateway.php +++ b/src/Gateways/SqliteGateway.php @@ -100,18 +100,7 @@ class SqliteGateway extends WebmentionGatewayInterface $statement = $this->connection->prepare($sql); $statement->execute(["post" => $post]); - $mentions = []; - - while ($row = $statement->fetch(PDO::FETCH_ASSOC)) { - $mentions[] = new Webmention( - $row["id"], - $row["target"], - $row["source"], - MentionType::from($row["type"]), - $row["content"], - new Author((int)$row["author"]) - ); - } + $mentions = array_map([$this, 'map_row'], $statement->fetchAll(PDO::FETCH_ASSOC)); $statement->closeCursor(); return $mentions; @@ -226,7 +215,50 @@ class SqliteGateway extends WebmentionGatewayInterface $statement = $this->connection->prepare($sql); $statement->execute($values); - return $statement->fetchAll(); + return array_map([$this, 'map_row'], $statement->fetchAll()); + } + + public function list(): array + { + $sql = <<connection->query($sql); + $mentions = array_map([$this, 'map_row'], $statement->fetchAll(PDO::FETCH_ASSOC)); + $statement->closeCursor(); + return $mentions; + } + + private function map_row(array|false $row): ?Webmention + { + if ($row) { + return new Webmention( + $row["id"], + $row["target"], + $row["source"], + MentionType::from($row["type"]), + $row["content"], + new Author( + (int)$row["author"], + $row["author_name"], + $row["author_url"], + $row["author_photo"] + ) + ); + } + return null; } } diff --git a/src/Gateways/WebmentionGatewayInterface.php b/src/Gateways/WebmentionGatewayInterface.php index 0f318c6..9235ce3 100644 --- a/src/Gateways/WebmentionGatewayInterface.php +++ b/src/Gateways/WebmentionGatewayInterface.php @@ -17,4 +17,6 @@ abstract class WebmentionGatewayInterface abstract public function get(int $id): ?Webmention; abstract public function find(array $values): array; + + abstract public function list(): array; } \ No newline at end of file diff --git a/tests/Gateways/SqliteGatewayTest.php b/tests/Gateways/SqliteGatewayTest.php index e24b8cb..f3b964b 100644 --- a/tests/Gateways/SqliteGatewayTest.php +++ b/tests/Gateways/SqliteGatewayTest.php @@ -241,4 +241,65 @@ class SqliteGatewayTest extends TestCase $retrieved = $this->gateway->find(["author_name" => "Carl Weathers"]); $this->assertCount(2, $retrieved); } + + public function testCanListAllWebmentions() + { + $this->gateway->save(new Webmention( + null, + "https://a-target-url.com", + "https://a-source-url.com", + MentionType::Like, + "Liked this post", + new \Lewisdale\Webmentions\Models\Author( + null, + "Doreen Mifah", + "https://my-homepage.com", + "https://cdn.imgserver.com/400/400" + ) + )); + + $this->gateway->save(new Webmention( + null, + "https://a-target-url.com", + "https://a-source-url.com", + MentionType::Like, + "Liked this post", + new \Lewisdale\Webmentions\Models\Author( + null, + "Carl Weathers", + "https://carl-weathers.com", + "https://cdn.imgserver.com/400/400" + ) + )); + + $this->gateway->save(new Webmention( + null, + "https://a-target-url.com", + "https://a-source-url.com", + MentionType::Like, + "Liked this post", + new \Lewisdale\Webmentions\Models\Author( + null, + "Barry White", + "https://barry.white.com", + "https://cdn.imgserver.com/400/400" + ) + )); + + $this->gateway->save(new Webmention( + null, + "https://a-target-url.com", + "https://a-source-url.com", + MentionType::Reply, + "This was a cool post!", + new \Lewisdale\Webmentions\Models\Author( + null, + "Carl Weathers", + "https://carl-weathers.com", + "https://cdn.imgserver.com/400/400" + ) + )); + + $this->assertCount(4, $this->gateway->list()); + } }