*/ protected $fillable = [ 'documentation_category_id', 'title', 'slug', 'summary', 'body', 'status', 'is_featured', 'version', 'reference', 'attachment_disk', 'attachment_path', 'attachment_name', 'attachment_mime', 'attachment_size', 'published_at', 'created_by', 'updated_by', ]; /** @var array */ protected $casts = [ 'is_featured' => 'boolean', 'published_at' => 'datetime', 'attachment_size' => 'integer', ]; /** * Bootstrap the model. */ protected static function booted(): void { static::saving(function (DocumentationDocument $document): void { if (blank($document->slug)) { $document->slug = Str::slug($document->title); } if ($document->status === self::STATUS_PUBLISHED && blank($document->published_at)) { $document->published_at = now(); } }); } /** * Owning category. * * @return BelongsTo */ public function category(): BelongsTo { return $this->belongsTo(DocumentationCategory::class, 'documentation_category_id'); } /** * Document attachments. * * @return HasMany */ public function attachments(): HasMany { return $this->hasMany(DocumentationAttachment::class, 'documentation_document_id')->latest(); } /** * Published document scope. * * @param Builder $query * @return Builder */ public function scopePublished(Builder $query): Builder { return $query->where('status', self::STATUS_PUBLISHED); } /** * Featured document scope. * * @param Builder $query * @return Builder */ public function scopeFeatured(Builder $query): Builder { return $query->where('is_featured', true); } /** * Render the document body as safe Markdown HTML for display. */ public function getRenderedBodyAttribute(): string { $body = trim((string) $this->body); if ($body === '') { return '

No document body has been added yet.

'; } if (method_exists(Str::class, 'markdown')) { return (string) Str::markdown($body, [ 'html_input' => 'strip', 'allow_unsafe_links' => false, ]); } return '

' . nl2br(e($body), false) . '

'; } /** * Determine whether the attached file is a Markdown document. */ public function hasMarkdownAttachment(): bool { $name = strtolower((string) $this->attachment_name); $mime = strtolower((string) $this->attachment_mime); return str_ends_with($name, '.md') || in_array($mime, ['text/markdown', 'text/x-markdown', 'text/plain'], true); } }