]> BookStack Code Mirror - bookstack/blobdiff - app/Activity/Models/Comment.php
API: Built out tests for comment API endpoints
[bookstack] / app / Activity / Models / Comment.php
index 72098a3c3c34d3974d3bfb09bd6a52d3f9629c53..4d6c7fa41c6c908640505cd084058ea0c35aa0b3 100644 (file)
@@ -3,41 +3,56 @@
 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 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   $text
  * @property string   $html
- * @property int|null $parent_id
+ * @property int|null $parent_id  - Relates to local_id, not id
  * @property int      $local_id
- * @property string   $entity_type
- * @property int      $entity_id
+ * @property string   $commentable_type
+ * @property int      $commentable_id
+ * @property string   $content_ref
+ * @property bool     $archived
  */
-class Comment extends Model implements Loggable
+class Comment extends Model implements Loggable, OwnableInterface
 {
     use HasFactory;
     use HasCreatorAndUpdater;
 
-    protected $fillable = ['text', 'parent_id'];
-    protected $appends = ['created', 'updated'];
+    protected $fillable = ['parent_id'];
+    protected $hidden = ['html'];
+
+    protected $casts = [
+        'archived' => 'boolean',
+    ];
 
     /**
      * Get the entity that this comment belongs to.
      */
     public function entity(): MorphTo
     {
-        return $this->morphTo('entity');
+        return $this->morphTo('commentable');
     }
 
     /**
      * Get the parent comment this is in reply to (if existing).
+     * @return BelongsTo<Comment, $this>
      */
-    public function parent()
+    public function parent(): BelongsTo
     {
-        return $this->belongsTo(Comment::class);
+        return $this->belongsTo(Comment::class, 'parent_id', 'local_id', 'parent')
+            ->where('commentable_type', '=', $this->commentable_type)
+            ->where('commentable_id', '=', $this->commentable_id);
     }
 
     /**
@@ -48,28 +63,29 @@ class Comment extends Model implements Loggable
         return $this->updated_at->timestamp > $this->created_at->timestamp;
     }
 
-    /**
-     * Get created date as a relative diff.
-     *
-     * @return mixed
-     */
-    public function getCreatedAttribute()
+    public function logDescriptor(): string
     {
-        return $this->created_at->diffForHumans();
+        return "Comment #{$this->local_id} (ID: {$this->id}) for {$this->commentable_type} (ID: {$this->commentable_id})";
     }
 
-    /**
-     * Get updated date as a relative diff.
-     *
-     * @return mixed
-     */
-    public function getUpdatedAttribute()
+    public function safeHtml(): string
     {
-        return $this->updated_at->diffForHumans();
+        return HtmlContentFilter::removeScriptsFromHtmlString($this->html ?? '');
     }
 
-    public function logDescriptor(): string
+    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 "Comment #{$this->local_id} (ID: {$this->id}) for {$this->entity_type} (ID: {$this->entity_id})";
+        return app()->make(PermissionApplicator::class)
+            ->restrictEntityRelationQuery($query, 'comments', 'commentable_id', 'commentable_type');
     }
 }