You're supposed to be using a third-party comment system not this.
But if you really need to, this package lets you add comments to your Eloquent models.
Play around with this demo project
$ composer require plmrlnsnts/commentator
Run the following command to publish config and migration files.
php artisan vendor:publish --provider="Plmrlnsnts\Commentator\CommentatorServiceProvider"
Run the migrations.
php artisan migrate
Next, register the routes to manage comments in the boot
method of your AppServiceProvider
.
use Plmrlnsnts\Commentator\Commentator;
public function boot()
{
Commentator::routes();
}
Add the HasComments
trait to your eloquent models.
use Plmrlnsnts\Commentator\HasComments;
class Article extends Model
{
use HasComments;
}
To add a comment to your model, use the addComment
method.
$article = Article::first();
$article->addComment(['body' => 'Better call Saul!']);
If you also support media files, pass an additional media
attribute.
$article->addComment([
'body' => 'Yo Mr. White! Check this out.',
'media' => 'https://unsplash.com/photos/yplNhhXxBtM',
]);
A user can be mentioned using @
followed by a combination of alphanumeric characters, underscores and hypens.
$comment = $article->addComment(['body' => '@Pinkman']);
Call the mentionedNames
method to retrieve an array of mentions.
$comment->mentionedNames();
// ['Pinkman']
Mentions are transformed to anchor tags by calling asHtml
to a comment instance.
$comment->asHtml();
// <a href="/profile/Pinkman">@Pinkman</a>
The
asHtml
strips any html element except anchor tags to prevent xss attacks.
If you want to support nested comments, use the addReply
method.
$comment->addReply(['body' => 'I am Heisenberg.']);
Commentator provides a JSON API that you may use to manage comments. This saves you the trouble of having to manually code controllers for creating, updating, and deleting comments.
This route returns a paginated list of comments for a given model. You need to pass the commentableKey
, and an optional sort
parameter to order the result from latest
.
const params = {
commentableKey: 'SOMESTRING',
sort: 'latest',
page: 1,
perPage: 10,
}
axios.get('/comments', { params })
.then(response => {
console.log(response.data)
})
This route is used to create new comments. It accepts two pieces of data: a body and/or a media.
const data = {
body: 'Yo, Mr. White! Check this out.',
media: 'https://unsplash.com/photos/yplNhhXxBtM',
commentableKey: 'SOMESTRING',
}
axios.post('/comments', data)
.then(response => {
console.log(response.data)
})
This route is used to update comments. It accepts two pieces of data: a body and/or a media.
const data = {
body: 'Changed',
}
axios.patch(`/comments/${commment.id}`, data)
.then(response => {
console.log(response.data)
})
Only comments that are owned by the authenticated user can be updated.
This route is used to delete comments.
axios.delete(`/comments/${commment.id}`)
.then(response => {
//
})
Only comments that are owned by the authenticated user can be deleted.
This route returns a paginated list of replies for a comment. You may pass an optional sort
parameter to order the result from latest
.
const params = {
sort: 'latest',
page: 1,
perPage: 10,
}
axios.get(`/comments/${comment.id}/replies`, { params })
.then(response => {
console.log(response.data)
})
This route is used to reply to a comment. It accepts two pieces of data: a body and/or a media.
const data = {
body: 'Yo, Mr. White! Check this out.',
media: 'https://unsplash.com/photos/yplNhhXxBtM',
}
axios.post(`/comments/${comment.id}/replies`, data)
.then(response => {
console.log(response.data)
})
Replies are comments too! So you can re-use the same routes for updating and deleting replies.
Commentator references the current User
model as the author when adding comments. If you are using a different namespace, change them in config/commentator.php
.
return [
'models' => [
'user' => \App\Models\User::class
]
];
The regular expression used to identify mentions, and the parsed link can be modified from the config
file.
return [
'mentions' => [
'regex' => '/@([\w\-]+)/',
'replace' => '<a href="/profile/$1">@$1</a>'
]
];