jonnybarnes.uk/app/Note.php
Jonny Barnes 23b6e440ba Squashed commit of the following:
commit 2840f58c61c906f5ac408e9681cf33f802625f74
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Fri Nov 25 15:52:58 2016 +0000

    Add changes

commit 86b515a20c65e4956766242db424d84082c7e99e
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Fri Nov 25 15:42:00 2016 +0000

    gulp derived assets

commit def587e2f3805a0ba669d804b12d83e9f3ec5ea7
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Fri Nov 25 15:41:43 2016 +0000

    Include new contact styles

commit 8256dc30b0ad23096b3dcde264826fc6cfaa8788
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Fri Nov 25 15:41:19 2016 +0000

    Better styled contacts

commit f12ce1d6f68857d88ad6f39f8b835d036c793c8a
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Wed Nov 23 18:11:47 2016 +0000

    Sort out views for contacts, better h-card

commit 7be5fe82029b20f6cde3ce921f0cb625c27d21d6
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Wed Nov 23 18:09:00 2016 +0000

    quick code tidy

commit 71dad7e4918ff4e513715d4ef3a296fa39507ca1
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Wed Nov 23 16:58:32 2016 +0000

    Get contact editing working

commit 0b885190733979be4f5508d28523e8e0b45399a2
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Wed Nov 23 16:42:10 2016 +0000

    Improve form layout, add facebook entry

commit 0a6bd79e384dcd872cb9a89b1232afaf20e729b2
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Wed Nov 23 16:41:49 2016 +0000

    Add facebook column

commit 639d49045c9a213eafd970ceafe288a51cfc95c8
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Wed Nov 23 16:30:40 2016 +0000

    Update changelog

commit f4a018591d50bf9af7e1a64daa9e4a04daa6e1d4
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Wed Nov 23 16:27:42 2016 +0000

    Reference right view, use a better variable name when parsing a URL

commit 583f7d7f7cc577cf31b37bbc2bdcd8865c7b9980
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Wed Nov 23 16:26:58 2016 +0000

    Move mini-hcard to templates folder, update content

commit 2e1b13eff052b65cf2b86796a9509c81d9c86768
Author: Jonny Barnes <jonny@jonnybarnes.uk>
Date:   Wed Nov 23 16:26:10 2016 +0000

    Add facebook column to contacts table
2016-11-25 15:53:14 +00:00

228 lines
6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App;
use Normalizer;
use Jonnybarnes\IndieWeb\Numbers;
use Illuminate\Database\Eloquent\Model;
use League\CommonMark\CommonMarkConverter;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\HasMedia\Interfaces\HasMedia;
use Illuminate\Database\Eloquent\ModelNotFoundException;
class Note extends Model implements HasMedia
{
use SoftDeletes;
use HasMediaTrait;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'notes';
/**
* Define the relationship with tags.
*
* @var array
*/
public function tags()
{
return $this->belongsToMany('App\Tag');
}
/**
* Define the relationship with webmentions.
*
* @var array
*/
public function webmentions()
{
return $this->morphMany('App\WebMention', 'commentable');
}
/**
* Definte the relationship with places.
*
* @var array
*/
public function place()
{
return $this->belongsTo('App\Place');
}
/**
* We shall set a blacklist of non-modifiable model attributes.
*
* @var array
*/
protected $guarded = ['id'];
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['deleted_at'];
/**
* 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.
*
* @param string $value
* @return string
*/
public function setNoteAttribute($value)
{
$this->attributes['note'] = normalizer_normalize($value, Normalizer::FORM_C);
}
/**
* Pre-process notes for web-view.
*
* @param string
* @return string
*/
public function getNoteAttribute($value)
{
$markdown = new CommonMarkConverter();
$html = $markdown->convertToHtml($value);
$hcards = $this->makeHCards($html);
$hashtags = $this->autoLinkHashtag($hcards);
return $hashtags;
}
/**
* Generate the NewBase60 ID from primary ID.
*
* @return string
*/
public function getNb60idAttribute()
{
$numbers = new Numbers();
return $numbers->numto60($this->id);
}
/**
* The Long URL for a note.
*
* @return string
*/
public function getLongurlAttribute()
{
return config('app.url') . '/notes/' . $this->nb60id;
}
/**
* The Short URL for a note.
*
* @return string
*/
public function getShorturlAttribute()
{
return config('app.shorturl') . '/notes/' . $this->nb60id;
}
/**
* Get the relavent client name assocaited with the client id.
*
* @return string|null
*/
public function getClientNameAttribute()
{
if ($this->client_id == null) {
return;
}
$name = MicropubClient::where('client_url', $this->client_id)->value('client_name');
if ($name == null) {
$url = parse_url($this->client_id);
if (isset($url['path'])) {
return $url['host'] . $url['path'];
}
return $url['host'];
}
return $name;
}
/**
* 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 notes text
* @return string
*/
private function makeHCards($text)
{
$regex = '/\[.*?\](*SKIP)(*F)|@(\w+)/'; //match @alice but not [@bob](...)
$hcards = preg_replace_callback(
$regex,
function ($matches) {
try {
$contact = Contact::where('nick', '=', mb_strtolower($matches[1]))->firstOrFail();
} catch (ModelNotFoundException $e) {
//assume its an actual twitter handle
return '<a href="https://twitter.com/' . $matches[1] . '">' . $matches[0] . '</a>';
}
$host = parse_url($contact->homepage, PHP_URL_HOST);
$contact->photo = (file_exists(public_path() . '/assets/profile-images/' . $host . '/image')) ?
'/assets/profile-images/' . $host . '/image'
:
'/assets/profile-images/default-image';
return trim(view('templates.mini-hcard', ['contact' => $contact])->render());
},
$text
);
return $hcards;
}
/**
* 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
* @return string
*/
private function autoLinkHashtag($text)
{
// $replacements = ["#tag" => "<a rel="tag" href="/tags/tag">#tag</a>]
$replacements = [];
$matches = [];
if (preg_match_all('/(?<=^|\s)\#([a-zA-Z0-9\-\_]+)/i', $text, $matches, PREG_PATTERN_ORDER)) {
// Look up #tags, get Full name and URL
foreach ($matches[0] as $name) {
$name = str_replace('#', '', $name);
$replacements[$name] =
'<a rel="tag" class="p-category" href="/notes/tagged/' . Tag::normalizeTag($name) . '">#' . $name . '</a>';
}
// Replace #tags with valid microformat-enabled link
foreach ($replacements as $name => $replacement) {
$text = str_replace('#' . $name, $replacement, $text);
}
}
return $text;
}
}