From 1ba1b40588ae98b445cb594d25ca9b7ba0e15aa0 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Sun, 22 Oct 2017 16:16:13 +0100 Subject: [PATCH] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 94b13846d90c02041f56b21111709da91cd40726 Author: Jonny Barnes Date: Sun Oct 22 15:51:47 2017 +0100 Remove un-needed use statement commit c370d83766fb10a100f780124bdcfc2694208140 Author: Jonny Barnes Date: Sun Oct 22 15:44:50 2017 +0100 use fillable instead of guarded, drop dates transform commit dcf620c168f75d6c9860f5149adebfaceb9d772f Author: Jonny Barnes Date: Sun Oct 22 15:42:41 2017 +0100 Given we are adding a property for contacts, we need to invoke Laravel’s own model __construct() method. commit 0cba9301c3175e60bf1c3b0ada36c79a3c33c72c Author: Jonny Barnes Date: Sun Oct 22 15:37:19 2017 +0100 Given change in mass-assignment protection, change how we populate database commit 7d09d174153ca99c0975d70fbccdc340d437227c Author: Jonny Barnes Date: Sun Oct 22 10:38:51 2017 +0100 Use a property to hold parsed contact info commit 25b05f8592ee282da5d82227b9873b523e9955d3 Author: Jonny Barnes Date: Fri Oct 20 17:19:44 2017 +0100 First attempts at reducing eloquent calls --- app/Note.php | 138 +++++++++++++++------------ database/factories/NoteFactory.php | 2 - database/seeds/NotesTableSeeder.php | 14 +-- resources/views/notes/show.blade.php | 2 +- 4 files changed, 86 insertions(+), 70 deletions(-) diff --git a/app/Note.php b/app/Note.php index 9acaa18b..1037afc8 100644 --- a/app/Note.php +++ b/app/Note.php @@ -4,6 +4,7 @@ namespace App; use Cache; use Twitter; +use Debugbar; use Normalizer; use GuzzleHttp\Client; use Laravel\Scout\Searchable; @@ -16,7 +17,6 @@ use Illuminate\Database\Eloquent\Model; use Jonnybarnes\EmojiA11y\EmojiModifier; use Illuminate\Database\Eloquent\SoftDeletes; use Jonnybarnes\CommonmarkLinkify\LinkifyExtension; -use Illuminate\Database\Eloquent\ModelNotFoundException; class Note extends Model { @@ -28,7 +28,15 @@ class Note extends Model * * @var string */ - private const USERNAMES_REGEX = '/\[.*?\](*SKIP)(*F)|@(\w+)/'; + private const USERNAMES_REGEX = '/@(\w+)/'; + + protected $contacts; + + public function __construct(array $attributes = []) + { + parent::__construct($attributes); + $this->contacts = null; + } /** * The database table used by the model. @@ -37,6 +45,24 @@ class Note extends Model */ protected $table = 'notes'; + /* + * Mass-assignment + * + * @var array + */ + protected $fillable = [ + 'note', + 'in_reply_to', + 'client_id', + ]; + + /** + * Hide the column used with Laravel Scout. + * + * @var array + */ + protected $hidden = ['searchable']; + /** * Define the relationship with tags. * @@ -87,27 +113,6 @@ class Note extends Model return $this->hasMany('App\Media'); } - /** - * We shall set a blacklist of non-modifiable model attributes. - * - * @var array - */ - protected $guarded = ['id']; - - /** - * Hide the column used with Laravel Scout. - * - * @var array - */ - protected $hidden = ['searchable']; - - /** - * The attributes that should be mutated to dates. - * - * @var array - */ - protected $dates = ['deleted_at']; - /** * Set the attributes to be indexed for searching with Scout. * @@ -141,9 +146,9 @@ class Note extends Model { $emoji = new EmojiModifier(); - $html = $this->convertMarkdown($value); - $hcards = $this->makeHCards($html); - $hashtags = $this->autoLinkHashtag($hcards); + $hcards = $this->makeHCards($value); + $html = $this->convertMarkdown($hcards); + $hashtags = $this->autoLinkHashtag($html); $modified = $emoji->makeEmojiAccessible($hashtags); return $modified; @@ -297,21 +302,16 @@ class Note extends Model */ public function getTwitterContentAttribute() { - // find @mentions - preg_match_all(self::USERNAMES_REGEX, $this->getOriginal('note'), $matches); - if (count($matches[1]) === 0) { + if ($this->contacts === null) { return; } - // check if any @mentions have a contact associated with them - $count = 0; - foreach ($matches[1] as $match) { - $contact = Contact::where('nick', '=', mb_strtolower($match))->first(); - if ($contact) { - $count++; - } + if (count($this->contacts) === 0) { + return; } - if ($count === 0) { + + if (count(array_unique(array_values($this->contacts))) === 1 + && array_unique(array_values($this->contacts))[0] === null) { return; } @@ -319,12 +319,11 @@ class Note extends Model $swapped = preg_replace_callback( self::USERNAMES_REGEX, function ($matches) { - try { - $contact = Contact::where('nick', '=', mb_strtolower($matches[1]))->firstOrFail(); - } catch (ModelNotFoundException $e) { - //assume its an actual twitter handle + if (is_null($this->contacts[$matches[1]])) { return $matches[0]; } + + $contact = $this->contacts[$matches[1]]; if ($contact->twitter) { return '@' . $contact->twitter; } @@ -339,21 +338,12 @@ class Note extends Model public function getFacebookContentAttribute() { - // find @mentions - preg_match_all(self::USERNAMES_REGEX, $this->getOriginal('note'), $matches); - if (count($matches[1]) === 0) { + if (count($this->contacts) === 0) { return; } - // check if any @mentions have a contact associated with them - $count = 0; - foreach ($matches[1] as $match) { - $contact = Contact::where('nick', '=', mb_strtolower($match))->first(); - if ($contact) { - $count++; - } - } - if ($count === 0) { + if (count(array_unique(array_values($this->contacts))) === 1 + && array_unique(array_values($this->contacts))[0] === null) { return; } @@ -361,12 +351,11 @@ class Note extends Model $swapped = preg_replace_callback( self::USERNAMES_REGEX, function ($matches) { - try { - $contact = Contact::where('nick', '=', mb_strtolower($matches[1]))->firstOrFail(); - } catch (ModelNotFoundException $e) { - //assume its an actual twitter handle + if (is_null($this->contacts[$matches[1]])) { return $matches[0]; } + + $contact = $this->contacts[$matches[1]]; if ($contact->facebook) { return '' . $contact->name . ''; @@ -405,15 +394,20 @@ class Note extends Model */ private function makeHCards($text) { + $this->getContacts(); + + if (count($this->contacts) === 0) { + return $text; + } + $hcards = preg_replace_callback( self::USERNAMES_REGEX, function ($matches) { - try { - $contact = Contact::where('nick', '=', mb_strtolower($matches[1]))->firstOrFail(); - } catch (ModelNotFoundException $e) { - //assume its an actual twitter handle + if (is_null($this->contacts[$matches[1]])) { return '' . $matches[0] . ''; } + + $contact = $this->contacts[$matches[1]]; // easier to read the following code $host = parse_url($contact->homepage, PHP_URL_HOST); $contact->photo = (file_exists(public_path() . '/assets/profile-images/' . $host . '/image')) ? '/assets/profile-images/' . $host . '/image' @@ -428,6 +422,28 @@ class Note extends Model return $hcards; } + public function getContacts() + { + if ($this->contacts === null) { + $this->setContacts(); + } + } + + public function setContacts() + { + $contacts = []; + if ($this->getOriginal('note')) { + preg_match_all(self::USERNAMES_REGEX, $this->getoriginal('note'), $matches); + + foreach ($matches[1] as $match) { + Debugbar::info('query inside getContacts'); + $contacts[$match] = Contact::where('nick', mb_strtolower($match))->first(); + } + } + + $this->contacts = $contacts; + } + /** * Given a string and section, finds all hashtags matching * `#[\-_a-zA-Z0-9]+` and wraps them in an `a` element with diff --git a/database/factories/NoteFactory.php b/database/factories/NoteFactory.php index cda94a9d..8fec01c7 100644 --- a/database/factories/NoteFactory.php +++ b/database/factories/NoteFactory.php @@ -5,7 +5,5 @@ use Faker\Generator as Faker; $factory->define(App\Note::class, function (Faker $faker) { return [ 'note' => $faker->paragraph, - 'tweet_id' => $faker->randomNumber(9), - 'facebook_url' => 'https://facebook.com/' . $faker->randomNumber(9), ]; }); diff --git a/database/seeds/NotesTableSeeder.php b/database/seeds/NotesTableSeeder.php index 3509ae8a..0a73a481 100644 --- a/database/seeds/NotesTableSeeder.php +++ b/database/seeds/NotesTableSeeder.php @@ -15,8 +15,8 @@ class NotesTableSeeder extends Seeder sleep(1); $noteWithPlace = App\Note::create([ 'note' => 'Having a #beer at the local. 🍺', - 'tweet_id' => '123456789', ]); + $noteWithPlace->tweet_id = '123456789'; $place = App\Place::find(1); $noteWithPlace->place()->associate($place); $noteWithPlace->save(); @@ -43,15 +43,17 @@ class NotesTableSeeder extends Seeder } $noteWithCoords = App\Note::create([ 'note' => 'Note from somehwere', - 'location' => '53.499,-2.379' ]); + $noteWithCoords->location = '53.499,-2.379'; + $noteWithCoords->save(); sleep(1); $noteSyndicated = App\Note::create([ 'note' => 'This note has all the syndication targets', - 'tweet_id' => '123456', - 'facebook_url' => 'https://www.facebook.com/post/12345789', - 'swarm_url' => 'https://www.swarmapp.com/checking/123456789', - 'instagram_url' => 'https://www.instagra.com/p/aWsEd123Jh', ]); + $noteSyndicated->tweet_id = '123456'; + $noteSyndicated->facebook_url = 'https://www.facebook.com/post/12345789'; + $noteSyndicated->swarm_url = 'https://www.swarmapp.com/checking/123456789'; + $noteSyndicated->instagram_url = 'https://www.instagram.com/p/aWsEd123Jh'; + $noteSyndicated->save(); } } diff --git a/resources/views/notes/show.blade.php b/resources/views/notes/show.blade.php index e4817757..e0a7770d 100644 --- a/resources/views/notes/show.blade.php +++ b/resources/views/notes/show.blade.php @@ -1,7 +1,7 @@ @extends('master') @section('title') -{{ strip_tags($note->note) }} « Notes « +{{ strip_tags($note->getOriginal('note')) }} « Notes « @stop @section('content')