From 0c62e558ec55064dea78ecc17a58e60184595830 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Thu, 22 Jun 2017 14:30:10 +0100 Subject: [PATCH] Massivly simplify notes index controller method --- app/Http/Controllers/NotesController.php | 171 +------------------- app/MicropubClient.php | 9 ++ app/Note.php | 190 +++++++++++++++++++++-- app/Place.php | 13 -- resources/views/templates/note.blade.php | 14 +- 5 files changed, 200 insertions(+), 197 deletions(-) diff --git a/app/Http/Controllers/NotesController.php b/app/Http/Controllers/NotesController.php index c91672ee..ae7251b6 100644 --- a/app/Http/Controllers/NotesController.php +++ b/app/Http/Controllers/NotesController.php @@ -25,37 +25,11 @@ class NotesController extends Controller */ public function index(Request $request) { - $notes = Note::orderBy('id', 'desc')->with('webmentions', 'place', 'media')->paginate(10); - foreach ($notes as $note) { - $replies = 0; - foreach ($note->webmentions as $webmention) { - if ($webmention->type == 'in-reply-to') { - $replies++; - } - } - $note->replies = $replies; - $note->twitter = $this->checkTwitterReply($note->in_reply_to); - $note->iso8601_time = $note->updated_at->toISO8601String(); - $note->human_time = $note->updated_at->diffForHumans(); - if ($note->location && ($note->place === null)) { - $pieces = explode(':', $note->location); - $latlng = explode(',', $pieces[0]); - $note->latitude = trim($latlng[0]); - $note->longitude = trim($latlng[1]); - $note->address = $this->reverseGeoCode((float) trim($latlng[0]), (float) trim($latlng[1])); - } - if ($note->place !== null) { - $lnglat = explode(' ', $note->place->location); - $note->latitude = $lnglat[1]; - $note->longitude = $lnglat[0]; - $note->address = $note->place->name; - $note->placeLink = '/places/' . $note->place->slug; - } - /*$mediaLinks = []; - foreach ($note->media()->get() as $media) { - $mediaLinks[] = $media->url; - }*/ - } + $notes = Note::orderBy('id', 'desc') + ->with('place', 'media', 'client') + ->withCount(['webmentions As replies' => function ($query) { + $query->where('type', 'in-reply-to'); + }])->paginate(10); $homepage = ($request->path() == '/'); @@ -70,10 +44,8 @@ class NotesController extends Controller */ public function show($urlId) { - $numbers = new Numbers(); $authorship = new Authorship(); - $realId = $numbers->b60tonum($urlId); - $note = Note::find($realId); + $note = Note::nb60($urlId)->first(); $replies = []; $reposts = []; $likes = []; @@ -135,23 +107,6 @@ class NotesController extends Controller break; } } - $note->twitter = $this->checkTwitterReply($note->in_reply_to); - $note->iso8601_time = $note->updated_at->toISO8601String(); - $note->human_time = $note->updated_at->diffForHumans(); - if ($note->location && ($note->place === null)) { - $pieces = explode(':', $note->location); - $latlng = explode(',', $pieces[0]); - $note->latitude = trim($latlng[0]); - $note->longitude = trim($latlng[1]); - $note->address = $this->reverseGeoCode((float) trim($latlng[0]), (float) trim($latlng[1])); - } - if ($note->place !== null) { - $lnglat = explode(' ', $note->place->location); - $note->latitude = $lnglat[1]; - $note->longitude = $lnglat[0]; - $note->address = $note->place->name; - $note->placeLink = '/places/' . $note->place->slug; - } return view('notes.show', compact('note', 'replies', 'reposts', 'likes')); } @@ -230,42 +185,6 @@ class NotesController extends Controller return $url; } - /** - * Twitter!!! - * - * @param string The reply to URL - * @return string | null - */ - private function checkTwitterReply($url) - { - if ($url == null) { - return; - } - - if (mb_substr($url, 0, 20, 'UTF-8') !== 'https://twitter.com/') { - return; - } - - $arr = explode('/', $url); - $tweetId = end($arr); - if (Cache::has($tweetId)) { - return Cache::get($tweetId); - } - try { - $oEmbed = Twitter::getOembed([ - 'id' => $tweetId, - 'align' => 'center', - 'omit_script' => true, - 'maxwidth' => 550, - ]); - } catch (\Exception $e) { - return; - } - Cache::put($tweetId, $oEmbed, ($oEmbed->cache_age / 60)); - - return $oEmbed; - } - /** * Filter the HTML in a reply webmention. * @@ -281,82 +200,4 @@ class NotesController extends Controller return $purifier->purify($html); } - - /** - * Do a reverse geocode lookup of a `lat,lng` value. - * - * @param float The latitude - * @param float The longitude - * @return string The location HTML - */ - public function reverseGeoCode(float $latitude, float $longitude): string - { - $latlng = $latitude . ',' . $longitude; - - return Cache::get($latlng, function () use ($latlng, $latitude, $longitude) { - $guzzle = new Client(); - $response = $guzzle->request('GET', 'https://nominatim.openstreetmap.org/reverse', [ - 'query' => [ - 'format' => 'json', - 'lat' => $latitude, - 'lon' => $longitude, - 'zoom' => 18, - 'addressdetails' => 1, - ], - 'headers' => ['User-Agent' => 'jonnybarnes.uk via Guzzle, email jonny@jonnybarnes.uk'], - ]); - $json = json_decode($response->getBody()); - if (isset($json->address->town)) { - $address = '' - . $json->address->town - . ', ' - . $json->address->country - . ''; - Cache::forever($latlng, $address); - - return $address; - } - if (isset($json->address->city)) { - $address = $json->address->city . ', ' . $json->address->country; - Cache::forever($latlng, $address); - - return $address; - } - if (isset($json->address->county)) { - $address = '' - . $json->address->county - . ', ' - . $json->address->country - . ''; - Cache::forever($latlng, $address); - - return $address; - } - $adress = '' . $json->address->country . ''; - Cache::forever($latlng, $address); - - return $address; - }); - } - - private function getGeoJson($longitude, $latitude, $title, $icon) - { - $icon = $icon ?? 'marker'; - - return -"{ - 'type': 'FeatureCollection', - 'features': [{ - 'type': 'Feature', - 'geometry': { - 'type': 'Point', - 'coordinates': [$longitude, $latitude] - }, - 'properties': { - 'title': '$title', - 'icon': '$icon' - } - }] -}"; - } } diff --git a/app/MicropubClient.php b/app/MicropubClient.php index 23e4917e..7388cf6d 100644 --- a/app/MicropubClient.php +++ b/app/MicropubClient.php @@ -19,4 +19,13 @@ class MicropubClient extends Model * @var array */ protected $fillable = ['client_url', 'client_name']; + + /** + * Define the relationship with notes. + * + * @return void + */ + public function notes() { + return $this->hasMany('App\Note', 'client_id', 'client_url'); + } } diff --git a/app/Note.php b/app/Note.php index ceaa15c1..32a15cad 100644 --- a/app/Note.php +++ b/app/Note.php @@ -2,7 +2,10 @@ namespace App; +use Cache; +use Twitter; use Normalizer; +use GuzzleHttp\Client; use Laravel\Scout\Searchable; use Jonnybarnes\IndieWeb\Numbers; use Illuminate\Database\Eloquent\Model; @@ -33,6 +36,15 @@ class Note extends Model return $this->belongsToMany('App\Tag'); } + /** + * Define the relationship with clients. + * + * @var array? + */ + public function client() { + return $this->belongsTo('App\MicropubClient', 'client_id', 'client_url'); + } + /** * Define the relationship with webmentions. * @@ -96,17 +108,6 @@ class Note extends Model ]; } - /** - * A mutator to ensure that in-reply-to is always non-empty or null. - * - * @param string value - * @return string - */ - public function setInReplyToAttribute($value) - { - $this->attributes['in_reply_to'] = empty($value) ? null : $value; - } - /** * Normalize the note to Unicode FORM C. * @@ -168,6 +169,26 @@ class Note extends Model return config('app.shorturl') . '/notes/' . $this->nb60id; } + /** + * Get the ISO8601 value for mf2. + * + * @return string + */ + public function getIso8601Attribute() + { + return $this->updated_at->toISO8601String(); + } + + /** + * Get the ISO8601 value for mf2. + * + * @return string + */ + public function getHumandiffAttribute() + { + return $this->updated_at->diffForHumans(); + } + /** * Get the pubdate value for RSS feeds. * @@ -179,10 +200,72 @@ class Note extends Model } /** - * Get the relavent client name assocaited with the client id. + * Get the latitude value. * * @return string|null */ + public function getLatitudeAttribute() + { + if ($this->place !== null) { + $lnglat = explode(' ', $this->place->location); + + return $lnglat[1]; + } + if ($this->location !== null) { + $pieces = explode(':', $this->location); + $latlng = explode(',', $pieces[0]); + + return trim($latlng[0]); + } + + return; + } + + /** + * Get the longitude value. + * + * @return string|null + */ + public function getLongitudeAttribute() + { + if ($this->place !== null) { + $lnglat = explode(' ', $this->place->location); + + return $lnglat[1]; + } + if ($this->location !== null) { + $pieces = explode(':', $this->location); + $latlng = explode(',', $pieces[0]); + + return trim($latlng[1]); + } + + return; + } + + /** + * Get the address for a note. This is either a reverse geo-code from the + * location, or is derived from the associated place. + * + * @return string|null + */ + public function getAddressAttribute() + { + if ($this->place !== null) { + return $this->place->name; + } + if ($this->location !== null) { + return $this->reverseGeoCode((float) $this->latitude, (float) $this->longitude); + } + + return; + } + + /* + * Get the relavent client name assocaited with the client id. + * + * @return string|null + * public function getClientNameAttribute() { if ($this->client_id == null) { @@ -199,6 +282,32 @@ class Note extends Model } return $name; + }*/ + + public function getTwitterAttribute() + { + if ($this->in_reply_to == null || mb_substr($this->in_reply_to, 0, 20, 'UTF-8') !== 'https://twitter.com/') { + return; + } + + $arr = explode('/', $url); + $tweetId = end($arr); + if (Cache::has($tweetId)) { + return Cache::get($tweetId); + } + try { + $oEmbed = Twitter::getOembed([ + 'id' => $tweetId, + 'align' => 'center', + 'omit_script' => true, + 'maxwidth' => 550, + ]); + } catch (\Exception $e) { + return; + } + Cache::put($tweetId, $oEmbed, ($oEmbed->cache_age / 60)); + + return $oEmbed; } /** @@ -284,4 +393,61 @@ class Note extends Model return $text; } + + /** + * Do a reverse geocode lookup of a `lat,lng` value. + * + * @param float The latitude + * @param float The longitude + * @return string The location HTML + */ + public function reverseGeoCode(float $latitude, float $longitude): string + { + $latlng = $latitude . ',' . $longitude; + + return Cache::get($latlng, function () use ($latlng, $latitude, $longitude) { + $guzzle = new Client(); + $response = $guzzle->request('GET', 'https://nominatim.openstreetmap.org/reverse', [ + 'query' => [ + 'format' => 'json', + 'lat' => $latitude, + 'lon' => $longitude, + 'zoom' => 18, + 'addressdetails' => 1, + ], + 'headers' => ['User-Agent' => 'jonnybarnes.uk via Guzzle, email jonny@jonnybarnes.uk'], + ]); + $json = json_decode($response->getBody()); + if (isset($json->address->town)) { + $address = '' + . $json->address->town + . ', ' + . $json->address->country + . ''; + Cache::forever($latlng, $address); + + return $address; + } + if (isset($json->address->city)) { + $address = $json->address->city . ', ' . $json->address->country; + Cache::forever($latlng, $address); + + return $address; + } + if (isset($json->address->county)) { + $address = '' + . $json->address->county + . ', ' + . $json->address->country + . ''; + Cache::forever($latlng, $address); + + return $address; + } + $adress = '' . $json->address->country . ''; + Cache::forever($latlng, $address); + + return $address; + }); + } } diff --git a/app/Place.php b/app/Place.php index e3bc6acc..0e1e0c9b 100644 --- a/app/Place.php +++ b/app/Place.php @@ -76,19 +76,6 @@ class Place extends Model return $query->where($field, '<=', $distance)->orderBy($field); } - /* - * Convert location to text. - * - * @param text $value - * @return text - * - public function getLocationAttribute($value) - { - $result = DB::select(DB::raw("SELECT ST_AsText('$value')")); - - return $result[0]->st_astext; - }*/ - /** * Get the latitude from the `location` property. * diff --git a/resources/views/templates/note.blade.php b/resources/views/templates/note.blade.php index 958d6103..dc6a3350 100644 --- a/resources/views/templates/note.blade.php +++ b/resources/views/templates/note.blade.php @@ -8,7 +8,7 @@
{!! $note->note !!} - @foreach($note->media()->get() as $media) + @foreach($note->media as $media) @if($media->type == 'image')@endif @if($media->type == 'audio')
-@if ($note->placeLink) +@if ($note->place)
@endif