Merge pull request #490 from jonnybarnes/479-store-syndication-targets-within-in-the-database
Store syndication targets within the database
This commit is contained in:
commit
271d50db53
16 changed files with 467 additions and 88 deletions
99
app/Http/Controllers/Admin/SyndicationTargetsController.php
Normal file
99
app/Http/Controllers/Admin/SyndicationTargetsController.php
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\SyndicationTarget;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class SyndicationTargetsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show a list of known syndication targets.
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
$targets = SyndicationTarget::all();
|
||||
|
||||
return view('admin.syndication.index', compact('targets'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show form to add a syndication target.
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function create(): View
|
||||
{
|
||||
return view('admin.syndication.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the request to adda new syndication target.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'uid' => 'required|string',
|
||||
'name' => 'required|string',
|
||||
]);
|
||||
|
||||
SyndicationTarget::create($validated);
|
||||
|
||||
return redirect('/admin/syndication');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a form to edit a syndication target.
|
||||
*
|
||||
* @param SyndicationTarget $syndicationTarget
|
||||
* @return View
|
||||
*/
|
||||
public function edit(SyndicationTarget $syndicationTarget): View
|
||||
{
|
||||
return view('admin.syndication.edit', [
|
||||
'syndication_target' => $syndicationTarget,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the request to edit a client name.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param SyndicationTarget $syndicationTarget
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function update(Request $request, SyndicationTarget $syndicationTarget): RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'uid' => 'required|string',
|
||||
'name' => 'required|string',
|
||||
]);
|
||||
|
||||
$syndicationTarget->update($validated);
|
||||
|
||||
return redirect('/admin/syndication');
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a request to delete a client.
|
||||
*
|
||||
* @param SyndicationTarget $syndicationTarget
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function destroy(SyndicationTarget $syndicationTarget): RedirectResponse
|
||||
{
|
||||
$syndicationTarget->delete();
|
||||
|
||||
return redirect('/admin/syndication');
|
||||
}
|
||||
}
|
|
@ -6,11 +6,13 @@ namespace App\Http\Controllers;
|
|||
|
||||
use App\Http\Responses\MicropubResponses;
|
||||
use App\Models\Place;
|
||||
use App\Models\SyndicationTarget;
|
||||
use App\Services\Micropub\HCardService;
|
||||
use App\Services\Micropub\HEntryService;
|
||||
use App\Services\Micropub\UpdateService;
|
||||
use App\Services\TokenService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Lcobucci\JWT\Encoding\CannotDecodeContent;
|
||||
use Lcobucci\JWT\Token\InvalidTokenStructure;
|
||||
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
|
||||
|
@ -43,13 +45,14 @@ class MicropubController extends Controller
|
|||
* This function receives an API request, verifies the authenticity
|
||||
* then passes over the info to the relevant Service class.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function post(): JsonResponse
|
||||
public function post(Request $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
$tokenData = $this->tokenService->validateToken(request()->input('access_token'));
|
||||
} catch (RequiredConstraintsViolated | InvalidTokenStructure | CannotDecodeContent $exception) {
|
||||
$tokenData = $this->tokenService->validateToken($request->input('access_token'));
|
||||
} catch (RequiredConstraintsViolated | InvalidTokenStructure | CannotDecodeContent) {
|
||||
$micropubResponses = new MicropubResponses();
|
||||
|
||||
return $micropubResponses->invalidTokenResponse();
|
||||
|
@ -61,15 +64,15 @@ class MicropubController extends Controller
|
|||
return $micropubResponses->tokenHasNoScopeResponse();
|
||||
}
|
||||
|
||||
$this->logMicropubRequest(request()->all());
|
||||
$this->logMicropubRequest($request->all());
|
||||
|
||||
if ((request()->input('h') == 'entry') || (request()->input('type.0') == 'h-entry')) {
|
||||
if (stristr($tokenData->claims()->get('scope'), 'create') === false) {
|
||||
if (($request->input('h') === 'entry') || ($request->input('type.0') === 'h-entry')) {
|
||||
if (stripos($tokenData->claims()->get('scope'), 'create') === false) {
|
||||
$micropubResponses = new MicropubResponses();
|
||||
|
||||
return $micropubResponses->insufficientScopeResponse();
|
||||
}
|
||||
$location = $this->hentryService->process(request()->all(), $this->getCLientId());
|
||||
$location = $this->hentryService->process($request->all(), $this->getCLientId());
|
||||
|
||||
return response()->json([
|
||||
'response' => 'created',
|
||||
|
@ -77,13 +80,13 @@ class MicropubController extends Controller
|
|||
], 201)->header('Location', $location);
|
||||
}
|
||||
|
||||
if (request()->input('h') == 'card' || request()->input('type.0') == 'h-card') {
|
||||
if (stristr($tokenData->claims()->get('scope'), 'create') === false) {
|
||||
if ($request->input('h') === 'card' || $request->input('type.0') === 'h-card') {
|
||||
if (stripos($tokenData->claims()->get('scope'), 'create') === false) {
|
||||
$micropubResponses = new MicropubResponses();
|
||||
|
||||
return $micropubResponses->insufficientScopeResponse();
|
||||
}
|
||||
$location = $this->hcardService->process(request()->all());
|
||||
$location = $this->hcardService->process($request->all());
|
||||
|
||||
return response()->json([
|
||||
'response' => 'created',
|
||||
|
@ -91,14 +94,14 @@ class MicropubController extends Controller
|
|||
], 201)->header('Location', $location);
|
||||
}
|
||||
|
||||
if (request()->input('action') == 'update') {
|
||||
if (stristr($tokenData->claims()->get('scope'), 'update') === false) {
|
||||
if ($request->input('action') === 'update') {
|
||||
if (stripos($tokenData->claims()->get('scope'), 'update') === false) {
|
||||
$micropubResponses = new MicropubResponses();
|
||||
|
||||
return $micropubResponses->insufficientScopeResponse();
|
||||
}
|
||||
|
||||
return $this->updateService->process(request()->all());
|
||||
return $this->updateService->process($request->all());
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
|
@ -121,21 +124,19 @@ class MicropubController extends Controller
|
|||
{
|
||||
try {
|
||||
$tokenData = $this->tokenService->validateToken(request()->input('access_token'));
|
||||
} catch (RequiredConstraintsViolated | InvalidTokenStructure $exception) {
|
||||
$micropubResponses = new MicropubResponses();
|
||||
|
||||
return $micropubResponses->invalidTokenResponse();
|
||||
} catch (RequiredConstraintsViolated | InvalidTokenStructure) {
|
||||
return (new MicropubResponses())->invalidTokenResponse();
|
||||
}
|
||||
|
||||
if (request()->input('q') === 'syndicate-to') {
|
||||
return response()->json([
|
||||
'syndicate-to' => config('syndication.targets'),
|
||||
'syndicate-to' => SyndicationTarget::all(),
|
||||
]);
|
||||
}
|
||||
|
||||
if (request()->input('q') == 'config') {
|
||||
if (request()->input('q') === 'config') {
|
||||
return response()->json([
|
||||
'syndicate-to' => config('syndication.targets'),
|
||||
'syndicate-to' => SyndicationTarget::all(),
|
||||
'media-endpoint' => route('media-endpoint'),
|
||||
]);
|
||||
}
|
||||
|
|
84
app/Models/SyndicationTarget.php
Normal file
84
app/Models/SyndicationTarget.php
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class SyndicationTarget extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'uid',
|
||||
'name',
|
||||
'service_name',
|
||||
'service_url',
|
||||
'service_photo',
|
||||
'user_name',
|
||||
'user_url',
|
||||
'user_photo',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that are visible when serializing the model.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $visible = [
|
||||
'uid',
|
||||
'name',
|
||||
'service',
|
||||
'user',
|
||||
];
|
||||
|
||||
/**
|
||||
* The accessors to append to the model's array form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $appends = [
|
||||
'service',
|
||||
'user',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the service data as a single attribute.
|
||||
*
|
||||
* @vreturn Attribute
|
||||
*/
|
||||
protected function service(): Attribute
|
||||
{
|
||||
return Attribute::get(
|
||||
get: fn ($value, $attributes) => [
|
||||
'name' => $attributes['service_name'],
|
||||
'url' => $attributes['service_url'],
|
||||
'photo' => $attributes['service_photo'],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user data as a single attribute.
|
||||
*
|
||||
* @vreturn Attribute
|
||||
*/
|
||||
protected function user(): Attribute
|
||||
{
|
||||
return Attribute::get(
|
||||
get: fn ($value, $attributes) => [
|
||||
'name' => $attributes['user_name'],
|
||||
'url' => $attributes['user_url'],
|
||||
'photo' => $attributes['user_photo'],
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ use App\Exceptions\InternetArchiveException;
|
|||
use App\Jobs\ProcessBookmark;
|
||||
use App\Jobs\SyndicateBookmarkToTwitter;
|
||||
use App\Models\Bookmark;
|
||||
use App\Models\SyndicationTarget;
|
||||
use App\Models\Tag;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
|
@ -52,7 +53,6 @@ class BookmarkService
|
|||
$bookmark->tags()->save($tag);
|
||||
}
|
||||
|
||||
$targets = Arr::pluck(config('syndication.targets'), 'uid', 'service.name');
|
||||
$mpSyndicateTo = null;
|
||||
if (Arr::get($request, 'mp-syndicate-to')) {
|
||||
$mpSyndicateTo = Arr::get($request, 'mp-syndicate-to');
|
||||
|
@ -60,18 +60,13 @@ class BookmarkService
|
|||
if (Arr::get($request, 'properties.mp-syndicate-to')) {
|
||||
$mpSyndicateTo = Arr::get($request, 'properties.mp-syndicate-to');
|
||||
}
|
||||
if (is_string($mpSyndicateTo)) {
|
||||
$service = array_search($mpSyndicateTo, $targets);
|
||||
if ($service == 'Twitter') {
|
||||
$mpSyndicateTo = Arr::wrap($mpSyndicateTo);
|
||||
foreach ($mpSyndicateTo as $uid) {
|
||||
$target = SyndicationTarget::where('uid', $uid)->first();
|
||||
if ($target && $target->service_name === 'Twitter') {
|
||||
SyndicateBookmarkToTwitter::dispatch($bookmark);
|
||||
}
|
||||
}
|
||||
if (is_array($mpSyndicateTo)) {
|
||||
foreach ($mpSyndicateTo as $uid) {
|
||||
$service = array_search($uid, $targets);
|
||||
if ($service == 'Twitter') {
|
||||
SyndicateBookmarkToTwitter::dispatch($bookmark);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,19 +21,13 @@ class HEntryService
|
|||
public function process(array $request, ?string $client = null): ?string
|
||||
{
|
||||
if (Arr::get($request, 'properties.like-of') || Arr::get($request, 'like-of')) {
|
||||
$like = resolve(LikeService::class)->createLike($request);
|
||||
|
||||
return $like->longurl;
|
||||
return resolve(LikeService::class)->createLike($request)->longurl;
|
||||
}
|
||||
|
||||
if (Arr::get($request, 'properties.bookmark-of') || Arr::get($request, 'bookmark-of')) {
|
||||
$bookmark = resolve(BookmarkService::class)->createBookmark($request);
|
||||
|
||||
return $bookmark->longurl;
|
||||
return resolve(BookmarkService::class)->createBookmark($request)->longurl;
|
||||
}
|
||||
|
||||
$note = resolve(NoteService::class)->createNote($request, $client);
|
||||
|
||||
return $note->longurl;
|
||||
return resolve(NoteService::class)->createNote($request, $client)->longurl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use App\Jobs\SyndicateNoteToTwitter;
|
|||
use App\Models\Media;
|
||||
use App\Models\Note;
|
||||
use App\Models\Place;
|
||||
use App\Models\SyndicationTarget;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
|
@ -18,7 +19,7 @@ class NoteService
|
|||
* Create a new note.
|
||||
*
|
||||
* @param array $request Data from request()->all()
|
||||
* @param string $client
|
||||
* @param string|null $client
|
||||
* @return Note
|
||||
*/
|
||||
public function createNote(array $request, ?string $client = null): Note
|
||||
|
@ -52,11 +53,9 @@ class NoteService
|
|||
|
||||
dispatch(new SendWebMentions($note));
|
||||
|
||||
//syndication targets
|
||||
if (count($this->getSyndicationTargets($request)) > 0) {
|
||||
if (in_array('twitter', $this->getSyndicationTargets($request))) {
|
||||
dispatch(new SyndicateNoteToTwitter($note));
|
||||
}
|
||||
// Syndication targets
|
||||
if (in_array('twitter', $this->getSyndicationTargets($request), true)) {
|
||||
dispatch(new SyndicateNoteToTwitter($note));
|
||||
}
|
||||
|
||||
return $note;
|
||||
|
@ -206,22 +205,14 @@ class NoteService
|
|||
private function getSyndicationTargets(array $request): array
|
||||
{
|
||||
$syndication = [];
|
||||
$targets = Arr::pluck(config('syndication.targets'), 'uid', 'service.name');
|
||||
$mpSyndicateTo = Arr::get($request, 'mp-syndicate-to') ?? Arr::get($request, 'properties.mp-syndicate-to');
|
||||
if (is_string($mpSyndicateTo)) {
|
||||
$service = array_search($mpSyndicateTo, $targets);
|
||||
if ($service == 'Twitter') {
|
||||
$mpSyndicateTo = Arr::wrap($mpSyndicateTo);
|
||||
foreach ($mpSyndicateTo as $uid) {
|
||||
$target = SyndicationTarget::where('uid', $uid)->first();
|
||||
if ($target && $target->service_name === 'Twitter') {
|
||||
$syndication[] = 'twitter';
|
||||
}
|
||||
}
|
||||
if (is_array($mpSyndicateTo)) {
|
||||
foreach ($mpSyndicateTo as $uid) {
|
||||
$service = array_search($uid, $targets);
|
||||
if ($service == 'Twitter') {
|
||||
$syndication[] = 'twitter';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $syndication;
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Here we define the syndication targets to be
|
||||
* returned by the micropub endpoint.
|
||||
*/
|
||||
|
||||
return [
|
||||
// if you don’t have any targets, then set this to 'targets' => [];
|
||||
'targets' => [
|
||||
[
|
||||
'uid' => 'https://twitter.com/jonnybarnes',
|
||||
'name' => 'jonnybarnes on Twitter',
|
||||
'service' => [
|
||||
'name' => 'Twitter',
|
||||
'url' => 'https://twitter.com',
|
||||
'photo' => 'https://upload.wikimedia.org/wikipedia/commons/4/4f/Twitter-logo.svg',
|
||||
],
|
||||
'user' => [
|
||||
'name' => 'jonnybarnes',
|
||||
'url' => 'https://twitter.com/jonnybarnes',
|
||||
'photo' => 'https://pbs.twimg.com/profile_images/875422855932121089/W628ZI8w_400x400.jpg',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
30
database/factories/SyndicationTargetFactory.php
Normal file
30
database/factories/SyndicationTargetFactory.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\SyndicationTarget>
|
||||
*/
|
||||
class SyndicationTargetFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'uid' => $this->faker->url,
|
||||
'name' => $this->faker->name,
|
||||
'service_name' => $this->faker->name,
|
||||
'service_url' => $this->faker->url,
|
||||
'service_photo' => $this->faker->url,
|
||||
'user_name' => $this->faker->name,
|
||||
'user_url' => $this->faker->url,
|
||||
'user_photo' => $this->faker->url,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('syndication_targets', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uid');
|
||||
$table->string('name');
|
||||
$table->string('service_name');
|
||||
$table->string('service_url');
|
||||
$table->string('service_photo');
|
||||
$table->string('user_name');
|
||||
$table->string('user_url');
|
||||
$table->string('user_photo');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('syndication_targets');
|
||||
}
|
||||
};
|
45
resources/views/admin/syndication/create.blade.php
Normal file
45
resources/views/admin/syndication/create.blade.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
@extends('master')
|
||||
|
||||
@section('title')New Syndication Target « Admin CP « @stop
|
||||
|
||||
@section('content')
|
||||
<h1>New Syndication Target</h1>
|
||||
<form action="/admin/syndication" method="post" accept-charset="utf-8" class="admin-form form">
|
||||
{{ csrf_field() }}
|
||||
<div>
|
||||
<label for="uid">Target UID:</label>
|
||||
<input type="text" name="uid" id="uid" placeholder="https://myfavoritesocialnetwork.example/aaronpk">
|
||||
</div>
|
||||
<div>
|
||||
<label for="name">Target Name:</label>
|
||||
<input type="text" name="name" id="name" placeholder="aaronpk on myfavoritesocialnetwork">
|
||||
</div>
|
||||
<div>
|
||||
<label for="service_name">Service Name:</label>
|
||||
<input type="text" name="service_name" id="service_name" placeholder="My Favorite Social Network">
|
||||
</div>
|
||||
<div>
|
||||
<label for="service_url">Service URL:</label>
|
||||
<input type="text" name="service_url" id="service_url" placeholder="https://myfavoritesocialnetwork.example/">
|
||||
</div>
|
||||
<div>
|
||||
<label for="service_photo">Service Logo:</label>
|
||||
<input type="text" name="service_photo" id="service_photo" placeholder="https://myfavoritesocialnetwork.example/img/icon.png">
|
||||
</div>
|
||||
<div>
|
||||
<label for="user_name">User Name:</label>
|
||||
<input type="text" name="user_name" id="user_name" placeholder="aaronpk">
|
||||
</div>
|
||||
<div>
|
||||
<label for="user_url">User URL:</label>
|
||||
<input type="text" name="user_url" id="user_url" placeholder="https://myfavoritesocialnetwork.example/aaronpk">
|
||||
</div>
|
||||
<div>
|
||||
<label for="user_photo">User Photo:</label>
|
||||
<input type="text" name="user_photo" id="user_photo" placeholder="https://myfavoritesocialnetwork.example/aaronpk/photo.jpg">
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" name="submit">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
@stop
|
52
resources/views/admin/syndication/edit.blade.php
Normal file
52
resources/views/admin/syndication/edit.blade.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
@extends('master')
|
||||
|
||||
@section('title')Edit Syndication Target « Admin CP « @stop
|
||||
|
||||
@section('content')
|
||||
<h1>Edit syndication target</h1>
|
||||
<form action="/admin/syndication/{{ $syndication_target->id }}" method="post" accept-charset="utf-8" class="admin-form form">
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('PUT') }}
|
||||
<div>
|
||||
<label for="uid">Target UID:</label>
|
||||
<input type="text" name="uid" id="uid" value="{{ old('target_uid', $syndication_target->uid) }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="name">Target Name:</label>
|
||||
<input type="text" name="name" id="name" value="{{ old('target_name', $syndication_target->name) }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="service_name">Service Name:</label>
|
||||
<input type="text" name="service_name" id="service_name" value="{{ old('service_name', $syndication_target->service_name) }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="service_url">Service URL:</label>
|
||||
<input type="text" name="service_url" id="service_url" value="{{ old('service_url', $syndication_target->service_url) }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="service_photo">Service Logo:</label>
|
||||
<input type="text" name="service_photo" id="service_photo" value="{{ old('service_photo', $syndication_target->service_photo) }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="user_name">User Name:</label>
|
||||
<input type="text" name="user_name" id="user_name" value="{{ old('user_name', $syndication_target->user_name) }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="user_url">User URL:</label>
|
||||
<input type="text" name="user_url" id="user_url" value="{{ old('user_url', $syndication_target->user_url) }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="user_photo">User Photo:</label>
|
||||
<input type="text" name="user_photo" id="user_photo" value="{{ old('user_photo', $syndication_target->user_photo) }}">
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" name="edit">Edit</button>
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
<form action="/admin/syndication/{{ $syndication_target->id }}" method="post">
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('DELETE') }}
|
||||
<button type="submit" name="delete">Delete syndication target</button>
|
||||
</form>
|
||||
@stop
|
22
resources/views/admin/syndication/index.blade.php
Normal file
22
resources/views/admin/syndication/index.blade.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
@extends('master')
|
||||
|
||||
@section('title')List Syndication Targets « Admin CP « @stop
|
||||
|
||||
@section('content')
|
||||
<h1>Syndication Targets</h1>
|
||||
@if($targets->isEmpty())
|
||||
<p>No saved syndication targets.</p>
|
||||
@else
|
||||
<ul>
|
||||
@foreach($targets as $target)
|
||||
<li>
|
||||
{{ $target['uid'] }}
|
||||
<a href="/admin/syndication/{{ $target['id'] }}/edit">edit?</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
<p>
|
||||
Create a <a href="/admin/syndication/create">new syndication target</a>?
|
||||
</p>
|
||||
@stop
|
|
@ -40,4 +40,10 @@
|
|||
You can either <a href="/admin/places/create">create</a> new places,
|
||||
or <a href="/admin/places/">edit</a> them.
|
||||
</p>
|
||||
|
||||
<h2>Syndication</h2>
|
||||
<p>
|
||||
You can either <a href="/admin/syndication/create">create</a> new syndication targets,
|
||||
or <a href="/admin/syndication">edit</a> them.
|
||||
</p>
|
||||
@stop
|
||||
|
|
|
@ -18,6 +18,7 @@ use App\Http\Controllers\Admin\HomeController;
|
|||
use App\Http\Controllers\Admin\LikesController as AdminLikesController;
|
||||
use App\Http\Controllers\Admin\NotesController as AdminNotesController;
|
||||
use App\Http\Controllers\Admin\PlacesController as AdminPlacesController;
|
||||
use App\Http\Controllers\Admin\SyndicationTargetsController;
|
||||
use App\Http\Controllers\ArticlesController;
|
||||
use App\Http\Controllers\AuthController;
|
||||
use App\Http\Controllers\BookmarksController;
|
||||
|
@ -122,6 +123,16 @@ Route::group(['domain' => config('url.longurl')], function () {
|
|||
Route::put('/{id}', [AdminLikesController::class, 'update']);
|
||||
Route::delete('/{id}', [AdminLikesController::class, 'destroy']);
|
||||
});
|
||||
|
||||
// Syndication Targets
|
||||
Route::group(['prefix' => 'syndication'], function () {
|
||||
Route::get('/', [SyndicationTargetsController::class, 'index']);
|
||||
Route::get('/create', [SyndicationTargetsController::class, 'create']);
|
||||
Route::post('/', [SyndicationTargetsController::class, 'store']);
|
||||
Route::get('/{syndicationTarget}/edit', [SyndicationTargetsController::class, 'edit']);
|
||||
Route::put('/{syndicationTarget}', [SyndicationTargetsController::class, 'update']);
|
||||
Route::delete('/{syndicationTarget}', [SyndicationTargetsController::class, 'destroy']);
|
||||
});
|
||||
});
|
||||
|
||||
// Blog pages using ArticlesController
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Tests\Feature;
|
|||
use App\Jobs\ProcessBookmark;
|
||||
use App\Jobs\SyndicateBookmarkToTwitter;
|
||||
use App\Models\Bookmark;
|
||||
use App\Models\SyndicationTarget;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Tests\TestCase;
|
||||
|
@ -36,6 +37,11 @@ class BookmarksTest extends TestCase
|
|||
{
|
||||
Queue::fake();
|
||||
|
||||
SyndicationTarget::factory()->create([
|
||||
'uid' => 'https://twitter.com/jonnybarnes',
|
||||
'service_name' => 'Twitter',
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'Authorization' => 'Bearer ' . $this->getToken(),
|
||||
])->post('/api/post', [
|
||||
|
@ -58,6 +64,11 @@ class BookmarksTest extends TestCase
|
|||
{
|
||||
Queue::fake();
|
||||
|
||||
SyndicationTarget::factory()->create([
|
||||
'uid' => 'https://twitter.com/jonnybarnes',
|
||||
'service_name' => 'Twitter',
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'Authorization' => 'Bearer ' . $this->getToken(),
|
||||
])->json('POST', '/api/post', [
|
||||
|
@ -82,6 +93,11 @@ class BookmarksTest extends TestCase
|
|||
{
|
||||
Queue::fake();
|
||||
|
||||
SyndicationTarget::factory()->create([
|
||||
'uid' => 'https://twitter.com/jonnybarnes',
|
||||
'service_name' => 'Twitter',
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'Authorization' => 'Bearer ' . $this->getToken(),
|
||||
])->post('/api/post', [
|
||||
|
|
|
@ -9,6 +9,7 @@ use App\Jobs\SyndicateNoteToTwitter;
|
|||
use App\Models\Media;
|
||||
use App\Models\Note;
|
||||
use App\Models\Place;
|
||||
use App\Models\SyndicationTarget;
|
||||
use Carbon\Carbon;
|
||||
use Faker\Factory;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
@ -51,10 +52,18 @@ class MicropubControllerTest extends TestCase
|
|||
}
|
||||
|
||||
/** @test */
|
||||
public function micropubClientsCanRequestSyndicationTargets(): void
|
||||
public function micropubClientsCanRequestSyndicationTargetsCanBeEmpty(): void
|
||||
{
|
||||
$response = $this->get('/api/post?q=syndicate-to', ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]);
|
||||
$response->assertJsonFragment(['uid' => 'https://twitter.com/jonnybarnes']);
|
||||
$response->assertJsonFragment(['syndicate-to' => []]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function micropubClientsCanRequestSyndicationTargetsPopulatesFromModel(): void
|
||||
{
|
||||
$syndicationTarget = SyndicationTarget::factory()->create();
|
||||
$response = $this->get('/api/post?q=syndicate-to', ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]);
|
||||
$response->assertJsonFragment(['uid' => $syndicationTarget->uid]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
|
@ -91,7 +100,7 @@ class MicropubControllerTest extends TestCase
|
|||
public function micropubClientCanRequestEndpointConfig(): void
|
||||
{
|
||||
$response = $this->get('/api/post?q=config', ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]);
|
||||
$response->assertJsonFragment(['uid' => 'https://twitter.com/jonnybarnes']);
|
||||
$response->assertJsonFragment(['media-endpoint' => route('media-endpoint')]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
|
@ -117,6 +126,12 @@ class MicropubControllerTest extends TestCase
|
|||
public function micropubClientCanRequestTheNewNoteIsSyndicatedToTwitter(): void
|
||||
{
|
||||
Queue::fake();
|
||||
|
||||
SyndicationTarget::factory()->create([
|
||||
'uid' => 'https://twitter.com/jonnybarnes',
|
||||
'service_name' => 'Twitter',
|
||||
]);
|
||||
|
||||
$faker = Factory::create();
|
||||
$note = $faker->text;
|
||||
$response = $this->post(
|
||||
|
@ -224,6 +239,11 @@ class MicropubControllerTest extends TestCase
|
|||
'path' => 'test-photo.jpg',
|
||||
'type' => 'image',
|
||||
]);
|
||||
SyndicationTarget::factory()->create([
|
||||
'uid' => 'https://twitter.com/jonnybarnes',
|
||||
'service_name' => 'Twitter',
|
||||
]);
|
||||
|
||||
$faker = Factory::create();
|
||||
$note = $faker->text;
|
||||
$response = $this->postJson(
|
||||
|
|
Loading…
Add table
Reference in a new issue