Allow micropub to post notes and articles

This commit is contained in:
Jonny Barnes 2022-11-29 19:58:44 +00:00
parent 5eed665801
commit ca6205d2a6
Signed by: jonny
SSH key fingerprint: SHA256:CTuSlns5U7qlD9jqHvtnVmfYV3Zwl2Z7WnJ4/dqOaL8
9 changed files with 102 additions and 49 deletions

View file

@ -53,11 +53,16 @@ class Article extends Model
} }
/** /**
* We shall set a blacklist of non-modifiable model attributes. * The attributes that are mass assignable.
* *
* @var array * @var array<int, string>
*/ */
protected $guarded = ['id']; protected $fillable = [
'url',
'title',
'main',
'published',
];
protected function html(): Attribute protected function html(): Attribute
{ {

View file

@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace App\Services;
use App\Models\Article;
class ArticleService extends Service
{
public function create(array $request, ?string $client = null): Article
{
return Article::create([
'title' => $this->getDataByKey($request, 'name'),
'main' => $this->getDataByKey($request, 'content'),
'published' => true,
]);
}
}

View file

@ -18,7 +18,7 @@ use Ramsey\Uuid\Uuid;
use Spatie\Browsershot\Browsershot; use Spatie\Browsershot\Browsershot;
use Spatie\Browsershot\Exceptions\CouldNotTakeBrowsershot; use Spatie\Browsershot\Exceptions\CouldNotTakeBrowsershot;
class BookmarkService class BookmarkService extends Service
{ {
/** /**
* Create a new Bookmark. * Create a new Bookmark.
@ -26,7 +26,7 @@ class BookmarkService
* @param array $request Data from request()->all() * @param array $request Data from request()->all()
* @return Bookmark * @return Bookmark
*/ */
public function createBookmark(array $request): Bookmark public function create(array $request, ?string $client = null): Bookmark
{ {
if (Arr::get($request, 'properties.bookmark-of.0')) { if (Arr::get($request, 'properties.bookmark-of.0')) {
//micropub request //micropub request

View file

@ -8,7 +8,7 @@ use App\Jobs\ProcessLike;
use App\Models\Like; use App\Models\Like;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
class LikeService class LikeService extends Service
{ {
/** /**
* Create a new Like. * Create a new Like.
@ -16,7 +16,7 @@ class LikeService
* @param array $request * @param array $request
* @return Like $like * @return Like $like
*/ */
public function createLike(array $request): Like public function create(array $request, ?string $client = null): Like
{ {
if (Arr::get($request, 'properties.like-of.0')) { if (Arr::get($request, 'properties.like-of.0')) {
//micropub request //micropub request

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Services\Micropub; namespace App\Services\Micropub;
use App\Services\ArticleService;
use App\Services\BookmarkService; use App\Services\BookmarkService;
use App\Services\LikeService; use App\Services\LikeService;
use App\Services\NoteService; use App\Services\NoteService;
@ -21,13 +22,17 @@ class HEntryService
public function process(array $request, ?string $client = null): ?string public function process(array $request, ?string $client = null): ?string
{ {
if (Arr::get($request, 'properties.like-of') || Arr::get($request, 'like-of')) { if (Arr::get($request, 'properties.like-of') || Arr::get($request, 'like-of')) {
return resolve(LikeService::class)->createLike($request)->longurl; return resolve(LikeService::class)->create($request)->longurl;
} }
if (Arr::get($request, 'properties.bookmark-of') || Arr::get($request, 'bookmark-of')) { if (Arr::get($request, 'properties.bookmark-of') || Arr::get($request, 'bookmark-of')) {
return resolve(BookmarkService::class)->createBookmark($request)->longurl; return resolve(BookmarkService::class)->create($request)->longurl;
} }
return resolve(NoteService::class)->createNote($request, $client)->longurl; if (Arr::get($request, 'properties.name') || Arr::get($request, 'name')) {
return resolve(ArticleService::class)->create($request)->longurl;
}
return resolve(NoteService::class)->create($request, $client)->longurl;
} }
} }

View file

@ -14,7 +14,7 @@ use App\Models\SyndicationTarget;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class NoteService class NoteService extends Service
{ {
/** /**
* Create a new note. * Create a new note.
@ -23,12 +23,12 @@ class NoteService
* @param string|null $client * @param string|null $client
* @return Note * @return Note
*/ */
public function createNote(array $request, ?string $client = null): Note public function create(array $request, ?string $client = null): Note
{ {
$note = Note::create( $note = Note::create(
[ [
'note' => $this->getContent($request), 'note' => $this->getDataByKey($request, 'content'),
'in_reply_to' => $this->getInReplyTo($request), 'in_reply_to' => $this->getDataByKey($request, 'in-reploy-to'),
'client_id' => $client, 'client_id' => $client,
] ]
); );
@ -66,39 +66,6 @@ class NoteService
return $note; return $note;
} }
/**
* Get the content from the request to create a new note.
*
* @param array $request Data from request()->all()
* @return string|null
*/
private function getContent(array $request): ?string
{
if (Arr::get($request, 'properties.content.0.html')) {
return Arr::get($request, 'properties.content.0.html');
}
if (is_string(Arr::get($request, 'properties.content.0'))) {
return Arr::get($request, 'properties.content.0');
}
return Arr::get($request, 'content');
}
/**
* Get the in-reply-to from the request to create a new note.
*
* @param array $request Data from request()->all()
* @return string|null
*/
private function getInReplyTo(array $request): ?string
{
if (Arr::get($request, 'properties.in-reply-to.0')) {
return Arr::get($request, 'properties.in-reply-to.0');
}
return Arr::get($request, 'in-reply-to');
}
/** /**
* Get the published time from the request to create a new note. * Get the published time from the request to create a new note.
* *

30
app/Services/Service.php Normal file
View file

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace App\Services;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
abstract class Service
{
abstract public function create(array $request, ?string $client = null): Model;
protected function getDataByKey(array $request, string $key): ?string
{
if (Arr::get($request, "properties.{$key}.0.html")) {
return Arr::get($request, "properties.{$key}.0.html");
}
if (is_string(Arr::get($request, "properties.{$key}.0"))) {
return Arr::get($request, "properties.{$key}.0");
}
if (is_string(Arr::get($request, "properties.{$key}"))) {
return Arr::get($request, "properties.{$key}");
}
return Arr::get($request, $key);
}
}

View file

@ -1,6 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<psalm <psalm
totallyTyped="false"
errorLevel="7" errorLevel="7"
resolveFromConfigFile="true" resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

View file

@ -675,7 +675,7 @@ class MicropubControllerTest extends TestCase
} }
/** @test */ /** @test */
public function micropubClientWebReauestCanEncodeTokenWithinTheForm(): void public function micropubClientWebRequestCanEncodeTokenWithinTheForm(): void
{ {
$faker = Factory::create(); $faker = Factory::create();
$note = $faker->text; $note = $faker->text;
@ -691,4 +691,32 @@ class MicropubControllerTest extends TestCase
$response->assertJson(['response' => 'created']); $response->assertJson(['response' => 'created']);
$this->assertDatabaseHas('notes', ['note' => $note]); $this->assertDatabaseHas('notes', ['note' => $note]);
} }
/** @test */
public function micropubClientApiRequestCreatesArticlesWhenItIncludesTheNameProperty(): void
{
$faker = Factory::create();
$name = $faker->text(50);
$content = $faker->paragraphs(5, true);
$response = $this->postJson(
'/api/post',
[
'type' => ['h-entry'],
'properties' => [
'name' => $name,
'content' => $content,
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
);
$response
->assertJson(['response' => 'created'])
->assertStatus(201);
$this->assertDatabaseHas('articles', [
'title' => $name,
'main' => $content,
]);
}
} }