mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-05-04 18:08:46 +03:00
To centralise logic to be more consistent, and to have smarter logic which avoids just following newline format from input, preventing smushing HTML elements (like list elements) next to eachother
113 lines
3.8 KiB
PHP
113 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace BookStack\Activity\Models;
|
|
|
|
use BookStack\App\Model;
|
|
use BookStack\Permissions\Models\JointPermission;
|
|
use BookStack\Permissions\PermissionApplicator;
|
|
use BookStack\Users\Models\HasCreatorAndUpdater;
|
|
use BookStack\Users\Models\OwnableInterface;
|
|
use BookStack\Util\HtmlContentFilter;
|
|
use BookStack\Util\HtmlContentFilterConfig;
|
|
use BookStack\Util\HtmlToPlainText;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
|
|
|
/**
|
|
* @property int $id
|
|
* @property string $html
|
|
* @property int|null $parent_id - Relates to local_id, not id
|
|
* @property int $local_id
|
|
* @property string $commentable_type
|
|
* @property int $commentable_id
|
|
* @property string $content_ref
|
|
* @property bool $archived
|
|
*/
|
|
class Comment extends Model implements Loggable, OwnableInterface
|
|
{
|
|
use HasFactory;
|
|
use HasCreatorAndUpdater;
|
|
|
|
protected $fillable = ['parent_id'];
|
|
protected $hidden = ['html'];
|
|
|
|
protected $casts = [
|
|
'archived' => 'boolean',
|
|
];
|
|
|
|
/**
|
|
* Get the entity that this comment belongs to.
|
|
*/
|
|
public function entity(): MorphTo
|
|
{
|
|
// We specifically define null here to avoid the different name (commentable)
|
|
// being used by Laravel eager loading instead of the method name, which it was doing
|
|
// in some scenarios like when deserialized when going through the queue system.
|
|
// So we instead specify the type and id column names to use.
|
|
// Related to:
|
|
// https://github.com/laravel/framework/pull/24815
|
|
// https://github.com/laravel/framework/issues/27342
|
|
// https://github.com/laravel/framework/issues/47953
|
|
// (and probably more)
|
|
|
|
// Ultimately, we could just align the method name to 'commentable' but that would be a potential
|
|
// breaking change and not really worthwhile in a patch due to the risk of creating extra problems.
|
|
return $this->morphTo(null, 'commentable_type', 'commentable_id');
|
|
}
|
|
|
|
/**
|
|
* Get the parent comment this is in reply to (if existing).
|
|
* @return BelongsTo<Comment, $this>
|
|
*/
|
|
public function parent(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Comment::class, 'parent_id', 'local_id', 'parent')
|
|
->where('commentable_type', '=', $this->commentable_type)
|
|
->where('commentable_id', '=', $this->commentable_id);
|
|
}
|
|
|
|
/**
|
|
* Check if a comment has been updated since creation.
|
|
*/
|
|
public function isUpdated(): bool
|
|
{
|
|
return $this->updated_at->timestamp > $this->created_at->timestamp;
|
|
}
|
|
|
|
public function logDescriptor(): string
|
|
{
|
|
return "Comment #{$this->local_id} (ID: {$this->id}) for {$this->commentable_type} (ID: {$this->commentable_id})";
|
|
}
|
|
|
|
public function safeHtml(): string
|
|
{
|
|
$filter = new HtmlContentFilter(new HtmlContentFilterConfig());
|
|
return $filter->filterString($this->html ?? '');
|
|
}
|
|
|
|
public function getPlainText(): string
|
|
{
|
|
$converter = new HtmlToPlainText();
|
|
return $converter->convert($this->html ?? '');
|
|
}
|
|
|
|
public function jointPermissions(): HasMany
|
|
{
|
|
return $this->hasMany(JointPermission::class, 'entity_id', 'commentable_id')
|
|
->whereColumn('joint_permissions.entity_type', '=', 'comments.commentable_type');
|
|
}
|
|
|
|
/**
|
|
* Scope the query to just the comments visible to the user based upon the
|
|
* user visibility of what has been commented on.
|
|
*/
|
|
public function scopeVisible(Builder $query): Builder
|
|
{
|
|
return app()->make(PermissionApplicator::class)
|
|
->restrictEntityRelationQuery($query, 'comments', 'commentable_id', 'commentable_type');
|
|
}
|
|
}
|