From 8477aba87bce6e78f9b476e0e69d02b7f2684ea4 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Thu, 22 Jun 2017 15:41:23 +0100 Subject: [PATCH] Massive simplification of code for displaying webmentions of notes, and the micropub client used to make a note --- app/Http/Controllers/NotesController.php | 114 ++--------------------- app/Jobs/AddClientToDatabase.php | 42 +++++++++ app/Services/TokenService.php | 2 + app/WebMention.php | 114 +++++++++++++++++++++++ resources/views/notes/show.blade.php | 14 +-- resources/views/notes/tagged.blade.php | 4 +- 6 files changed, 173 insertions(+), 117 deletions(-) create mode 100644 app/Jobs/AddClientToDatabase.php diff --git a/app/Http/Controllers/NotesController.php b/app/Http/Controllers/NotesController.php index ae7251b6..da95f3c2 100644 --- a/app/Http/Controllers/NotesController.php +++ b/app/Http/Controllers/NotesController.php @@ -2,16 +2,9 @@ namespace App\Http\Controllers; -use Twitter; -use HTMLPurifier; -use App\{Note, Tag}; -use GuzzleHttp\Client; -use HTMLPurifier_Config; +use App\Note; use Illuminate\Http\Request; use Jonnybarnes\IndieWeb\Numbers; -use Illuminate\Filesystem\Filesystem; -use Illuminate\Support\Facades\Cache; -use Jonnybarnes\WebmentionsParser\Authorship; // Need to sort out Twitter and webmentions! @@ -44,50 +37,18 @@ class NotesController extends Controller */ public function show($urlId) { - $authorship = new Authorship(); $note = Note::nb60($urlId)->first(); $replies = []; $reposts = []; $likes = []; - $carbon = new \Carbon\Carbon(); foreach ($note->webmentions as $webmention) { - /* - reply->url | - reply->photo | Author - reply->name | - reply->source - reply->date - reply->reply - - repost->url | - repost->photo | Author - repost->name | - repost->date - repost->source - - like->url | - like->photo | Author - like->name | - */ - $microformats = json_decode($webmention->mf2, true); - $authorHCard = $authorship->findAuthor($microformats); - $content['url'] = $authorHCard['properties']['url'][0]; - $content['photo'] = $this->createPhotoLink($authorHCard['properties']['photo'][0]); - $content['name'] = $authorHCard['properties']['name'][0]; + $content['author'] = $webmention->author; + $content['published'] = $webmention->published; + $content['source'] = $webmention->source; switch ($webmention->type) { case 'in-reply-to': - $content['source'] = $webmention->source; - if (isset($microformats['items'][0]['properties']['published'][0])) { - try { - $content['date'] = $carbon->parse( - $microformats['items'][0]['properties']['published'][0] - )->toDayDateTimeString(); - } catch (\Exception $exception) { - $content['date'] = $webmention->updated_at->toDayDateTimeString(); - } - } else { - $content['date'] = $webmention->updated_at->toDayDateTimeString(); - } + $content['reply'] = $webmention->reply; + $microformats = json_decode($webmention->mf2, true); $content['reply'] = $this->filterHTML( $microformats['items'][0]['properties']['content'][0]['html'] ); @@ -95,10 +56,6 @@ class NotesController extends Controller break; case 'repost-of': - $content['date'] = $carbon->parse( - $microformats['items'][0]['properties']['published'][0] - )->toDayDateTimeString(); - $content['source'] = $webmention->source; $reposts[] = $content; break; @@ -138,66 +95,7 @@ class NotesController extends Controller $notes = Note::whereHas('tags', function ($query) use ($tag) { $query->where('tag', $tag); })->get(); - foreach ($notes as $note) { - $note->iso8601_time = $note->updated_at->toISO8601String(); - $note->human_time = $note->updated_at->diffForHumans(); - } return view('notes.tagged', compact('notes', 'tag')); } - - /** - * Create the photo link. - * - * We shall leave twitter.com and twimg.com links as they are. Then we shall - * check for local copies, if that fails leave the link as is. - * - * @param string - * @return string - */ - public function createPhotoLink($url) - { - $host = parse_url($url, PHP_URL_HOST); - if ($host == 'pbs.twimg.com') { - //make sure we use HTTPS, we know twitter supports it - return str_replace('http://', 'https://', $url); - } - if ($host == 'twitter.com') { - if (Cache::has($url)) { - return Cache::get($url); - } - $username = parse_url($url, PHP_URL_PATH); - try { - $info = Twitter::getUsers(['screen_name' => $username]); - $profile_image = $info->profile_image_url_https; - Cache::put($url, $profile_image, 10080); //1 week - } catch (Exception $e) { - return $url; //not sure here - } - - return $profile_image; - } - $filesystem = new Filesystem(); - if ($filesystem->exists(public_path() . '/assets/profile-images/' . $host . '/image')) { - return '/assets/profile-images/' . $host . '/image'; - } - - return $url; - } - - /** - * Filter the HTML in a reply webmention. - * - * @param string The reply HTML - * @return string The filtered HTML - */ - private function filterHTML($html) - { - $config = HTMLPurifier_Config::createDefault(); - $config->set('Cache.SerializerPath', storage_path() . '/HTMLPurifier'); - $config->set('HTML.TargetBlank', true); - $purifier = new HTMLPurifier($config); - - return $purifier->purify($html); - } } diff --git a/app/Jobs/AddClientToDatabase.php b/app/Jobs/AddClientToDatabase.php new file mode 100644 index 00000000..970f4c07 --- /dev/null +++ b/app/Jobs/AddClientToDatabase.php @@ -0,0 +1,42 @@ +client_id = $client_id; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + if (MicropubClient::where('client_url', $this->client_id)->count() == 0) { + $client = MicropubClient::create([ + 'client_url' => $this->client_id, + 'client_name' => $this->client_id, // default client name is the URL + ]); + } + } +} diff --git a/app/Services/TokenService.php b/app/Services/TokenService.php index 42f2f718..a91c9dc9 100644 --- a/app/Services/TokenService.php +++ b/app/Services/TokenService.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Services; +use App\Jobs\AddClientToDatabase; use Lcobucci\JWT\Signer\Hmac\Sha256; use App\Exceptions\InvalidTokenException; use Lcobucci\JWT\{Builder, Parser, Token}; @@ -26,6 +27,7 @@ class TokenService ->set('nonce', bin2hex(random_bytes(8))) ->sign($signer, config('app.key')) ->getToken(); + dispatch(new AddClientToDatabase($data['client_id'])); return (string) $token; } diff --git a/app/WebMention.php b/app/WebMention.php index 759cc1ea..ca2fa12d 100644 --- a/app/WebMention.php +++ b/app/WebMention.php @@ -2,7 +2,13 @@ namespace App; +use Twitter; +use HTMLPurifier; +use Carbon\Carbon; +use HTMLPurifier_Config; +use Illuminate\Filesystem\Filesystem; use Illuminate\Database\Eloquent\Model; +use Jonnybarnes\WebmentionsParser\Authorship; class WebMention extends Model { @@ -29,4 +35,112 @@ class WebMention extends Model * @var array */ protected $guarded = ['id']; + + /** + * Get the author of the webmention. + * + * @return array + */ + public function getAuthorAttribute() + { + $authorship = new Authorship(); + $hCard = $authorship->findAuthor(json_decode($this->mf2, true)); + if (array_key_exists('properties', $hCard) && + array_key_exists('photo', $hCard['properties']) + ) { + $hCard['properties']['photo'][0] = $this->createPhotoLink($hCard['properties']['photo'][0]); + } + + return $hCard; + } + + /** + * Get the published value for the webmention. + * + * @return string + */ + public function getPublishedAttribute() + { + $microformats = json_decode($this->mf2, true); + $carbon = new Carbon(); + if (isset($microformats['items'][0]['properties']['published'][0])) { + try { + $published = $carbon->parse( + $microformats['items'][0]['properties']['published'][0] + )->toDayDateTimeString(); + } catch (\Exception $exception) { + $published = $webmention->updated_at->toDayDateTimeString(); + } + } else { + $published = $webmention->updated_at->toDayDateTimeString(); + } + + return $published; + } + + /** + * Get the filteres HTML of a reply. + * + * @return strin|null + */ + public function getReplyAttribute() + { + $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']); + } + } + + /** + * Create the photo link. + * + * @param string + * @return string + */ + public function createPhotoLink(string $url): string + { + $url = normalize_url($url); + $host = parse_url($url, PHP_URL_HOST); + if ($host == 'pbs.twimg.com') { + //make sure we use HTTPS, we know twitter supports it + return str_replace('http://', 'https://', $url); + } + if ($host == 'twitter.com') { + if (Cache::has($url)) { + return Cache::get($url); + } + $username = parse_url($url, PHP_URL_PATH); + try { + $info = Twitter::getUsers(['screen_name' => $username]); + $profile_image = $info->profile_image_url_https; + Cache::put($url, $profile_image, 10080); //1 week + } catch (Exception $e) { + return $url; //not sure here + } + + return $profile_image; + } + $filesystem = new Filesystem(); + if ($filesystem->exists(public_path() . '/assets/profile-images/' . $host . '/image')) { + return '/assets/profile-images/' . $host . '/image'; + } + + return $url; + } + + /** + * Filter the HTML in a reply webmention. + * + * @param string The reply HTML + * @return string The filtered HTML + */ + private function filterHTML($html) + { + $config = HTMLPurifier_Config::createDefault(); + $config->set('Cache.SerializerPath', storage_path() . '/HTMLPurifier'); + $config->set('HTML.TargetBlank', true); + $purifier = new HTMLPurifier($config); + + return $purifier->purify($html); + } } diff --git a/resources/views/notes/show.blade.php b/resources/views/notes/show.blade.php index 43f19105..ec6e9e41 100644 --- a/resources/views/notes/show.blade.php +++ b/resources/views/notes/show.blade.php @@ -9,9 +9,9 @@ @include('templates.note', ['note' => $note]) @foreach($replies as $reply)
- - {{ $reply['name'] }} - said at {{ $reply['date'] }} + + {{ $reply['author']['properties']['name'][0] }} + said at {{ $reply['published'] }}
{!! $reply['reply'] !!}
@@ -19,13 +19,13 @@ @endforeach @if(count($likes) > 0)

Likes

@endif @foreach($likes as $like) - + @endforeach @if(count($reposts) > 0)

Reposts

@endif @foreach($reposts as $repost) -

- {{ $repost['name'] }} - reposted this at {{ $repost['date'] }}.

+

+ {{ $repost['author']['properties']['name'][0] }} + reposted this at {{ $repost['published'] }}.

@endforeach diff --git a/resources/views/notes/tagged.blade.php b/resources/views/notes/tagged.blade.php index 2bd044d8..f7214657 100644 --- a/resources/views/notes/tagged.blade.php +++ b/resources/views/notes/tagged.blade.php @@ -1,13 +1,13 @@ @extends('master') @section('title') -Tagged Notes « +Tagged Notes « @stop @section('content')

Notes tagged with {{ $tag }}

@foreach ($notes as $note)
{!! $note->note !!} -{{ $note->human_time }}
+{{ $note->humandiff }}
@endforeach @stop