diff --git a/.env.travis b/.env.travis
index 766e9ed8..177e5cc8 100644
--- a/.env.travis
+++ b/.env.travis
@@ -12,3 +12,6 @@ SESSION_DRIVER=array
QUEUE_DRIVER=sync
SCOUT_DRIVER=pgsql
+
+DISPLAY_NAME='Travis Test'
+USER_NAME=travis
diff --git a/.travis.yml b/.travis.yml
index a93b22a5..f99b6ea4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -34,7 +34,6 @@ env:
- setup=basic
php:
- - 7.1
- 7.2
before_install:
diff --git a/app/Console/Commands/ParseCachedWebMentions.php b/app/Console/Commands/ParseCachedWebMentions.php
index 960a1b9f..2183cd4a 100644
--- a/app/Console/Commands/ParseCachedWebMentions.php
+++ b/app/Console/Commands/ParseCachedWebMentions.php
@@ -1,5 +1,7 @@
securityChecker->check(base_path() . '/composer.lock');
if (count($alerts) === 0) {
diff --git a/app/Http/Controllers/Admin/ArticlesController.php b/app/Http/Controllers/Admin/ArticlesController.php
index 1db84696..848f8440 100644
--- a/app/Http/Controllers/Admin/ArticlesController.php
+++ b/app/Http/Controllers/Admin/ArticlesController.php
@@ -1,19 +1,23 @@
orderBy('id', 'desc')->get();
@@ -23,9 +27,9 @@ class ArticlesController extends Controller
/**
* Show the new article form.
*
- * @return \Illuminate\View\Factory view
+ * @return \Illuminate\View\View
*/
- public function create()
+ public function create(): View
{
$message = session('message');
@@ -35,23 +39,22 @@ class ArticlesController extends Controller
/**
* Process an incoming request for a new article and save it.
*
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\View\Factory view
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function store(Request $request)
+ public function store(): RedirectResponse
{
//if a `.md` is attached use that for the main content.
- if ($request->hasFile('article')) {
- $file = $request->file('article')->openFile();
+ if (request()->hasFile('article')) {
+ $file = request()->file('article')->openFile();
$content = $file->fread($file->getSize());
}
- $main = $content ?? $request->input('main');
+ $main = $content ?? request()->input('main');
$article = Article::create(
[
- 'url' => $request->input('url'),
- 'title' => $request->input('title'),
+ 'url' => request()->input('url'),
+ 'title' => request()->input('title'),
'main' => $main,
- 'published' => $request->input('published') ?? 0,
+ 'published' => request()->input('published') ?? 0,
]
);
@@ -61,10 +64,10 @@ class ArticlesController extends Controller
/**
* Show the edit form for an existing article.
*
- * @param string The article id
- * @return \Illuminate\View\Factory view
+ * @param int $articleId
+ * @return \Illuminate\View\View
*/
- public function edit($articleId)
+ public function edit(int $articleId): View
{
$post = Article::select(
'title',
@@ -79,17 +82,16 @@ class ArticlesController extends Controller
/**
* Process an incoming request to edit an article.
*
- * @param \Illuminate\Http\Request $request
- * @param string
- * @return \Illuminate|View\Factory view
+ * @param int $articleId
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function update(Request $request, $articleId)
+ public function update(int $articleId): RedirectResponse
{
$article = Article::find($articleId);
- $article->title = $request->input('title');
- $article->url = $request->input('url');
- $article->main = $request->input('main');
- $article->published = $request->input('published') ?? 0;
+ $article->title = request()->input('title');
+ $article->url = request()->input('url');
+ $article->main = request()->input('main');
+ $article->published = request()->input('published') ?? 0;
$article->save();
return redirect('/admin/blog');
@@ -98,10 +100,10 @@ class ArticlesController extends Controller
/**
* Process a request to delete an aricle.
*
- * @param string The article id
- * @return \Illuminate\View\Factory view
+ * @param int $articleId
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function destroy($articleId)
+ public function destroy(int $articleId): RedirectResponse
{
Article::where('id', $articleId)->delete();
diff --git a/app/Http/Controllers/Admin/ClientsController.php b/app/Http/Controllers/Admin/ClientsController.php
index 366e0994..9eb37c97 100644
--- a/app/Http/Controllers/Admin/ClientsController.php
+++ b/app/Http/Controllers/Admin/ClientsController.php
@@ -1,19 +1,23 @@
$request->input('client_url'),
- 'client_name' => $request->input('client_name'),
+ 'client_url' => request()->input('client_url'),
+ 'client_name' => request()->input('client_name'),
]);
return redirect('/admin/clients');
@@ -49,10 +52,10 @@ class ClientsController extends Controller
/**
* Show a form to edit a client name.
*
- * @param string The client id
- * @return \Illuminate\View\Factory view
+ * @param int $clientId
+ * @return \Illuminate\View\View
*/
- public function edit($clientId)
+ public function edit(int $clientId): View
{
$client = MicropubClient::findOrFail($clientId);
@@ -66,15 +69,14 @@ class ClientsController extends Controller
/**
* Process the request to edit a client name.
*
- * @param string The client id
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\View\Factory view
+ * @param int $clientId
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function update($clientId, Request $request)
+ public function update(int $clientId): RedirectResponse
{
$client = MicropubClient::findOrFail($clientId);
- $client->client_url = $request->input('client_url');
- $client->client_name = $request->input('client_name');
+ $client->client_url = request()->input('client_url');
+ $client->client_name = request()->input('client_name');
$client->save();
return redirect('/admin/clients');
@@ -83,10 +85,10 @@ class ClientsController extends Controller
/**
* Process a request to delete a client.
*
- * @param string The client id
- * @return redirect
+ * @param int $clientId
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function destroy($clientId)
+ public function destroy(int $clientId): RedirectResponse
{
MicropubClient::where('id', $clientId)->delete();
diff --git a/app/Http/Controllers/Admin/ContactsController.php b/app/Http/Controllers/Admin/ContactsController.php
index 82ec7e88..c32aa610 100644
--- a/app/Http/Controllers/Admin/ContactsController.php
+++ b/app/Http/Controllers/Admin/ContactsController.php
@@ -1,21 +1,25 @@
name = $request->input('name');
- $contact->nick = $request->input('nick');
- $contact->homepage = $request->input('homepage');
- $contact->twitter = $request->input('twitter');
- $contact->facebook = $request->input('facebook');
+ $contact->name = request()->input('name');
+ $contact->nick = request()->input('nick');
+ $contact->homepage = request()->input('homepage');
+ $contact->twitter = request()->input('twitter');
+ $contact->facebook = request()->input('facebook');
$contact->save();
return redirect('/admin/contacts');
@@ -54,10 +57,10 @@ class ContactsController extends Controller
/**
* Show the form to edit an existing contact.
*
- * @param string The contact id
- * @return \Illuminate\View\Factory view
+ * @param int $contactId
+ * @return \Illuminate\View\View
*/
- public function edit($contactId)
+ public function edit(int $contactId): View
{
$contact = Contact::findOrFail($contactId);
@@ -69,28 +72,27 @@ class ContactsController extends Controller
*
* @todo Allow saving profile pictures for people without homepages
*
- * @param string The contact id
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\View\Factory view
+ * @param int $contactId
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function update($contactId, Request $request)
+ public function update(int $contactId): RedirectResponse
{
$contact = Contact::findOrFail($contactId);
- $contact->name = $request->input('name');
- $contact->nick = $request->input('nick');
- $contact->homepage = $request->input('homepage');
- $contact->twitter = $request->input('twitter');
- $contact->facebook = $request->input('facebook');
+ $contact->name = request()->input('name');
+ $contact->nick = request()->input('nick');
+ $contact->homepage = request()->input('homepage');
+ $contact->twitter = request()->input('twitter');
+ $contact->facebook = request()->input('facebook');
$contact->save();
- if ($request->hasFile('avatar') && ($request->input('homepage') != '')) {
- $dir = parse_url($request->input('homepage'), PHP_URL_HOST);
+ if (request()->hasFile('avatar') && (request()->input('homepage') != '')) {
+ $dir = parse_url(request()->input('homepage'), PHP_URL_HOST);
$destination = public_path() . '/assets/profile-images/' . $dir;
$filesystem = new Filesystem();
if ($filesystem->isDirectory($destination) === false) {
$filesystem->makeDirectory($destination);
}
- $request->file('avatar')->move($destination, 'image');
+ request()->file('avatar')->move($destination, 'image');
}
return redirect('/admin/contacts');
@@ -99,10 +101,10 @@ class ContactsController extends Controller
/**
* Process the request to delete a contact.
*
- * @param string The contact id
- * @return \Illuminate\View\Factory view
+ * @param int $contactId
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function destroy($contactId)
+ public function destroy(int $contactId): RedirectResponse
{
$contact = Contact::findOrFail($contactId);
$contact->delete();
@@ -116,16 +118,16 @@ class ContactsController extends Controller
* This method attempts to find the microformat marked-up profile image
* from a given homepage and save it accordingly
*
- * @param string The contact id
- * @return \Illuminate\View\Factory view
+ * @param int $contactId
+ * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
- public function getAvatar($contactId)
+ public function getAvatar(int $contactId)
{
// Initialising
$avatarURL = null;
$avatar = null;
$contact = Contact::findOrFail($contactId);
- if (mb_strlen($contact->homepage !== null) !== 0) {
+ if ($contact->homepage !== null && mb_strlen($contact->homepage) !== 0) {
$client = resolve(Client::class);
try {
$response = $client->get($contact->homepage);
diff --git a/app/Http/Controllers/Admin/HomeController.php b/app/Http/Controllers/Admin/HomeController.php
index ebb06f31..6ad2d0d7 100644
--- a/app/Http/Controllers/Admin/HomeController.php
+++ b/app/Http/Controllers/Admin/HomeController.php
@@ -1,12 +1,20 @@
config('admin.user')]);
}
diff --git a/app/Http/Controllers/Admin/LikesController.php b/app/Http/Controllers/Admin/LikesController.php
index acb08222..6d69a879 100644
--- a/app/Http/Controllers/Admin/LikesController.php
+++ b/app/Http/Controllers/Admin/LikesController.php
@@ -12,6 +12,11 @@ use Illuminate\Http\RedirectResponse;
class LikesController extends Controller
{
+ /**
+ * List the likes that can be edited.
+ *
+ * @return \Illuminate\View\View
+ */
public function index(): View
{
$likes = Like::all();
@@ -19,11 +24,21 @@ class LikesController extends Controller
return view('admin.likes.index', compact('likes'));
}
+ /**
+ * Show the form to make a new like.
+ *
+ * @return \Illuminate\View\View
+ */
public function create(): View
{
return view('admin.likes.create');
}
+ /**
+ * Process a request to make a new like.
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
public function store(): RedirectResponse
{
$like = Like::create([
@@ -34,6 +49,12 @@ class LikesController extends Controller
return redirect('/admin/likes');
}
+ /**
+ * Display the form to edit a specific like.
+ *
+ * @param int $likeId
+ * @return \Illuminate\View\View
+ */
public function edit(int $likeId): View
{
$like = Like::findOrFail($likeId);
@@ -44,6 +65,12 @@ class LikesController extends Controller
]);
}
+ /**
+ * Process a request to edit a like.
+ *
+ * @param int $likeId
+ * @return \Illuminate\Http\RedirectResponse
+ */
public function update(int $likeId): RedirectResponse
{
$like = Like::findOrFail($likeId);
@@ -54,6 +81,12 @@ class LikesController extends Controller
return redirect('/admin/likes');
}
+ /**
+ * Process the request to delete a like.
+ *
+ * @param int $likeId
+ * @return \Illuminate\Http\RedirectResponse
+ */
public function destroy(int $likeId): RedirectResponse
{
Like::where('id', $likeId)->delete();
diff --git a/app/Http/Controllers/Admin/NotesController.php b/app/Http/Controllers/Admin/NotesController.php
index 44b4a30f..98ef6f9a 100644
--- a/app/Http/Controllers/Admin/NotesController.php
+++ b/app/Http/Controllers/Admin/NotesController.php
@@ -1,20 +1,24 @@
orderBy('id', 'desc')->get();
foreach ($notes as $note) {
@@ -27,9 +31,9 @@ class NotesController extends Controller
/**
* Show the form to make a new note.
*
- * @return \Illuminate\View\Factory view
+ * @return \Illuminate\View\View
*/
- public function create()
+ public function create(): View
{
return view('admin.notes.create');
}
@@ -37,14 +41,13 @@ class NotesController extends Controller
/**
* Process a request to make a new note.
*
- * @param Illuminate\Http\Request $request
- * @todo Sort this mess out
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function store(Request $request)
+ public function store(): RedirectResponse
{
Note::create([
- 'in-reply-to' => $request->input('in-reply-to'),
- 'note' => $request->input('content'),
+ 'in-reply-to' => request()->input('in-reply-to'),
+ 'note' => request()->input('content'),
]);
return redirect('/admin/notes');
@@ -53,10 +56,10 @@ class NotesController extends Controller
/**
* Display the form to edit a specific note.
*
- * @param string The note id
- * @return \Illuminate\View\Factory view
+ * @param int $noteId
+ * @return \Illuminate\View\View
*/
- public function edit($noteId)
+ public function edit(int $noteId): View
{
$note = Note::find($noteId);
$note->originalNote = $note->getOriginal('note');
@@ -68,18 +71,18 @@ class NotesController extends Controller
* Process a request to edit a note. Easy since this can only be done
* from the admin CP.
*
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\View\Factory view
+ * @param int $noteId
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function update($noteId, Request $request)
+ public function update(int $noteId): RedirectResponse
{
//update note data
$note = Note::findOrFail($noteId);
- $note->note = $request->input('content');
- $note->in_reply_to = $request->input('in-reply-to');
+ $note->note = request()->input('content');
+ $note->in_reply_to = request()->input('in-reply-to');
$note->save();
- if ($request->input('webmentions')) {
+ if (request()->input('webmentions')) {
dispatch(new SendWebMentions($note));
}
@@ -89,12 +92,12 @@ class NotesController extends Controller
/**
* Delete the note.
*
- * @param int id
- * @return view
+ * @param int $noteId
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function destroy($id)
+ public function destroy(int $noteId): RedirectResponse
{
- $note = Note::findOrFail($id);
+ $note = Note::findOrFail($noteId);
$note->delete();
return redirect('/admin/notes');
diff --git a/app/Http/Controllers/Admin/PlacesController.php b/app/Http/Controllers/Admin/PlacesController.php
index 4bf54f4a..9247eb31 100644
--- a/app/Http/Controllers/Admin/PlacesController.php
+++ b/app/Http/Controllers/Admin/PlacesController.php
@@ -1,11 +1,15 @@
only(['name', 'description', 'latitude', 'longitude']);
+ $data = request()->only(['name', 'description', 'latitude', 'longitude']);
$place = $this->placeService->createPlace($data);
return redirect('/admin/places');
@@ -56,10 +59,10 @@ class PlacesController extends Controller
/**
* Display the form to edit a specific place.
*
- * @param string The place id
- * @return \Illuminate\View\Factory view
+ * @param int $placeId
+ * @return \Illuminate\View\View
*/
- public function edit($placeId)
+ public function edit(int $placeId): View
{
$place = Place::findOrFail($placeId);
@@ -69,17 +72,19 @@ class PlacesController extends Controller
/**
* Process a request to edit a place.
*
- * @param string The place id
- * @param Illuminate\Http\Request $request
- * @return Illuminate\View\Factory view
+ * @param int $placeId
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function update($placeId, Request $request)
+ public function update(int $placeId): RedirectResponse
{
$place = Place::findOrFail($placeId);
- $place->name = $request->name;
- $place->description = $request->description;
- $place->location = new Point((float) $request->latitude, (float) $request->longitude);
- $place->icon = $request->icon;
+ $place->name = request()->input('name');
+ $place->description = request()->input('description');
+ $place->location = new Point(
+ (float) request()->input('latitude'),
+ (float) request()->input('longitude')
+ );
+ $place->icon = request()->input('icon');
$place->save();
return redirect('/admin/places');
@@ -88,10 +93,10 @@ class PlacesController extends Controller
/**
* List the places we can merge with the current place.
*
- * @param string Place id
- * @return Illuminate\View\Factory view
+ * @param int $placeId
+ * @return \Illuminate\View\View
*/
- public function mergeIndex($placeId)
+ public function mergeIndex(int $placeId): View
{
$first = Place::find($placeId);
$results = Place::near(new Point($first->latitude, $first->longitude))->get();
@@ -105,27 +110,39 @@ class PlacesController extends Controller
return view('admin.places.merge.index', compact('first', 'places'));
}
- public function mergeEdit($place1_id, $place2_id)
+ /**
+ * Show a form for merging two specific places.
+ *
+ * @param int $placeId1
+ * @param int $placeId2
+ * @return \Illuminate\View\View
+ */
+ public function mergeEdit(int $placeId1, int $placeId2): View
{
- $place1 = Place::find($place1_id);
- $place2 = Place::find($place2_id);
+ $place1 = Place::find($placeId1);
+ $place2 = Place::find($placeId2);
return view('admin.places.merge.edit', compact('place1', 'place2'));
}
- public function mergeStore(Request $request)
+ /**
+ * Process the request to merge two places.
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function mergeStore(): RedirectResponse
{
- $place1 = Place::find($request->input('place1'));
- $place2 = Place::find($request->input('place2'));
+ $place1 = Place::find(request()->input('place1'));
+ $place2 = Place::find(request()->input('place2'));
- if ($request->input('delete') === '1') {
+ if (request()->input('delete') === '1') {
foreach ($place1->notes as $note) {
$note->place()->dissociate();
$note->place()->associate($place2->id);
}
$place1->delete();
}
- if ($request->input('delete') === '2') {
+ if (request()->input('delete') === '2') {
foreach ($place2->notes as $note) {
$note->place()->dissociate();
$note->place()->associate($place1->id);
diff --git a/app/Http/Controllers/ArticlesController.php b/app/Http/Controllers/ArticlesController.php
index df2f1988..cdb91b61 100644
--- a/app/Http/Controllers/ArticlesController.php
+++ b/app/Http/Controllers/ArticlesController.php
@@ -1,21 +1,27 @@
date((int) $year, (int) $month)
+ ->date($year, $month)
->orderBy('updated_at', 'desc')
->simplePaginate(5);
@@ -25,9 +31,12 @@ class ArticlesController extends Controller
/**
* Show a single article.
*
- * @return \Illuminate\View\Factory view
+ * @param int $year
+ * @param int $month
+ * @param string $slug
+ * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
- public function show($year, $month, $slug)
+ public function show(int $year, int $month, string $slug)
{
$article = Article::where('titleurl', $slug)->firstOrFail();
if ($article->updated_at->year != $year || $article->updated_at->month != $month) {
@@ -44,12 +53,12 @@ class ArticlesController extends Controller
* We only have the ID, work out post title, year and month
* and redirect to it.
*
- * @return \Illuminte\Routing\RedirectResponse redirect
+ * @param int $idFromUrl
+ * @return \Illuminte\Http\RedirectResponse
*/
- public function onlyIdInUrl($inURLId)
+ public function onlyIdInUrl(int $idFromUrl): RedirectResponse
{
- $numbers = new Numbers();
- $realId = $numbers->b60tonum($inURLId);
+ $realId = resolve(Numbers::class)->b60tonum($idFromUrl);
$article = Article::findOrFail($realId);
return redirect($article->link);
diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php
index b58ed184..b2793be4 100644
--- a/app/Http/Controllers/AuthController.php
+++ b/app/Http/Controllers/AuthController.php
@@ -1,12 +1,21 @@
input('username') === config('admin.user')
+ if (request()->input('username') === config('admin.user')
&&
- $request->input('password') === config('admin.pass')
+ request()->input('password') === config('admin.pass')
) {
session(['loggedin' => true]);
diff --git a/app/Http/Controllers/BookmarksController.php b/app/Http/Controllers/BookmarksController.php
index a19bdeb6..8bd95d96 100644
--- a/app/Http/Controllers/BookmarksController.php
+++ b/app/Http/Controllers/BookmarksController.php
@@ -1,19 +1,33 @@
with('tags')->withCount('tags')->paginate(10);
return view('bookmarks.index', compact('bookmarks'));
}
- public function show(Bookmark $bookmark)
+ /**
+ * Show a single bookmark.
+ *
+ * @param \App\Models\Bookmark $bookmark
+ * @return \Illuminate\View\View
+ */
+ public function show(Bookmark $bookmark): View
{
$bookmark->loadMissing('tags');
diff --git a/app/Http/Controllers/ContactsController.php b/app/Http/Controllers/ContactsController.php
index c85e12a4..5ed7f945 100644
--- a/app/Http/Controllers/ContactsController.php
+++ b/app/Http/Controllers/ContactsController.php
@@ -1,8 +1,11 @@
firstOrFail();
diff --git a/app/Http/Controllers/FeedsController.php b/app/Http/Controllers/FeedsController.php
index 2d6da628..3ffb99f8 100644
--- a/app/Http/Controllers/FeedsController.php
+++ b/app/Http/Controllers/FeedsController.php
@@ -1,7 +1,10 @@
latest('updated_at')->take(20)->get();
$buildDate = $articles->first()->updated_at->toRssString();
@@ -26,7 +29,7 @@ class FeedsController extends Controller
*
* @return \Illuminate\Http\Response
*/
- public function blogAtom()
+ public function blogAtom(): Response
{
$articles = Article::where('published', '1')->latest('updated_at')->take(20)->get();
@@ -40,7 +43,7 @@ class FeedsController extends Controller
*
* @return \Illuminate\Http\Response
*/
- public function notesRss()
+ public function notesRss(): Response
{
$notes = Note::latest()->take(20)->get();
$buildDate = $notes->first()->updated_at->toRssString();
@@ -55,7 +58,7 @@ class FeedsController extends Controller
*
* @return \Illuminate\Http\Response
*/
- public function notesAtom()
+ public function notesAtom(): Response
{
$notes = Note::latest()->take(20)->get();
@@ -64,10 +67,12 @@ class FeedsController extends Controller
->header('Content-Type', 'application/atom+xml; charset=utf-8');
}
+ /** @todo sort out return type for json responses */
+
/**
* Returns the blog JSON feed.
*
- * @return \Illuminate\Http\response
+ * @return \Illuminate\Http\JsonResponse
*/
public function blogJson()
{
@@ -100,7 +105,7 @@ class FeedsController extends Controller
/**
* Returns the notes JSON feed.
*
- * @return \Illuminate\Http\response
+ * @return \Illuminate\Http\JsonResponse
*/
public function notesJson()
{
diff --git a/app/Http/Controllers/LikesController.php b/app/Http/Controllers/LikesController.php
index ea9e503b..dbc92ec6 100644
--- a/app/Http/Controllers/LikesController.php
+++ b/app/Http/Controllers/LikesController.php
@@ -1,19 +1,33 @@
paginate(20);
return view('likes.index', compact('likes'));
}
- public function show(Like $like)
+ /**
+ * Show a single like.
+ *
+ * @param \App\Models\Like $like
+ * @return \Illuminate\View\View
+ */
+ public function show(Like $like): View
{
return view('likes.show', compact('like'));
}
diff --git a/app/Http/Controllers/MicropubController.php b/app/Http/Controllers/MicropubController.php
index a0fd24b0..149f8acc 100644
--- a/app/Http/Controllers/MicropubController.php
+++ b/app/Http/Controllers/MicropubController.php
@@ -1,11 +1,14 @@
input('access_token'));
$tokenData = $this->tokenService->validateToken(request()->input('access_token'));
} catch (InvalidTokenException $e) {
return $this->invalidTokenResponse();
@@ -96,14 +98,16 @@ class MicropubController extends Controller
}
/**
+ * Respond to a GET request to the micropub endpoint.
+ *
* A GET request has been made to `api/post` with an accompanying
* token, here we check wether the token is valid and respond
* appropriately. Further if the request has the query parameter
* synidicate-to we respond with the known syndication endpoints.
*
- * @return \Illuminate\Http\Response
+ * @return \Illuminate\Http\JsonResponse
*/
- public function get()
+ public function get(): JsonResponse
{
try {
$tokenData = $this->tokenService->validateToken(request()->bearerToken());
@@ -124,7 +128,7 @@ class MicropubController extends Controller
]);
}
- if (substr(request()->input('q'), 0, 4) === 'geo:') {
+ if (request()->has('q') && substr(request()->input('q'), 0, 4) === 'geo:') {
preg_match_all(
'/([0-9\.\-]+)/',
request()->input('q'),
@@ -153,9 +157,9 @@ class MicropubController extends Controller
/**
* Process a media item posted to the media endpoint.
*
- * @return Illuminate\Http\Response
+ * @return Illuminate\Http\JsonResponse
*/
- public function media()
+ public function media(): JsonResponse
{
try {
$tokenData = $this->tokenService->validateToken(request()->bearerToken());
@@ -210,10 +214,10 @@ class MicropubController extends Controller
/**
* Get the file type from the mimetype of the uploaded file.
*
- * @param string The mimetype
- * @return string The type
+ * @param string $mimetype
+ * @return string
*/
- private function getFileTypeFromMimeType($mimetype)
+ private function getFileTypeFromMimeType(string $mimetype): string
{
//try known images
$imageMimeTypes = [
@@ -252,6 +256,11 @@ class MicropubController extends Controller
return 'download';
}
+ /**
+ * Determine the client id from the access token sent with the request.
+ *
+ * @return string
+ */
private function getClientId(): string
{
return resolve(TokenService::class)
@@ -259,6 +268,11 @@ class MicropubController extends Controller
->getClaim('client_id');
}
+ /**
+ * Save the details of the micropub request to a log file.
+ *
+ * @param array $request This is the info from request()->all()
+ */
private function logMicropubRequest(array $request)
{
$logger = new Logger('micropub');
@@ -266,7 +280,13 @@ class MicropubController extends Controller
$logger->debug('MicropubLog', $request);
}
- private function saveFile(UploadedFile $file)
+ /**
+ * Save an uploaded file to the local disk.
+ *
+ * @param \Illuminate\Http\UploadedFele $file
+ * @return string $filename
+ */
+ private function saveFile(UploadedFile $file): string
{
$filename = Uuid::uuid4() . '.' . $file->extension();
Storage::disk('local')->put($filename, $file);
@@ -274,6 +294,11 @@ class MicropubController extends Controller
return $filename;
}
+ /**
+ * Generate a response to be returned when the token has insufficient scope.
+ *
+ * @return \Illuminate\Http\JsonRepsonse
+ */
private function insufficientScopeResponse()
{
return response()->json([
@@ -283,6 +308,11 @@ class MicropubController extends Controller
], 401);
}
+ /**
+ * Generate a response to be returned when the token is invalid.
+ *
+ * @return \Illuminate\Http\JsonRepsonse
+ */
private function invalidTokenResponse()
{
return response()->json([
@@ -292,6 +322,11 @@ class MicropubController extends Controller
], 400);
}
+ /**
+ * Generate a response to be returned when the token has no scope.
+ *
+ * @return \Illuminate\Http\JsonRepsonse
+ */
private function tokenHasNoScopeResponse()
{
return response()->json([
diff --git a/app/Http/Controllers/NotesController.php b/app/Http/Controllers/NotesController.php
index 06ab3eb8..d5ff483e 100644
--- a/app/Http/Controllers/NotesController.php
+++ b/app/Http/Controllers/NotesController.php
@@ -1,10 +1,14 @@
with('webmentions')->firstOrFail();
@@ -51,10 +55,10 @@ class NotesController extends Controller
/**
* Redirect /note/{decID} to /notes/{nb60id}.
*
- * @param string The decimal id of he note
- * @return \Illuminate\Routing\RedirectResponse redirect
+ * @param int $decId The decimal id of the note
+ * @return \Illuminate\Http\RedirectResponse
*/
- public function redirect($decId)
+ public function redirect(int $decId): RedirectResponse
{
return redirect(config('app.url') . '/notes/' . (new Numbers())->numto60($decId));
}
@@ -62,10 +66,10 @@ class NotesController extends Controller
/**
* Show all notes tagged with {tag}.
*
- * @param string The tag
- * @return \Illuminate\View\Factory view
+ * @param string $tag
+ * @return \Illuminate\View\View
*/
- public function tagged($tag)
+ public function tagged(string $tag): View
{
$notes = Note::whereHas('tags', function ($query) use ($tag) {
$query->where('tag', $tag);
diff --git a/app/Http/Controllers/PlacesController.php b/app/Http/Controllers/PlacesController.php
index 37ee61f7..f93ab259 100644
--- a/app/Http/Controllers/PlacesController.php
+++ b/app/Http/Controllers/PlacesController.php
@@ -1,17 +1,20 @@
firstOrFail();
diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index 6ef9af6c..b03c16d0 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -1,15 +1,22 @@
terms)->paginate(10);
+ $notes = Note::search(request()->input('terms'))->paginate(10);
return view('search', compact('notes'));
}
diff --git a/app/Http/Controllers/SessionStoreController.php b/app/Http/Controllers/SessionStoreController.php
index c7d239eb..042aa958 100644
--- a/app/Http/Controllers/SessionStoreController.php
+++ b/app/Http/Controllers/SessionStoreController.php
@@ -1,9 +1,16 @@
input('css');
diff --git a/app/Http/Controllers/ShortURLsController.php b/app/Http/Controllers/ShortURLsController.php
index a4979ca0..2510a7b0 100644
--- a/app/Http/Controllers/ShortURLsController.php
+++ b/app/Http/Controllers/ShortURLsController.php
@@ -1,7 +1,11 @@
client->discoverAuthorizationEndpoint(normalize_url($request->input('me')));
+ $authorizationEndpoint = $this->client->discoverAuthorizationEndpoint(normalize_url(request()->input('me')));
if ($authorizationEndpoint) {
$auth = $this->client->verifyIndieAuthCode(
$authorizationEndpoint,
- $request->input('code'),
- $request->input('me'),
- $request->input('redirect_uri'),
- $request->input('client_id')
+ request()->input('code'),
+ request()->input('me'),
+ request()->input('redirect_uri'),
+ request()->input('client_id')
);
if (array_key_exists('me', $auth)) {
$scope = $auth['scope'] ?? '';
$tokenData = [
- 'me' => $request->input('me'),
- 'client_id' => $request->input('client_id'),
+ 'me' => request()->input('me'),
+ 'client_id' => request()->input('client_id'),
'scope' => $scope,
];
$token = $this->tokenService->getNewToken($tokenData);
$content = http_build_query([
- 'me' => $request->input('me'),
+ 'me' => request()->input('me'),
'scope' => $scope,
'access_token' => $token,
]);
diff --git a/app/Http/Controllers/WebMentionsController.php b/app/Http/Controllers/WebMentionsController.php
index b9110f56..960840ea 100644
--- a/app/Http/Controllers/WebMentionsController.php
+++ b/app/Http/Controllers/WebMentionsController.php
@@ -1,9 +1,11 @@
has('target') !== true) || ($request->has('source') !== true)) {
- return new Response(
+ if ((request()->has('target') !== true) || (request()->has('source') !== true)) {
+ return response(
'You need both the target and source parameters',
400
);
}
//next check the $target is valid
- $path = parse_url($request->input('target'), PHP_URL_PATH);
+ $path = parse_url(request()->input('target'), PHP_URL_PATH);
$pathParts = explode('/', $path);
if ($pathParts[1] == 'notes') {
//we have a note
$noteId = $pathParts[2];
- $numbers = new Numbers();
try {
- $note = Note::findOrFail($numbers->b60tonum($noteId));
- dispatch(new ProcessWebMention($note, $request->input('source')));
+ $note = Note::findOrFail(resolve(Numbers::class)->b60tonum($noteId));
+ dispatch(new ProcessWebMention($note, request()->input('source')));
} catch (ModelNotFoundException $e) {
- return new Response('This note doesn’t exist.', 400);
+ return response('This note doesn’t exist.', 400);
}
- return new Response(
+ return response(
'Webmention received, it will be processed shortly',
202
);
}
if ($pathParts[1] == 'blog') {
- return new Response(
+ return response(
'I don’t accept webmentions for blog posts yet.',
501
);
}
- return new Response(
+ return response(
'Invalid request',
400
);
diff --git a/app/Http/Middleware/ActivityStreamLinks.php b/app/Http/Middleware/ActivityStreamLinks.php
index 4c240759..4cad411f 100644
--- a/app/Http/Middleware/ActivityStreamLinks.php
+++ b/app/Http/Middleware/ActivityStreamLinks.php
@@ -1,8 +1,11 @@
path() === '/') {
diff --git a/app/Http/Middleware/LocalhostSessionMiddleware.php b/app/Http/Middleware/LocalhostSessionMiddleware.php
index ded4f25a..5131b9fc 100644
--- a/app/Http/Middleware/LocalhostSessionMiddleware.php
+++ b/app/Http/Middleware/LocalhostSessionMiddleware.php
@@ -1,8 +1,11 @@
config('app.url')]);
diff --git a/app/Http/Middleware/MyAuthMiddleware.php b/app/Http/Middleware/MyAuthMiddleware.php
index 5354e55b..73b04266 100644
--- a/app/Http/Middleware/MyAuthMiddleware.php
+++ b/app/Http/Middleware/MyAuthMiddleware.php
@@ -1,8 +1,11 @@
session()->has('loggedin') !== true) {
//they’re not logged in, so send them to login form
diff --git a/app/Http/Middleware/VerifyMicropubToken.php b/app/Http/Middleware/VerifyMicropubToken.php
index 73edd404..aa650560 100644
--- a/app/Http/Middleware/VerifyMicropubToken.php
+++ b/app/Http/Middleware/VerifyMicropubToken.php
@@ -1,8 +1,11 @@
input('access_token')) {
return $next($request);
diff --git a/app/Jobs/AddClientToDatabase.php b/app/Jobs/AddClientToDatabase.php
index 89e2cae5..b7d9c0f4 100644
--- a/app/Jobs/AddClientToDatabase.php
+++ b/app/Jobs/AddClientToDatabase.php
@@ -1,5 +1,7 @@
getStatusCode() == '200') {
- $filesystem = new \Illuminate\FileSystem\FileSystem();
+ $filesystem = new FileSystem();
$filename = storage_path('HTML') . '/' . $this->createFilenameFromURL($this->source);
//backup file first
$filenameBackup = $filename . '.' . date('Y-m-d') . '.backup';
diff --git a/app/Jobs/ProcessBookmark.php b/app/Jobs/ProcessBookmark.php
index 14e4ac4c..491c2b5c 100644
--- a/app/Jobs/ProcessBookmark.php
+++ b/app/Jobs/ProcessBookmark.php
@@ -1,5 +1,7 @@
isTweet($this->like->url)) {
$tweet = Twitter::getOembed(['url' => $this->like->url]);
@@ -83,8 +87,16 @@ class ProcessLike implements ShouldQueue
}
$this->like->save();
+
+ return 0;
}
+ /**
+ * Determine if a given URL is that of a Tweet.
+ *
+ * @param string $url
+ * @return bool
+ */
private function isTweet(string $url): bool
{
$host = parse_url($url, PHP_URL_HOST);
diff --git a/app/Jobs/ProcessMedia.php b/app/Jobs/ProcessMedia.php
index 08985383..dcac4a82 100644
--- a/app/Jobs/ProcessMedia.php
+++ b/app/Jobs/ProcessMedia.php
@@ -1,5 +1,7 @@
microformats = $microformats;
}
@@ -30,7 +32,7 @@ class SaveProfileImage implements ShouldQueue
/**
* Execute the job.
*
- * @return void
+ * @param \Jonnybarnes\WebmentionsParser\Authorship $authorship
*/
public function handle(Authorship $authorship)
{
diff --git a/app/Jobs/SendWebMentions.php b/app/Jobs/SendWebMentions.php
index 0635e117..e60946ff 100644
--- a/app/Jobs/SendWebMentions.php
+++ b/app/Jobs/SendWebMentions.php
@@ -1,5 +1,7 @@
note->in_reply_to);
+ $inReplyTo = $this->note->in_reply_to ?? '';
+ // above so explode doesn’t complain about null being passed in
+ $urlsInReplyTo = explode(' ', $inReplyTo);
$urlsNote = $this->getLinks($this->note->note);
$urls = array_filter(array_merge($urlsInReplyTo, $urlsNote)); //filter out none URLs
foreach ($urls as $url) {
@@ -54,10 +57,10 @@ class SendWebMentions implements ShouldQueue
/**
* Discover if a URL has a webmention endpoint.
*
- * @param string The URL
- * @return string The webmention endpoint URL
+ * @param string $url
+ * @return string|null
*/
- public function discoverWebmentionEndpoint($url)
+ public function discoverWebmentionEndpoint(string $url)
{
//let’s not send webmentions to myself
if (parse_url($url, PHP_URL_HOST) == config('app.longurl')) {
@@ -97,8 +100,8 @@ class SendWebMentions implements ShouldQueue
/**
* Get the URLs from a note.
*
- * @param string $html
- * @return array $urls
+ * @param string $html
+ * @return array $urls
*/
public function getLinks($html)
{
@@ -119,8 +122,8 @@ class SendWebMentions implements ShouldQueue
/**
* Resolve a URI if necessary.
*
- * @param string $url
- * @param string $base
+ * @param string $url
+ * @param string $base The base of the URL
* @return string
*/
public function resolveUri(string $url, string $base): string
diff --git a/app/Jobs/SyndicateBookmarkToFacebook.php b/app/Jobs/SyndicateBookmarkToFacebook.php
index dc555f8a..973ea249 100644
--- a/app/Jobs/SyndicateBookmarkToFacebook.php
+++ b/app/Jobs/SyndicateBookmarkToFacebook.php
@@ -1,5 +1,7 @@
[
@@ -52,7 +55,7 @@ class Article extends Model
*
* @return string
*/
- public function getHtmlAttribute()
+ public function getHtmlAttribute(): string
{
$markdown = new CommonMarkConverter();
$html = $markdown->convertToHtml($this->main);
@@ -70,7 +73,7 @@ class Article extends Model
*
* @return string
*/
- public function getW3cTimeAttribute()
+ public function getW3cTimeAttribute(): string
{
return $this->updated_at->toW3CString();
}
@@ -80,7 +83,7 @@ class Article extends Model
*
* @return string
*/
- public function getTooltipTimeAttribute()
+ public function getTooltipTimeAttribute(): string
{
return $this->updated_at->toRFC850String();
}
@@ -90,7 +93,7 @@ class Article extends Model
*
* @return string
*/
- public function getHumanTimeAttribute()
+ public function getHumanTimeAttribute(): string
{
return $this->updated_at->diffForHumans();
}
@@ -100,7 +103,7 @@ class Article extends Model
*
* @return string
*/
- public function getPubdateAttribute()
+ public function getPubdateAttribute(): string
{
return $this->updated_at->toRSSString();
}
@@ -110,7 +113,7 @@ class Article extends Model
*
* @return string
*/
- public function getLinkAttribute()
+ public function getLinkAttribute(): string
{
return '/blog/' . $this->updated_at->year . '/' . $this->updated_at->format('m') . '/' . $this->titleurl;
}
@@ -120,7 +123,7 @@ class Article extends Model
*
* @return \Illuminate\Database\Eloquent\Builder
*/
- public function scopeDate($query, int $year = null, int $month = null)
+ public function scopeDate($query, int $year = null, int $month = null): Builder
{
if ($year == null) {
return $query;
diff --git a/app/Models/Bookmark.php b/app/Models/Bookmark.php
index 9b9ab747..e633098b 100644
--- a/app/Models/Bookmark.php
+++ b/app/Models/Bookmark.php
@@ -1,5 +1,7 @@
id;
}
diff --git a/app/Models/Contact.php b/app/Models/Contact.php
index b77decc7..5cf4bb82 100644
--- a/app/Models/Contact.php
+++ b/app/Models/Contact.php
@@ -1,5 +1,7 @@
attributes['url'] = normalize_url($value);
}
- public function setAuthorUrlAttribute($value)
+ /**
+ * Normalize the URL of the author of the like.
+ *
+ * @param string $value The author’s url
+ */
+ public function setAuthorUrlAttribute(?string $value)
{
$this->attributes['author_url'] = normalize_url($value);
}
- public function getContentAttribute($value)
+ /**
+ * If the content contains HTML, filter it.
+ *
+ * @param string $value The content of the like
+ * @return string|null
+ */
+ public function getContentAttribute(?string $value): ?string
{
if ($value === null) {
return null;
@@ -38,7 +56,13 @@ class Like extends Model
return $value;
}
- public function filterHTML($html)
+ /**
+ * Filter some HTML with HTMLPurifier.
+ *
+ * @param string $html
+ * @return string
+ */
+ private function filterHTML(string $html): string
{
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.SerializerPath', storage_path() . '/HTMLPurifier');
diff --git a/app/Models/Media.php b/app/Models/Media.php
index 232d3132..4d25c74f 100644
--- a/app/Models/Media.php
+++ b/app/Models/Media.php
@@ -1,8 +1,11 @@
belongsTo('App\Models\Note');
}
@@ -33,7 +38,7 @@ class Media extends Model
*
* @return string
*/
- public function getUrlAttribute()
+ public function getUrlAttribute(): string
{
if (starts_with($this->path, 'https://')) {
return $this->path;
@@ -47,7 +52,7 @@ class Media extends Model
*
* @return string
*/
- public function getMediumurlAttribute()
+ public function getMediumurlAttribute(): string
{
$basename = $this->getBasename($this->path);
$extension = $this->getExtension($this->path);
@@ -60,7 +65,7 @@ class Media extends Model
*
* @return string
*/
- public function getSmallurlAttribute()
+ public function getSmallurlAttribute(): string
{
$basename = $this->getBasename($this->path);
$extension = $this->getExtension($this->path);
@@ -68,7 +73,13 @@ class Media extends Model
return config('filesystems.disks.s3.url') . '/' . $basename . '-small.' . $extension;
}
- public function getBasename($path)
+ /**
+ * Give the real part of a filename, i.e. strip the file extension.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getBasename(string $path): string
{
// the following achieves this data flow
// foo.bar.png => ['foo', 'bar', 'png'] => ['foo', 'bar'] => foo.bar
@@ -81,7 +92,13 @@ class Media extends Model
return $basename;
}
- public function getExtension($path)
+ /**
+ * Get the extension from a given filename.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getExtension(string $path): string
{
$parts = explode('.', $path);
diff --git a/app/Models/MicropubClient.php b/app/Models/MicropubClient.php
index d769b193..5d2b45e0 100644
--- a/app/Models/MicropubClient.php
+++ b/app/Models/MicropubClient.php
@@ -1,8 +1,11 @@
hasMany('App\Models\Note', 'client_id', 'client_url');
}
diff --git a/app/Models/Note.php b/app/Models/Note.php
index 0acb627a..73f504a7 100644
--- a/app/Models/Note.php
+++ b/app/Models/Note.php
@@ -1,5 +1,7 @@
$this->note,
@@ -127,30 +138,36 @@ class Note extends Model
/**
* Normalize the note to Unicode FORM C.
*
- * @param string $value
- * @return string
+ * @param string|null $value
*/
- public function setNoteAttribute($value)
+ public function setNoteAttribute(?string $value)
{
- $normalized = normalizer_normalize($value, Normalizer::FORM_C);
- if ($normalized === '') { //we don’t want to save empty strings to the db
- $normalized = null;
+ if ($value !== null) {
+ $normalized = normalizer_normalize($value, Normalizer::FORM_C);
+ if ($normalized === '') { //we don’t want to save empty strings to the db
+ $normalized = null;
+ }
+ $this->attributes['note'] = $normalized;
}
- $this->attributes['note'] = $normalized;
}
/**
* Pre-process notes for web-view.
*
- * @param string
- * @return string
+ * @param string|null $value
+ * @return string|null
*/
- public function getNoteAttribute($value)
+ public function getNoteAttribute(?string $value): ?string
{
if ($value === null && $this->place !== null) {
$value = '📍: ' . $this->place->name . '';
}
+ // if $value is still null, just return null
+ if ($value === null) {
+ return null;
+ }
+
$hcards = $this->makeHCards($value);
$hashtags = $this->autoLinkHashtag($hcards);
$html = $this->convertMarkdown($hashtags);
@@ -164,11 +181,10 @@ class Note extends Model
*
* @return string
*/
- public function getNb60idAttribute()
+ public function getNb60idAttribute(): string
{
- $numbers = new Numbers();
-
- return $numbers->numto60($this->id);
+ // we cast to string because sometimes the nb60id is an “int”
+ return (string) resolve(Numbers::class)->numto60($this->id);
}
/**
@@ -176,7 +192,7 @@ class Note extends Model
*
* @return string
*/
- public function getLongurlAttribute()
+ public function getLongurlAttribute(): string
{
return config('app.url') . '/notes/' . $this->nb60id;
}
@@ -186,7 +202,7 @@ class Note extends Model
*
* @return string
*/
- public function getShorturlAttribute()
+ public function getShorturlAttribute(): string
{
return config('app.shorturl') . '/notes/' . $this->nb60id;
}
@@ -196,7 +212,7 @@ class Note extends Model
*
* @return string
*/
- public function getIso8601Attribute()
+ public function getIso8601Attribute(): string
{
return $this->updated_at->toISO8601String();
}
@@ -206,7 +222,7 @@ class Note extends Model
*
* @return string
*/
- public function getHumandiffAttribute()
+ public function getHumandiffAttribute(): string
{
return $this->updated_at->diffForHumans();
}
@@ -216,7 +232,7 @@ class Note extends Model
*
* @return string
*/
- public function getPubdateAttribute()
+ public function getPubdateAttribute(): string
{
return $this->updated_at->toRSSString();
}
@@ -224,9 +240,9 @@ class Note extends Model
/**
* Get the latitude value.
*
- * @return string|null
+ * @return float|null
*/
- public function getLatitudeAttribute()
+ public function getLatitudeAttribute(): ?float
{
if ($this->place !== null) {
return $this->place->location->getLat();
@@ -235,16 +251,18 @@ class Note extends Model
$pieces = explode(':', $this->location);
$latlng = explode(',', $pieces[0]);
- return trim($latlng[0]);
+ return (float) trim($latlng[0]);
}
+
+ return null;
}
/**
* Get the longitude value.
*
- * @return string|null
+ * @return float|null
*/
- public function getLongitudeAttribute()
+ public function getLongitudeAttribute(): ?float
{
if ($this->place !== null) {
return $this->place->location->getLng();
@@ -253,8 +271,10 @@ class Note extends Model
$pieces = explode(':', $this->location);
$latlng = explode(',', $pieces[0]);
- return trim($latlng[1]);
+ return (float) trim($latlng[1]);
}
+
+ return null;
}
/**
@@ -263,7 +283,7 @@ class Note extends Model
*
* @return string|null
*/
- public function getAddressAttribute()
+ public function getAddressAttribute(): ?string
{
if ($this->place !== null) {
return $this->place->name;
@@ -271,12 +291,19 @@ class Note extends Model
if ($this->location !== null) {
return $this->reverseGeoCode((float) $this->latitude, (float) $this->longitude);
}
+
+ return null;
}
- public function getTwitterAttribute()
+ /**
+ * Get the OEmbed html for a tweet the note is a reply to.
+ *
+ * @return object|null
+ */
+ public function getTwitterAttribute(): ?object
{
if ($this->in_reply_to == null || mb_substr($this->in_reply_to, 0, 20, 'UTF-8') !== 'https://twitter.com/') {
- return;
+ return null;
}
$tweetId = basename($this->in_reply_to);
@@ -292,7 +319,7 @@ class Note extends Model
'maxwidth' => 512,
]);
} catch (\Exception $e) {
- return;
+ return null;
}
Cache::put($tweetId, $oEmbed, ($oEmbed->cache_age / 60));
@@ -301,20 +328,24 @@ class Note extends Model
/**
* Show a specific form of the note for twitter.
+ *
+ * That is we swap the contacts names for their known Twitter handles.
+ *
+ * @return string|null
*/
- public function getTwitterContentAttribute()
+ public function getTwitterContentAttribute(): ?string
{
if ($this->contacts === null) {
- return;
+ return null;
}
if (count($this->contacts) === 0) {
- return;
+ return null;
}
if (count(array_unique(array_values($this->contacts))) === 1
&& array_unique(array_values($this->contacts))[0] === null) {
- return;
+ return null;
}
// swap in twitter usernames
@@ -338,15 +369,22 @@ class Note extends Model
return $this->convertMarkdown($swapped);
}
- public function getFacebookContentAttribute()
+ /**
+ * Show a specific form of the note for facebook.
+ *
+ * That is we swap the contacts names for their known Facebook usernames.
+ *
+ * @return string|null
+ */
+ public function getFacebookContentAttribute(): ?string
{
if (count($this->contacts) === 0) {
- return;
+ return null;
}
if (count(array_unique(array_values($this->contacts))) === 1
&& array_unique(array_values($this->contacts))[0] === null) {
- return;
+ return null;
}
// swap in facebook usernames
@@ -374,27 +412,27 @@ class Note extends Model
/**
* Scope a query to select a note via a NewBase60 id.
*
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param string $nb60id
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param string $nb60id
* @return \Illuminate\Database\Eloquent\Builder
*/
- public function scopeNb60($query, $nb60id)
+ public function scopeNb60(Builder $query, string $nb60id): Builder
{
- $numbers = new Numbers();
-
- return $query->where('id', $numbers->b60tonum($nb60id));
+ return $query->where('id', resolve(Numbers::class)->b60tonum($nb60id));
}
/**
+ * Swap contact’s nicks for a full mf2 h-card.
+ *
* Take note that this method does two things, given @username (NOT [@username](URL)!)
* we try to create a fancy hcard from our contact info. If this is not possible
* due to lack of contact info, we assume @username is a twitter handle and link it
* as such.
*
- * @param string The note’s text
+ * @param string $text
* @return string
*/
- private function makeHCards($text)
+ private function makeHCards(string $text): string
{
$this->getContacts();
@@ -424,6 +462,9 @@ class Note extends Model
return $hcards;
}
+ /**
+ * Get the value of the `contacts` property.
+ */
public function getContacts()
{
if ($this->contacts === null) {
@@ -431,6 +472,9 @@ class Note extends Model
}
}
+ /**
+ * Process the note and save the contacts to the `contacts` property.
+ */
public function setContacts()
{
$contacts = [];
@@ -446,14 +490,16 @@ class Note extends Model
}
/**
+ * Turn text hashtags to full HTML links.
+ *
* Given a string and section, finds all hashtags matching
* `#[\-_a-zA-Z0-9]+` and wraps them in an `a` element with
* `rel=tag` set and a `href` of 'section/tagged/' + tagname without the #.
*
- * @param string The note
+ * @param string $note
* @return string
*/
- public function autoLinkHashtag($text)
+ public function autoLinkHashtag(string $note): string
{
return preg_replace_callback(
'/#([^\s]*)\b/',
@@ -462,25 +508,31 @@ class Note extends Model
. Tag::normalize($matches[1]) . '">#'
. $matches[1] . '';
},
- $text
+ $note
);
}
- private function convertMarkdown($text)
+ /**
+ * Pass a note through the commonmark library.
+ *
+ * @param string $note
+ * @return string
+ */
+ private function convertMarkdown(string $note): string
{
$environment = Environment::createCommonMarkEnvironment();
$environment->addExtension(new LinkifyExtension());
$converter = new Converter(new DocParser($environment), new HtmlRenderer($environment));
- return $converter->convertToHtml($text);
+ return $converter->convertToHtml($note);
}
/**
* Do a reverse geocode lookup of a `lat,lng` value.
*
- * @param float The latitude
- * @param float The longitude
- * @return string The location HTML
+ * @param float $latitude
+ * @param float $longitude
+ * @return string
*/
public function reverseGeoCode(float $latitude, float $longitude): string
{
@@ -498,7 +550,7 @@ class Note extends Model
],
'headers' => ['User-Agent' => 'jonnybarnes.uk via Guzzle, email jonny@jonnybarnes.uk'],
]);
- $json = json_decode($response->getBody());
+ $json = json_decode((string) $response->getBody());
if (isset($json->address->town)) {
$address = ''
. $json->address->town
diff --git a/app/Models/Place.php b/app/Models/Place.php
index 1f09faea..05a75f2e 100644
--- a/app/Models/Place.php
+++ b/app/Models/Place.php
@@ -1,5 +1,7 @@
[
@@ -49,7 +51,7 @@ class Place extends Model
/**
* Define the relationship with Notes.
*
- * @var array
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function notes()
{
@@ -59,12 +61,12 @@ class Place extends Model
/**
* Select places near a given location.
*
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param Point $point
- * @param int Distance
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Phaza\LaravelPostgis\Geometries\Point $point
+ * @param int $distance
* @return \Illuminate\Database\Eloquent\Builder
*/
- public function scopeNear(Builder $query, Point $point, $distance = 1000)
+ public function scopeNear(Builder $query, Point $point, $distance = 1000): Builder
{
$field = DB::raw(
sprintf(
@@ -77,7 +79,14 @@ class Place extends Model
return $query->where($field, '<=', $distance)->orderBy($field);
}
- public function scopeWhereExternalURL(Builder $query, string $url)
+ /**
+ * Select places based on a URL.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param string $url
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeWhereExternalURL(Builder $query, string $url): Builder
{
return $query->where('external_urls', '@>', json_encode([
$this->getType($url) => $url,
@@ -87,21 +96,21 @@ class Place extends Model
/**
* Get the latitude from the `location` property.
*
- * @return string latitude
+ * @return float
*/
- public function getLatitudeAttribute()
+ public function getLatitudeAttribute(): float
{
- return explode(' ', $this->location)[1];
+ return $this->location->getLat();
}
/**
* Get the longitude from the `location` property.
*
- * @return string longitude
+ * @return float
*/
- public function getLongitudeAttribute()
+ public function getLongitudeAttribute(): float
{
- return explode(' ', $this->location)[0];
+ return $this->location->getLng();
}
/**
@@ -109,7 +118,7 @@ class Place extends Model
*
* @return string
*/
- public function getLongurlAttribute()
+ public function getLongurlAttribute(): string
{
return config('app.url') . '/places/' . $this->slug;
}
@@ -119,7 +128,7 @@ class Place extends Model
*
* @return string
*/
- public function getShorturlAttribute()
+ public function getShorturlAttribute(): string
{
return config('app.shorturl') . '/places/' . $this->slug;
}
@@ -129,12 +138,17 @@ class Place extends Model
*
* @return string
*/
- public function getUriAttribute()
+ public function getUriAttribute(): string
{
return $this->longurl;
}
- public function setExternalUrlsAttribute($url)
+ /**
+ * Dealing with a jsonb column, so we check input first.
+ *
+ * @param string|null $url
+ */
+ public function setExternalUrlsAttribute(?string $url)
{
if ($url === null) {
return;
@@ -148,7 +162,13 @@ class Place extends Model
$this->attributes['external_urls'] = json_encode($already);
}
- private function getType(string $url): ?string
+ /**
+ * Given a URL, see if it is one of our known types.
+ *
+ * @param string $url
+ * @return string
+ */
+ private function getType(string $url): string
{
$host = parse_url($url, PHP_URL_HOST);
if (ends_with($host, 'foursquare.com') === true) {
diff --git a/app/Models/Tag.php b/app/Models/Tag.php
index 89e08ee5..5007ad5c 100644
--- a/app/Models/Tag.php
+++ b/app/Models/Tag.php
@@ -1,5 +1,7 @@
attributes['tag'] = $this->normalize($value);
}
@@ -45,9 +49,10 @@ class Tag extends Model
* This method actually normalizes a tag. That means lowercase-ing and
* removing fancy diatric characters.
*
- * @param string
+ * @param string $tag
+ * @return string
*/
- public static function normalize($tag)
+ public static function normalize(string $tag): string
{
return mb_strtolower(
preg_replace(
diff --git a/app/Models/User.php b/app/Models/User.php
index 6bd0f157..7fc687c7 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -1,5 +1,7 @@
findAuthor(json_decode($this->mf2, true));
@@ -57,11 +59,12 @@ class WebMention extends Model
/**
* Get the published value for the webmention.
*
- * @return string
+ * @return string|null
*/
- public function getPublishedAttribute()
+ public function getPublishedAttribute(): ?string
{
- $microformats = json_decode($this->mf2, true);
+ $mf2 = $this->mf2 ?? '';
+ $microformats = json_decode($mf2, true);
if (isset($microformats['items'][0]['properties']['published'][0])) {
try {
$published = carbon()->parse(
@@ -82,12 +85,17 @@ class WebMention extends Model
*
* @return string|null
*/
- public function getReplyAttribute()
+ public function getReplyAttribute(): ?string
{
+ if ($this->mf2 === null) {
+ return null;
+ }
$microformats = json_decode($this->mf2, true);
if (isset($microformats['items'][0]['properties']['content'][0]['html'])) {
return $this->filterHTML($microformats['items'][0]['properties']['content'][0]['html']);
}
+
+ return null;
}
/**
@@ -126,10 +134,10 @@ class WebMention extends Model
/**
* Filter the HTML in a reply webmention.
*
- * @param string The reply HTML
- * @return string The filtered HTML
+ * @param string $html
+ * @return string
*/
- private function filterHTML($html)
+ private function filterHTML(string $html): string
{
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.SerializerPath', storage_path() . '/HTMLPurifier');
diff --git a/app/Observers/NoteObserver.php b/app/Observers/NoteObserver.php
index bf618edb..d74d9e47 100644
--- a/app/Observers/NoteObserver.php
+++ b/app/Observers/NoteObserver.php
@@ -1,8 +1,11 @@
getTagsFromNote($note->getAttributes()['note'] ?? null);
+ $text = array_get($note->getAttributes(), 'note');
+ if ($text === null) {
+ return;
+ }
+ $tags = $this->getTagsFromNote($text);
if (count($tags) === 0) {
return;
@@ -31,11 +37,15 @@ class NoteObserver
* Listen to the Note updated event.
*
* @param \App\Note $Note
- * @return void
*/
public function updated(Note $note)
{
- $tags = $this->getTagsFromNote($note->getAttributes()['note']);
+ $text = array_get($note->getAttributes(), 'note');
+ if ($text === null) {
+ return;
+ }
+
+ $tags = $this->getTagsFromNote($text);
if (count($tags) === 0) {
return;
}
@@ -53,14 +63,19 @@ class NoteObserver
* Listen to the Note deleting event.
*
* @param \App\Note $note
- * @return void
*/
public function deleting(Note $note)
{
$note->tags()->detach();
}
- public function getTagsFromNote($note)
+ /**
+ * Retrieve the tags from a note’s text, tag for form #tag.
+ *
+ * @param string $note
+ * @return \Illuminate\Support\Collection
+ */
+ private function getTagsFromNote(string $note): Collection
{
preg_match_all('/#([^\s<>]+)\b/', $note, $tags);
diff --git a/app/Services/ActivityStreamsService.php b/app/Services/ActivityStreamsService.php
index 04923d62..d7d9f660 100644
--- a/app/Services/ActivityStreamsService.php
+++ b/app/Services/ActivityStreamsService.php
@@ -1,11 +1,18 @@
header('Content-Type', 'application/activity+json');
}
+ /**
+ * Return the relevant data to an AS2.0 request for a particular note.
+ *
+ * @param \App\Models\Note $note
+ * @return \Illuminate\Http\Response
+ */
public function singleNoteResponse(Note $note)
{
$data = json_encode([
diff --git a/app/Services/BookmarkService.php b/app/Services/BookmarkService.php
index b1dcaf50..f05d6a1e 100644
--- a/app/Services/BookmarkService.php
+++ b/app/Services/BookmarkService.php
@@ -20,7 +20,7 @@ class BookmarkService
/**
* Create a new Bookmark.
*
- * @param array $request
+ * @param array $request Data from request()->all()
* @return Bookmark $bookmark
*/
public function createBookmark(array $request): Bookmark
@@ -84,6 +84,12 @@ class BookmarkService
return $bookmark;
}
+ /**
+ * Given a URL, use browsershot to save an image of the page.
+ *
+ * @param string $url
+ * @return string The uuid for the screenshot
+ */
public function saveScreenshot(string $url): string
{
$browsershot = new Browsershot();
@@ -99,6 +105,12 @@ class BookmarkService
return $uuid->toString();
}
+ /**
+ * Given a URL, attempt to save it to the Internet Archive.
+ *
+ * @param string $url
+ * @return string
+ */
public function getArchiveLink(string $url): string
{
$client = resolve(Client::class);
diff --git a/app/Services/Micropub/HCardService.php b/app/Services/Micropub/HCardService.php
index 62907379..f3d1ff3c 100644
--- a/app/Services/Micropub/HCardService.php
+++ b/app/Services/Micropub/HCardService.php
@@ -1,12 +1,20 @@
all()
+ * @return string
+ */
+ public function process(array $request): string
{
$data = [];
if (array_get($request, 'properties.name')) {
diff --git a/app/Services/Micropub/HEntryService.php b/app/Services/Micropub/HEntryService.php
index fe44c04a..edb054ab 100644
--- a/app/Services/Micropub/HEntryService.php
+++ b/app/Services/Micropub/HEntryService.php
@@ -1,12 +1,21 @@
all()
+ * @param string|null $client The micropub client that made the request
+ * @return string|null
+ */
+ public function process(array $request, ?string $client = null): ?string
{
if (array_get($request, 'properties.like-of') || array_get($request, 'like-of')) {
$like = resolve(LikeService::class)->createLike($request);
diff --git a/app/Services/Micropub/UpdateService.php b/app/Services/Micropub/UpdateService.php
index 45756584..b4f81085 100644
--- a/app/Services/Micropub/UpdateService.php
+++ b/app/Services/Micropub/UpdateService.php
@@ -1,5 +1,7 @@
all()
+ * @return \Illuminate\Http\JsonResponse
+ */
public function process(array $request)
{
$urlPath = parse_url(array_get($request, 'url'), PHP_URL_PATH);
diff --git a/app/Services/NoteService.php b/app/Services/NoteService.php
index 2680ec29..b29f5d3c 100644
--- a/app/Services/NoteService.php
+++ b/app/Services/NoteService.php
@@ -12,11 +12,11 @@ class NoteService
/**
* Create a new note.
*
- * @param array $request
- * @param string $client
- * @return \App\Note $note
+ * @param array $request Data from request()->all()
+ * @param string $client
+ * @return \App\Note
*/
- public function createNote(array $request, string $client = null): Note
+ public function createNote(array $request, ?string $client = null): Note
{
$note = Note::create(
[
@@ -60,6 +60,12 @@ 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 (array_get($request, 'properties.content.0.html')) {
@@ -72,6 +78,12 @@ class NoteService
return array_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 (array_get($request, 'properties.in-reply-to.0')) {
@@ -81,6 +93,12 @@ class NoteService
return array_get($request, 'in-reply-to');
}
+ /**
+ * Get the published time from the request to create a new note.
+ *
+ * @param array $request Data from request()->all()
+ * @return string|null
+ */
private function getPublished(array $request): ?string
{
if (array_get($request, 'properties.published.0')) {
@@ -94,6 +112,12 @@ class NoteService
return null;
}
+ /**
+ * Get the location data from the request to create a new note.
+ *
+ * @param array $request Data from request()->all()
+ * @return string|null
+ */
private function getLocation(array $request): ?string
{
$location = array_get($request, 'properties.location.0') ?? array_get($request, 'location');
@@ -110,6 +134,12 @@ class NoteService
return null;
}
+ /**
+ * Get the checkin data from the request to create a new note. This will be a Place.
+ *
+ * @param array $request Data from request()->all()
+ * @return \App\Models\Place|null
+ */
private function getCheckin(array $request): ?Place
{
if (array_get($request, 'properties.location.0.type.0') === 'h-card') {
@@ -149,6 +179,12 @@ class NoteService
return null;
}
+ /**
+ * Get the Swarm URL from the syndication data in the request to create a new note.
+ *
+ * @param array $request Data from request()->all()
+ * @return string|null
+ */
private function getSwarmUrl(array $request): ?string
{
if (stristr(array_get($request, 'properties.syndication.0', ''), 'swarmapp')) {
@@ -158,6 +194,12 @@ class NoteService
return null;
}
+ /**
+ * Get the syndication targets from the request to create a new note.
+ *
+ * @param array $request Data from request()->all()
+ * @return array
+ */
private function getSyndicationTargets(array $request): array
{
$syndication = [];
@@ -187,6 +229,12 @@ class NoteService
return $syndication;
}
+ /**
+ * Get the media URLs from the request to create a new note.
+ *
+ * @param array $request Data from request()->all()
+ * @return array
+ */
private function getMedia(array $request): array
{
$media = [];
@@ -211,6 +259,12 @@ class NoteService
return $media;
}
+ /**
+ * Get the Instagram photo URL from the request to create a new note.
+ *
+ * @param array $request Data from request()->all()
+ * @return string|null
+ */
private function getInstagramUrl(array $request): ?string
{
if (starts_with(array_get($request, 'properties.syndication.0'), 'https://www.instagram.com')) {
diff --git a/changelog.md b/changelog.md
index 755e3eb0..87be660a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,8 @@
# Changelog
+## Version {next}
+ - Improve code-base by liberal use of `strict_types`
+
## Version 0.15.3 (2018-01-12)
- Improve `likes`, including adding a new section in the admin cp
- Add the ability to POSSE the like of a Tweet
diff --git a/tests/Feature/MicropubControllerTest.php b/tests/Feature/MicropubControllerTest.php
index 81a86591..20db8222 100644
--- a/tests/Feature/MicropubControllerTest.php
+++ b/tests/Feature/MicropubControllerTest.php
@@ -887,7 +887,7 @@ class MicropubControllerTest extends TestCase
'h' => 'entry',
'content' => $note,
'published' => Carbon::now()->toW3CString(),
- 'access_token' => $this->getToken(),
+ 'access_token' => (string) $this->getToken(),
]
);
$response->assertJson(['response' => 'created']);
diff --git a/tests/Feature/SwarmTest.php b/tests/Feature/SwarmTest.php
index ff86eaaa..7e8f133b 100644
--- a/tests/Feature/SwarmTest.php
+++ b/tests/Feature/SwarmTest.php
@@ -146,7 +146,6 @@ class SwarmTest extends TestCase
$response
->assertStatus(201)
->assertJson(['response' => 'created']);
- //dump($response->__get('headers')->get('location'));
$this->assertDatabaseHas('places', [
'external_urls' => '{"foursquare": "https://foursquare.com/v/654321"}'
]);
diff --git a/tests/Feature/TokenServiceTest.php b/tests/Feature/TokenServiceTest.php
index c9c33078..58b4cc3d 100644
--- a/tests/Feature/TokenServiceTest.php
+++ b/tests/Feature/TokenServiceTest.php
@@ -55,6 +55,5 @@ class TokenServiceTest extends TestCase
$service = new TokenService();
$token = $service->validateToken($token);
- dump($token);
}
}