Massivly simplify notes index controller method

This commit is contained in:
Jonny Barnes 2017-06-22 14:30:10 +01:00
parent 36cf131839
commit 0c62e558ec
5 changed files with 200 additions and 197 deletions

View file

@ -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 = '<span class="p-locality">'
. $json->address->town
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
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 = '<span class="p-region">'
. $json->address->county
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
Cache::forever($latlng, $address);
return $address;
}
$adress = '<span class="p-country-name">' . $json->address->country . '</span>';
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'
}
}]
}";
}
}

View file

@ -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');
}
}

View file

@ -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 = '<span class="p-locality">'
. $json->address->town
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
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 = '<span class="p-region">'
. $json->address->county
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
Cache::forever($latlng, $address);
return $address;
}
$adress = '<span class="p-country-name">' . $json->address->country . '</span>';
Cache::forever($latlng, $address);
return $address;
});
}
}

View file

@ -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.
*

View file

@ -8,7 +8,7 @@
<div class="note">
<div class="e-content p-name">
{!! $note->note !!}
@foreach($note->media()->get() as $media)
@foreach($note->media as $media)
@if($media->type == 'image')<img class="u-photo" src="{{ $media->url }}" alt="">@endif
@if($media->type == 'audio')<audio class="u-audio" src="{{ $media->url }}" controls>@endif
@if($media->type == 'video')<video class="u-video" src="{{ $media->url }}" controls>@endif
@ -17,10 +17,10 @@
</div>
<div class="note-metadata">
<div>
<a class="u-url" href="/notes/{{ $note->nb60id }}"><time class="dt-published" datetime="{{ $note->iso8601_time }}">{{ $note->human_time }}</time></a>@if($note->client_name) via <a class="client" href="{{ $note->client_id }}">{{ $note->client_name }}</a>@endif
@if($note->placeLink)in <span class="p-location h-card"><a class="p-name u-url" href="{{ $note->placeLink }}">{{ $note->address }}</a><data class="p-latitude" value="{{ $note->latitude }}"></data><data class="p-longitude" value="{{ $note->longitude }}"></data></span>
<a class="u-url" href="/notes/{{ $note->nb60id }}"><time class="dt-published" datetime="{{ $note->iso8601 }}" title="{{ $note->iso8601 }}">{{ $note->humandiff }}</time></a>@if($note->client) via <a class="client" href="{{ $note->client->client_url }}">{{ $note->client->client_name }}</a>@endif
@if($note->place)in <span class="p-location h-card"><a class="p-name u-url" href="{{ $note->place->longurl }}">{{ $note->address }}</a><data class="p-latitude" value="{{ $note->place->latitude }}"></data><data class="p-longitude" value="{{ $note->place->longitude }}"></data></span>
@elseif($note->address)in <span class="p-location h-adr">{!! $note->address !!}<data class="p-latitude" value="{{ $note->latitude }}"></data><data class="p-longitude" value="{{ $note->longitude }}"></data></span>@endif
@if($note->replies > 0) @include('templates.replies-icon'): {{ $note->replies }}@endif
@if($note->replies_count > 0) @include('templates.replies-icon'): {{ $note->replies_count }}@endif
</div>
<div class="social-links">
@if(
@ -37,10 +37,10 @@
@endif
</div>
</div>
@if ($note->placeLink)
@if ($note->place)
<div class="map"
data-latitude="{{ $note->latitude }}"
data-longitude="{{ $note->longitude }}"
data-latitude="{{ $note->place->latitude }}"
data-longitude="{{ $note->place->longitude }}"
data-name="{{ $note->place->name }}"
data-marker="{{ $note->place->icon }}"></div>
@endif