blocks()->with('comparisonResults')->get()->each(function (AcademyLessonBlock $block) use ($lesson): void { if ($lesson->isForceDeleting()) { $block->forceDelete(); return; } $block->delete(); }); }); } protected $fillable = [ 'category_id', 'title', 'slug', 'lesson_number', 'course_order', 'series_name', 'excerpt', 'content', 'content_markdown', 'difficulty', 'access_level', 'lesson_type', 'cover_image', 'article_cover_image', 'tags', 'video_url', 'reading_minutes', 'featured', 'active', 'published_at', 'seo_title', 'seo_description', ]; protected $casts = [ 'lesson_number' => 'integer', 'course_order' => 'integer', 'tags' => 'array', 'reading_minutes' => 'integer', 'featured' => 'boolean', 'active' => 'boolean', 'published_at' => 'datetime', ]; protected $appends = [ 'formatted_lesson_number', 'lesson_label', ]; public function scopeActive(Builder $query): Builder { return $query->where('active', true); } public function scopePublished(Builder $query): Builder { return $query->whereNotNull('published_at')->where('published_at', '<=', now()); } public function scopeOrderedForCourse(Builder $query): Builder { return $query ->orderByRaw('case when course_order is null then 1 else 0 end') ->orderBy('course_order') ->orderByRaw('case when lesson_number is null then 1 else 0 end') ->orderBy('lesson_number') ->orderByDesc('published_at') ->orderBy('id'); } public function category(): BelongsTo { return $this->belongsTo(AcademyCategory::class, 'category_id'); } public function progress(): HasMany { return $this->hasMany(AcademyLessonProgress::class, 'lesson_id'); } public function courseLessons(): HasMany { return $this->hasMany(AcademyCourseLesson::class, 'lesson_id') ->orderBy('order_num') ->orderBy('id'); } public function courses(): BelongsToMany { return $this->belongsToMany(AcademyCourse::class, 'academy_course_lessons', 'lesson_id', 'course_id') ->using(AcademyCourseLesson::class) ->withPivot(['section_id', 'order_num', 'is_required', 'access_override', 'unlock_after_lesson_id']) ->withTimestamps() ->orderBy('academy_course_lessons.order_num') ->orderBy('academy_course_lessons.id'); } public function blocks(): HasMany { return $this->hasMany(AcademyLessonBlock::class, 'lesson_id') ->orderBy('sort_order') ->orderBy('id'); } public function activeBlocks(): HasMany { return $this->blocks()->where('active', true); } public function getFormattedLessonNumberAttribute(): ?string { if (! is_int($this->lesson_number) || $this->lesson_number < 1) { return null; } return sprintf('Lesson %02d', $this->lesson_number); } public function getLessonLabelAttribute(): ?string { $formattedLessonNumber = $this->formatted_lesson_number; if ($formattedLessonNumber === null) { return null; } $seriesName = trim((string) ($this->series_name ?? '')); if ($seriesName === '') { return $formattedLessonNumber; } return sprintf('%s ยท %s', $seriesName, $formattedLessonNumber); } }