Add a rudimentary API endpoint. TODO: Add auth to the API
This commit is contained in:
parent
ec83d67bde
commit
7dc9d0a5cb
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
/vendor/
|
/vendor/
|
||||||
/.phpunit.result.cache
|
/.phpunit.result.cache
|
||||||
.idea
|
.idea
|
||||||
|
/*.db
|
||||||
|
11
index.php
11
index.php
@ -17,6 +17,9 @@ use Lewisdale\Webmentions\Webmention;
|
|||||||
use Symfony\Component\HttpClient\HttpClient;
|
use Symfony\Component\HttpClient\HttpClient;
|
||||||
|
|
||||||
$router = new Router();
|
$router = new Router();
|
||||||
|
$gateway = new SqliteGateway("webmentions.db");
|
||||||
|
|
||||||
|
$apiController = new \Lewisdale\Webmentions\Api\WebmentionApi($gateway);
|
||||||
|
|
||||||
$router->post("/send", function (Request $req, Response $response) {
|
$router->post("/send", function (Request $req, Response $response) {
|
||||||
$mentioner = new Webmention();
|
$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'];
|
$source = $req->post['source'];
|
||||||
$target = $req->post['target'];
|
$target = $req->post['target'];
|
||||||
|
|
||||||
$endpoint = new Endpoint(HttpClient::create(), new SqliteGateway("webmentions.db"));
|
$endpoint = new Endpoint(HttpClient::create(), $gateway);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$endpoint->receiveWebmention($source, $target);
|
$endpoint->receiveWebmention($source, $target);
|
||||||
@ -57,4 +60,8 @@ $router->post("/endpoint", function (Request $req, Response $response) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$router->get('/', fn($req, $res) => "<h1>Webmention server</h1>");
|
$router->get('/', fn($req, $res) => "<h1>Webmention server</h1>");
|
||||||
|
|
||||||
|
$router->get('/api/webmentions', [$apiController, "list"]);
|
||||||
|
$router->get('/api/webmentions/(\d+)', [$apiController, "get"]);
|
||||||
|
|
||||||
$router->dispatch();
|
$router->dispatch();
|
43
src/Api/WebmentionApi.php
Normal file
43
src/Api/WebmentionApi.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Lewisdale\Webmentions\Api;
|
||||||
|
|
||||||
|
use Lewisdale\Webmentions\Gateways\WebmentionGatewayInterface;
|
||||||
|
use Lewisdale\Webmentions\Router\Request;
|
||||||
|
use Lewisdale\Webmentions\Router\Response;
|
||||||
|
use Lewisdale\Webmentions\Router\StatusCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API Controller for retrieving Webmentions
|
||||||
|
*/
|
||||||
|
class WebmentionApi
|
||||||
|
{
|
||||||
|
function __construct(private readonly WebmentionGatewayInterface $gateway)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// List Webmentions. Optionally filter by target.
|
||||||
|
public function list(Request $request, Response $response)
|
||||||
|
{
|
||||||
|
$target = array_key_exists("post", $request->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;
|
||||||
|
}
|
||||||
|
}
|
@ -100,18 +100,7 @@ class SqliteGateway extends WebmentionGatewayInterface
|
|||||||
$statement = $this->connection->prepare($sql);
|
$statement = $this->connection->prepare($sql);
|
||||||
$statement->execute(["post" => $post]);
|
$statement->execute(["post" => $post]);
|
||||||
|
|
||||||
$mentions = [];
|
$mentions = array_map([$this, 'map_row'], $statement->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
|
||||||
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"])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$statement->closeCursor();
|
$statement->closeCursor();
|
||||||
|
|
||||||
return $mentions;
|
return $mentions;
|
||||||
@ -226,7 +215,50 @@ class SqliteGateway extends WebmentionGatewayInterface
|
|||||||
$statement = $this->connection->prepare($sql);
|
$statement = $this->connection->prepare($sql);
|
||||||
$statement->execute($values);
|
$statement->execute($values);
|
||||||
|
|
||||||
return $statement->fetchAll();
|
return array_map([$this, 'map_row'], $statement->fetchAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function list(): array
|
||||||
|
{
|
||||||
|
$sql = <<<SQL
|
||||||
|
SELECT webmentions.id as id,
|
||||||
|
webmentions.source as source,
|
||||||
|
webmentions.target as target,
|
||||||
|
webmentions.type as type,
|
||||||
|
webmentions.content as content,
|
||||||
|
authors.id as author,
|
||||||
|
authors.name as author_name,
|
||||||
|
authors.url as author_url,
|
||||||
|
authors.photo as author_photo
|
||||||
|
FROM webmentions
|
||||||
|
LEFT JOIN
|
||||||
|
authors ON webmentions.author=authors.id
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
$statement = $this->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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,4 +17,6 @@ abstract class WebmentionGatewayInterface
|
|||||||
abstract public function get(int $id): ?Webmention;
|
abstract public function get(int $id): ?Webmention;
|
||||||
|
|
||||||
abstract public function find(array $values): array;
|
abstract public function find(array $values): array;
|
||||||
|
|
||||||
|
abstract public function list(): array;
|
||||||
}
|
}
|
@ -241,4 +241,65 @@ class SqliteGatewayTest extends TestCase
|
|||||||
$retrieved = $this->gateway->find(["author_name" => "Carl Weathers"]);
|
$retrieved = $this->gateway->find(["author_name" => "Carl Weathers"]);
|
||||||
$this->assertCount(2, $retrieved);
|
$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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user