Store authors alongside webmentions
This commit is contained in:
parent
3cafc5238e
commit
51f1269600
@ -21,13 +21,22 @@ class SqliteGateway extends WebmentionGatewayInterface
|
||||
{
|
||||
// Create Webmention table
|
||||
$sql = <<<SQL
|
||||
PRAGMA foreign_keys = ON;
|
||||
CREATE TABLE IF NOT EXISTS authors (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
url TEXT,
|
||||
photo TEXT,
|
||||
UNIQUE(name, url)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS webmentions (
|
||||
id INTEGER PRIMARY KEY,
|
||||
target TEXT NOT NULL,
|
||||
source TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
content TEXT,
|
||||
author INTEGER
|
||||
author INTEGER,
|
||||
FOREIGN KEY(author) REFERENCES authors(id)
|
||||
);
|
||||
SQL;
|
||||
|
||||
@ -36,7 +45,22 @@ class SqliteGateway extends WebmentionGatewayInterface
|
||||
|
||||
public function get(int $id): ?Webmention
|
||||
{
|
||||
$sql = "SELECT * FROM webmentions WHERE id=:id LIMIT 1;";
|
||||
$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
|
||||
WHERE webmentions.id=:id
|
||||
LIMIT 1;
|
||||
SQL;
|
||||
$statement = $this->connection->prepare($sql);
|
||||
$statement->execute(["id" => $id]);
|
||||
$row = $statement->fetch(PDO::FETCH_ASSOC);
|
||||
@ -49,7 +73,7 @@ class SqliteGateway extends WebmentionGatewayInterface
|
||||
$row["source"],
|
||||
MentionType::from($row["type"]),
|
||||
$row["content"],
|
||||
new Author((int)$row["author"])
|
||||
new Author((int)$row["author"], $row["author_name"], $row["author_url"], $row["author_photo"])
|
||||
);
|
||||
}
|
||||
|
||||
@ -58,7 +82,21 @@ class SqliteGateway extends WebmentionGatewayInterface
|
||||
|
||||
public function getByPost(string $post): array
|
||||
{
|
||||
$sql = "SELECT * FROM webmentions WHERE target=:post";
|
||||
$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
|
||||
WHERE target=:post;
|
||||
SQL;
|
||||
$statement = $this->connection->prepare($sql);
|
||||
$statement->execute(["post" => $post]);
|
||||
|
||||
@ -81,8 +119,10 @@ class SqliteGateway extends WebmentionGatewayInterface
|
||||
|
||||
public function save(Webmention $webmention): ?int
|
||||
{
|
||||
$author = $this->saveAuthor($webmention->author);
|
||||
|
||||
$sql = <<< SQL
|
||||
INSERT INTO webmentions
|
||||
REPLACE INTO webmentions
|
||||
(id, target, source, type, content, author)
|
||||
VALUES
|
||||
(:id, :target, :source, :type, :content, :author);
|
||||
@ -95,13 +135,65 @@ class SqliteGateway extends WebmentionGatewayInterface
|
||||
"source" => $webmention->source,
|
||||
"type" => $webmention->type->toString(),
|
||||
"content" => $webmention->content,
|
||||
"author" => $webmention->author->id,
|
||||
"author" => $author,
|
||||
]);
|
||||
|
||||
$statement->closeCursor();
|
||||
|
||||
return $success ? (int)$this->connection->lastInsertId() : null;
|
||||
}
|
||||
|
||||
protected function saveAuthor(Author $author): ?int
|
||||
{
|
||||
if (!$author->name || !$author->url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sql = <<< SQL
|
||||
INSERT OR IGNORE INTO authors
|
||||
(id, name, url, photo)
|
||||
VALUES
|
||||
(:id, :name, :url, :photo);
|
||||
SQL;
|
||||
|
||||
$statement = $this->connection->prepare($sql);
|
||||
$success = $statement->execute([
|
||||
"id" => $author->id,
|
||||
"name" => $author->name,
|
||||
"url" => $author->url,
|
||||
"photo" => $author->photo,
|
||||
]);
|
||||
$statement->closeCursor();
|
||||
|
||||
return $this->findAuthor($author->name, $author->url)?->id;
|
||||
}
|
||||
|
||||
protected function findAuthor(string $name, string $url): ?Author
|
||||
{
|
||||
|
||||
$sql = "SELECT id, name, url, photo FROM authors WHERE url=:url AND name=:name";
|
||||
$statement = $this->connection->prepare($sql);
|
||||
|
||||
$success = $statement->execute([
|
||||
"url" => $url,
|
||||
"name" => $name,
|
||||
]);
|
||||
|
||||
if (!$success) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$row = $statement->fetch(PDO::FETCH_ASSOC);
|
||||
$statement->closeCursor();
|
||||
|
||||
return $row ? new Author(
|
||||
(int)$row['id'],
|
||||
$row['name'],
|
||||
$row['url'],
|
||||
$row['photo']
|
||||
) : null;
|
||||
}
|
||||
|
||||
public function delete(Webmention $webmention): void
|
||||
{
|
||||
$sql = "DELETE FROM webmentions WHERE id=:id;";
|
||||
@ -116,7 +208,18 @@ class SqliteGateway extends WebmentionGatewayInterface
|
||||
return "$v=:$v";
|
||||
}, array_keys($values)));
|
||||
$sql = <<<SQL
|
||||
SELECT * FROM webmentions
|
||||
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
|
||||
WHERE {$keys}
|
||||
SQL;
|
||||
|
||||
|
@ -4,13 +4,17 @@ namespace Lewisdale\Webmentions\Gateways;
|
||||
|
||||
use Lewisdale\Webmentions\Models\Webmention;
|
||||
|
||||
abstract class WebmentionGatewayInterface {
|
||||
abstract class WebmentionGatewayInterface
|
||||
{
|
||||
abstract protected function up(): void;
|
||||
|
||||
abstract public function getByPost(string $post): array;
|
||||
|
||||
abstract public function save(Webmention $webmention): ?int;
|
||||
|
||||
abstract public function delete(Webmention $webmention): void;
|
||||
|
||||
abstract public function get(int $id): ?Webmention;
|
||||
|
||||
abstract public function find(array $values): array;
|
||||
}
|
||||
|
||||
?>
|
@ -20,5 +20,3 @@ class Webmention
|
||||
return "Webmention (id: {$this->id}, target: {$this->target}, source: {$this->source}, content: {$this->content}, author: {$this->author->name})";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -43,7 +43,7 @@ class SqliteGatewayTest extends TestCase
|
||||
"https://a-source.url",
|
||||
MentionType::Like,
|
||||
"No content",
|
||||
new \Lewisdale\Webmentions\Models\Author(),
|
||||
new \Lewisdale\Webmentions\Models\Author(null, null, null, null),
|
||||
);
|
||||
|
||||
$webmention->id = $this->gateway->save($webmention);
|
||||
@ -155,4 +155,90 @@ class SqliteGatewayTest extends TestCase
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
public function testItSavesAnAuthorWithTheWebmention()
|
||||
{
|
||||
$webmention = 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"
|
||||
)
|
||||
);
|
||||
$webmention->id = $this->gateway->save($webmention);
|
||||
$retrieved = $this->gateway->get($webmention->id)?->author;
|
||||
$expected = $webmention->author;
|
||||
|
||||
$this->assertEquals($expected->name, $retrieved?->name);
|
||||
$this->assertEquals($expected->url, $retrieved?->url);
|
||||
$this->assertEquals($expected->photo, $retrieved?->photo);
|
||||
}
|
||||
|
||||
public function testItLooksUpWebmentionsByAuthorName()
|
||||
{
|
||||
$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"
|
||||
)
|
||||
));
|
||||
|
||||
$retrieved = $this->gateway->find(["author_name" => "Carl Weathers"]);
|
||||
$this->assertCount(2, $retrieved);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user