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());
+ }
}