*/ public function compare(CourseVersion $before, CourseVersion $after): array { $before->loadMissing(['modules.lessons.blocks', 'assessments.questions']); $after->loadMissing(['modules.lessons.blocks', 'assessments.questions']); $categories = [ $this->category('structure', 'ساختار', $this->structure($before), $this->structure($after), $this->structureLabel($before), $this->structureLabel($after)), $this->category('content', 'محتوا', $this->content($before), $this->content($after), $this->contentLabel($before), $this->contentLabel($after)), $this->category('assessments', 'ارزیابی‌ها', $this->assessments($before), $this->assessments($after), $this->assessmentLabel($before), $this->assessmentLabel($after)), $this->category('settings', 'تنظیمات', $this->settings($before), $this->settings($after), 'مشخصات و قوانین نسخه', 'مشخصات و قوانین نسخه'), ]; return [ 'compatible' => true, 'before' => $this->identity($before), 'after' => $this->identity($after), 'changedCategories' => collect($categories)->where('changed', true)->count(), 'categories' => $categories, ]; } public function unpublishedChangeCount(CourseVersion $version): int { if ($version->status->value !== 'draft') { return 0; } if (! $version->source_version_id) { $version->loadMissing(['modules.lessons.blocks', 'assessments.questions']); return $version->modules->count() + $version->lessons->count() + $version->blocks->count() + $version->assessments->count(); } $source = CourseVersion::query()->where('organization_id', $version->organization_id)->where('course_id', $version->course_id)->find($version->source_version_id); if (! $source) { return 0; } return collect($this->compare($source, $version)['categories'])->where('changed', true)->count(); } /** @return array */ private function identity(CourseVersion $version): array { return ['id' => $version->getKey(), 'number' => $version->version_number, 'status' => $version->status->value]; } /** @return array */ private function category(string $key, string $label, array $before, array $after, string $beforeLabel, string $afterLabel): array { return compact('key', 'label', 'beforeLabel', 'afterLabel') + ['changed' => $before !== $after]; } private function structure(CourseVersion $version): array { return $version->modules->sortBy('position')->map(fn ($module) => [ 'title' => $module->title, 'position' => $module->position, 'lessons' => $module->lessons->sortBy('position')->map(fn ($lesson) => ['title' => $lesson->title, 'position' => $lesson->position, 'presentationMode' => $lesson->presentation_mode])->values()->all(), ])->values()->all(); } private function content(CourseVersion $version): array { return $version->modules->sortBy('position')->flatMap(fn ($module) => $module->lessons->sortBy('position')->map(fn ($lesson) => [ 'lessonPosition' => $lesson->position, 'blocks' => $lesson->blocks->sortBy('position')->map(fn ($block) => ['type' => $block->type, 'schemaVersion' => $block->schema_version, 'data' => $block->data, 'style' => $block->style, 'behavior' => $block->behavior, 'responsive' => $block->responsive, 'accessibility' => $block->accessibility, 'position' => $block->position])->values()->all(), ]))->values()->all(); } private function assessments(CourseVersion $version): array { return $version->assessments->sortBy('created_at')->map(fn ($assessment) => [ 'title' => $assessment->title, 'settings' => $assessment->settings, 'questions' => $assessment->questions->sortBy('position')->map(fn ($question) => ['type' => $question->type, 'prompt' => $question->prompt, 'configuration' => $question->configuration, 'position' => $question->position])->values()->all(), ])->values()->all(); } private function settings(CourseVersion $version): array { return ['title' => $version->title, 'description' => $version->description, 'settings' => $version->settings, 'completionRules' => $version->completion_rules]; } private function structureLabel(CourseVersion $version): string { return $version->modules->count().' ماژول · '.$version->lessons->count().' درس'; } private function contentLabel(CourseVersion $version): string { return $version->blocks->count().' بلوک محتوایی'; } private function assessmentLabel(CourseVersion $version): string { return $version->assessments->count().' ارزیابی'; } }