Refactor of micropub request handling
Trying to organise the code better. It now temporarily doesn’t support update requests. Thought the spec defines them as SHOULD features and not MUST features. So safe for now :)
This commit is contained in:
parent
23c275945a
commit
83d10e1a70
26 changed files with 699 additions and 352 deletions
34
app/Services/Micropub/CardHandler.php
Normal file
34
app/Services/Micropub/CardHandler.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Micropub;
|
||||
|
||||
use App\Exceptions\InvalidTokenScopeException;
|
||||
use App\Services\PlaceService;
|
||||
|
||||
class CardHandler implements MicropubHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @throws InvalidTokenScopeException
|
||||
*/
|
||||
public function handle(array $data): array
|
||||
{
|
||||
// Handle h-card requests
|
||||
$scopes = $data['token_data']['scope'];
|
||||
if (is_string($scopes)) {
|
||||
$scopes = explode(' ', $scopes);
|
||||
}
|
||||
|
||||
if (! in_array('create', $scopes, true)) {
|
||||
throw new InvalidTokenScopeException;
|
||||
}
|
||||
|
||||
$location = resolve(PlaceService::class)->createPlace($data)->uri;
|
||||
|
||||
return [
|
||||
'response' => 'created',
|
||||
'url' => $location,
|
||||
];
|
||||
}
|
||||
}
|
41
app/Services/Micropub/EntryHandler.php
Normal file
41
app/Services/Micropub/EntryHandler.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Micropub;
|
||||
|
||||
use App\Exceptions\InvalidTokenScopeException;
|
||||
use App\Services\ArticleService;
|
||||
use App\Services\BookmarkService;
|
||||
use App\Services\LikeService;
|
||||
use App\Services\NoteService;
|
||||
|
||||
class EntryHandler implements MicropubHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @throws InvalidTokenScopeException
|
||||
*/
|
||||
public function handle(array $data)
|
||||
{
|
||||
$scopes = $data['token_data']['scope'];
|
||||
if (is_string($scopes)) {
|
||||
$scopes = explode(' ', $scopes);
|
||||
}
|
||||
|
||||
if (! in_array('create', $scopes, true)) {
|
||||
throw new InvalidTokenScopeException;
|
||||
}
|
||||
|
||||
$location = match (true) {
|
||||
isset($data['like-of']) => resolve(LikeService::class)->create($data)->url,
|
||||
isset($data['bookmark-of']) => resolve(BookmarkService::class)->create($data)->uri,
|
||||
isset($data['name']) => resolve(ArticleService::class)->create($data)->link,
|
||||
default => resolve(NoteService::class)->create($data)->uri,
|
||||
};
|
||||
|
||||
return [
|
||||
'response' => 'created',
|
||||
'url' => $location,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Micropub;
|
||||
|
||||
use App\Services\PlaceService;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class HCardService
|
||||
{
|
||||
/**
|
||||
* Create a Place from h-card data, return the URL.
|
||||
*/
|
||||
public function process(array $request): string
|
||||
{
|
||||
$data = [];
|
||||
if (Arr::get($request, 'properties.name')) {
|
||||
$data['name'] = Arr::get($request, 'properties.name');
|
||||
$data['description'] = Arr::get($request, 'properties.description');
|
||||
$data['geo'] = Arr::get($request, 'properties.geo');
|
||||
} else {
|
||||
$data['name'] = Arr::get($request, 'name');
|
||||
$data['description'] = Arr::get($request, 'description');
|
||||
$data['geo'] = Arr::get($request, 'geo');
|
||||
$data['latitude'] = Arr::get($request, 'latitude');
|
||||
$data['longitude'] = Arr::get($request, 'longitude');
|
||||
}
|
||||
|
||||
return resolve(PlaceService::class)->createPlace($data)->uri;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Micropub;
|
||||
|
||||
use App\Services\ArticleService;
|
||||
use App\Services\BookmarkService;
|
||||
use App\Services\LikeService;
|
||||
use App\Services\NoteService;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class HEntryService
|
||||
{
|
||||
/**
|
||||
* Create the relevant model from some h-entry data.
|
||||
*/
|
||||
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)->create($request)->url;
|
||||
}
|
||||
|
||||
if (Arr::get($request, 'properties.bookmark-of') || Arr::get($request, 'bookmark-of')) {
|
||||
return resolve(BookmarkService::class)->create($request)->uri;
|
||||
}
|
||||
|
||||
if (Arr::get($request, 'properties.name') || Arr::get($request, 'name')) {
|
||||
return resolve(ArticleService::class)->create($request)->link;
|
||||
}
|
||||
|
||||
return resolve(NoteService::class)->create($request, $client)->uri;
|
||||
}
|
||||
}
|
10
app/Services/Micropub/MicropubHandlerInterface.php
Normal file
10
app/Services/Micropub/MicropubHandlerInterface.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Micropub;
|
||||
|
||||
interface MicropubHandlerInterface
|
||||
{
|
||||
public function handle(array $data);
|
||||
}
|
34
app/Services/Micropub/MicropubHandlerRegistry.php
Normal file
34
app/Services/Micropub/MicropubHandlerRegistry.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Micropub;
|
||||
|
||||
use App\Exceptions\MicropubHandlerException;
|
||||
|
||||
class MicropubHandlerRegistry
|
||||
{
|
||||
/**
|
||||
* @var MicropubHandlerInterface[]
|
||||
*/
|
||||
protected array $handlers = [];
|
||||
|
||||
public function register(string $type, MicropubHandlerInterface $handler): self
|
||||
{
|
||||
$this->handlers[$type] = $handler;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws MicropubHandlerException
|
||||
*/
|
||||
public function getHandler(string $type): MicropubHandlerInterface
|
||||
{
|
||||
if (! isset($this->handlers[$type])) {
|
||||
throw new MicropubHandlerException("No handler registered for '{$type}'");
|
||||
}
|
||||
|
||||
return $this->handlers[$type];
|
||||
}
|
||||
}
|
|
@ -4,21 +4,33 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Services\Micropub;
|
||||
|
||||
use App\Exceptions\InvalidTokenScopeException;
|
||||
use App\Models\Media;
|
||||
use App\Models\Note;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UpdateService
|
||||
/*
|
||||
* @todo Implement this properly
|
||||
*/
|
||||
class UpdateHandler implements MicropubHandlerInterface
|
||||
{
|
||||
/**
|
||||
* Process a micropub request to update an entry.
|
||||
* @throws InvalidTokenScopeException
|
||||
*/
|
||||
public function process(array $request): JsonResponse
|
||||
public function handle(array $data)
|
||||
{
|
||||
$urlPath = parse_url(Arr::get($request, 'url'), PHP_URL_PATH);
|
||||
$scopes = $data['token_data']['scope'];
|
||||
if (is_string($scopes)) {
|
||||
$scopes = explode(' ', $scopes);
|
||||
}
|
||||
|
||||
if (! in_array('update', $scopes, true)) {
|
||||
throw new InvalidTokenScopeException;
|
||||
}
|
||||
|
||||
$urlPath = parse_url(Arr::get($data, 'url'), PHP_URL_PATH);
|
||||
|
||||
// is it a note we are updating?
|
||||
if (mb_substr($urlPath, 1, 5) !== 'notes') {
|
||||
|
@ -30,7 +42,7 @@ class UpdateService
|
|||
|
||||
try {
|
||||
$note = Note::nb60(basename($urlPath))->firstOrFail();
|
||||
} catch (ModelNotFoundException $exception) {
|
||||
} catch (ModelNotFoundException) {
|
||||
return response()->json([
|
||||
'error' => 'invalid_request',
|
||||
'error_description' => 'No known note with given ID',
|
||||
|
@ -38,8 +50,8 @@ class UpdateService
|
|||
}
|
||||
|
||||
// got the note, are we dealing with a “replace” request?
|
||||
if (Arr::get($request, 'replace')) {
|
||||
foreach (Arr::get($request, 'replace') as $property => $value) {
|
||||
if (Arr::get($data, 'replace')) {
|
||||
foreach (Arr::get($data, 'replace') as $property => $value) {
|
||||
if ($property === 'content') {
|
||||
$note->note = $value[0];
|
||||
}
|
||||
|
@ -59,14 +71,14 @@ class UpdateService
|
|||
}
|
||||
$note->save();
|
||||
|
||||
return response()->json([
|
||||
return [
|
||||
'response' => 'updated',
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
||||
// how about “add”
|
||||
if (Arr::get($request, 'add')) {
|
||||
foreach (Arr::get($request, 'add') as $property => $value) {
|
||||
if (Arr::get($data, 'add')) {
|
||||
foreach (Arr::get($data, 'add') as $property => $value) {
|
||||
if ($property === 'syndication') {
|
||||
foreach ($value as $syndicationURL) {
|
||||
if (Str::startsWith($syndicationURL, 'https://www.facebook.com')) {
|
Loading…
Add table
Add a link
Reference in a new issue