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
{

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\Exceptions\CouldNotTakeBrowsershot;
class BookmarkService
class BookmarkService extends Service
{
/**
* Create a new Bookmark.
@ -26,7 +26,7 @@ class BookmarkService
* @param array $request Data from request()->all()
* @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')) {
//micropub request

View file

@ -8,7 +8,7 @@ use App\Jobs\ProcessLike;
use App\Models\Like;
use Illuminate\Support\Arr;
class LikeService
class LikeService extends Service
{
/**
* Create a new Like.
@ -16,7 +16,7 @@ class LikeService
* @param array $request
* @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')) {
//micropub request

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Services\Micropub;
use App\Services\ArticleService;
use App\Services\BookmarkService;
use App\Services\LikeService;
use App\Services\NoteService;
@ -21,13 +22,17 @@ class HEntryService
public function process(array $request, ?string $client = null): ?string
{
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')) {
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\Str;
class NoteService
class NoteService extends Service
{
/**
* Create a new note.
@ -23,12 +23,12 @@ class NoteService
* @param string|null $client
* @return Note
*/
public function createNote(array $request, ?string $client = null): Note
public function create(array $request, ?string $client = null): Note
{
$note = Note::create(
[
'note' => $this->getContent($request),
'in_reply_to' => $this->getInReplyTo($request),
'note' => $this->getDataByKey($request, 'content'),
'in_reply_to' => $this->getDataByKey($request, 'in-reploy-to'),
'client_id' => $client,
]
);
@ -66,39 +66,6 @@ class NoteService
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.
*

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"?>
<psalm
totallyTyped="false"
errorLevel="7"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

View file

@ -675,7 +675,7 @@ class MicropubControllerTest extends TestCase
}
/** @test */
public function micropubClientWebReauestCanEncodeTokenWithinTheForm(): void
public function micropubClientWebRequestCanEncodeTokenWithinTheForm(): void
{
$faker = Factory::create();
$note = $faker->text;
@ -691,4 +691,32 @@ class MicropubControllerTest extends TestCase
$response->assertJson(['response' => 'created']);
$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,
]);
}
}