PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.10.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.10.0
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
← All changes | Modules/Course/Http/Controllers/CourseAdminController.php +42 -7 2.9.12.10.0 View file →
@@ -85,9 +85,9 @@
85 85 $courseData = [
86 86 'parent_id' => $request->get('parent_id') ?: null, // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
87 87 'title' => $request->getSafe('title', 'sanitize_text_field'),
88 88 'privacy' => $request->get('privacy'),
89 - 'description' => wp_kses_post($request->get('description')),
89 + 'description' => wp_kses_post((string) $request->get('description', '')),
90 90 'status' => $request->get('status', 'draft'),
91 91 'settings' => [
92 92 'course_type' => $request->get('course_type'),
93 93 'emoji' => CustomSanitizer::sanitizeEmoji($request->get('settings.emoji', '')),
@@ -94,9 +94,9 @@
94 94 'shape_svg' => CustomSanitizer::sanitizeSvg($request->get('settings.shape_svg', '')),
95 95 'disable_comments' => $request->get('settings.disable_comments') === 'yes' ? 'yes' : 'no',
96 96 'hide_members_count' => $request->get('settings.hide_members_count') === 'yes' ? 'yes' : 'no',
97 97 'course_layout' => $request->get('settings.course_layout') === 'modern' ? 'modern' : 'classic',
98 - 'course_details' => CustomSanitizer::unslashMarkdown(trim($request->get('settings.course_details'))),
98 + 'course_details' => CustomSanitizer::unslashMarkdown(trim((string) $request->get('settings.course_details', ''))),
99 99 'hide_instructor_view' => $request->get('settings.hide_instructor_view') === 'yes' ? 'yes' : 'no',
100 100 'show_instructor_students_count' => $request->get('settings.show_instructor_students_count') === 'yes' ? 'yes' : 'no',
101 101 'sequential_lesson_order' => $request->get('settings.sequential_lesson_order') === 'yes' ? 'yes' : 'no',
102 102 ],
@@ -229,9 +229,9 @@
229 229
230 230 $courseData = [
231 231 'title' => $request->getSafe('title', 'sanitize_text_field'),
232 232 'privacy' => $request->get('privacy'),
233 - 'description' => wp_kses_post($request->get('description')),
233 + 'description' => wp_kses_post((string) $request->get('description', '')),
234 234 'status' => $request->get('status'),
235 235 'cover_photo' => $request->getSafe('cover_photo', 'sanitize_url'),
236 236 'parent_id' => $request->get('parent_id') ?: null, // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
237 237 ];
@@ -303,9 +303,9 @@
303 303 $existingSettings['show_instructor_students_count'] = $request->get('settings.show_instructor_students_count') === 'yes' ? 'yes' : 'no';
304 304 $existingSettings['show_paywalls'] = $request->get('settings.show_paywalls') === 'yes' ? 'yes' : 'no';
305 305 $existingSettings['show_welcome_banner'] = $request->get('settings.show_welcome_banner') === 'yes' ? 'yes' : 'no';
306 306 $existingSettings['course_layout'] = $request->get('settings.course_layout') === 'modern' ? 'modern' : 'classic';
307 - $existingSettings['course_details'] = CustomSanitizer::unslashMarkdown(trim($request->get('settings.course_details')));
307 + $existingSettings['course_details'] = CustomSanitizer::unslashMarkdown(trim((string) $request->get('settings.course_details', '')));
308 308 $existingSettings['sequential_lesson_order'] = $request->get('settings.sequential_lesson_order') === 'yes' ? 'yes' : 'no';
309 309
310 310 if ($request->get('privacy') == 'public' && $existingSettings['course_type'] == 'self_paced') {
311 311 $existingSettings['public_lesson_view'] = $request->get('settings.public_lesson_view') == 'yes' ? 'yes' : 'no';
@@ -383,8 +383,10 @@
383 383 $newTopic = $topic->replicate();
384 384 $newTopic->space_id = $newCourse->id;
385 385 $newTopic->save();
386 386
387 + do_action('fluent_community/section/created', $newTopic, $newCourse);
388 +
387 389 foreach ($topic->lessons as $lesson) {
388 390 /** @var CourseLesson $lesson */
389 391 $newLesson = $lesson->replicate();
390 392 $newLesson->space_id = $newCourse->id;
@@ -390,8 +392,10 @@
390 392 $newLesson->space_id = $newCourse->id;
391 393 $newLesson->parent_id = $newTopic->id;
392 394 $newLesson->save();
393 395 CourseHelper::copyLessonDocuments($lesson, $newLesson);
396 +
397 + do_action('fluent_community/lesson/created', $newLesson, $newTopic);
394 398 }
395 399 }
396 400
397 401 do_action('fluent_community/course/created', $newCourse);
@@ -735,9 +739,9 @@
735 739 'space_id' => $courseId,
736 740 'status' => 'published',
737 741 ];
738 742
739 - Course::findOrFail($courseId);
743 + $course = Course::findOrFail($courseId);
740 744
741 745 $latestPriority = CourseTopic::where('type', 'course_section')->where('space_id', $courseId)->max('priority');
742 746
743 747 $sectionData['priority'] = (int) $latestPriority + 1;
@@ -745,8 +749,10 @@
745 749 $section = CourseTopic::create($sectionData);
746 750
747 751 $section->load('lessons');
748 752
753 + do_action('fluent_community/section/created', $section, $course);
754 +
749 755 return [
750 756 'message' => __('Section has been created successfully.', 'fluent-community'),
751 757 'section' => $section,
752 758 ];
@@ -868,8 +874,10 @@
868 874 $newSection->space_id = $toCourse->id;
869 875 $newSection->priority = (int) $latestPriority + 1;
870 876 $newSection->save();
871 877
878 + do_action('fluent_community/section/created', $newSection, $toCourse);
879 +
872 880 $originalLessons = CourseLesson::where('parent_id', $originalSection->id)->get();
873 881 foreach ($originalLessons as $lesson) {
874 882 /** @var CourseLesson $lesson */
875 883 $newLesson = $lesson->replicate();
@@ -876,8 +884,10 @@
876 884 $newLesson->space_id = $toCourse->id;
877 885 $newLesson->parent_id = $newSection->id;
878 886 $newLesson->save();
879 887 CourseHelper::copyLessonDocuments($lesson, $newLesson);
888 +
889 + do_action('fluent_community/lesson/created', $newLesson, $newSection);
880 890 }
881 891
882 892 $newSection->load('lessons');
883 893
@@ -989,8 +999,10 @@
989 999 $lesson = CourseLesson::create($lessonData);
990 1000
991 1001 $lesson = CourseLesson::findOrFail($lesson->id);
992 1002
1003 + do_action('fluent_community/lesson/created', $lesson, $topic);
1004 +
993 1005 return [
994 1006 'message' => __('Lesson has been created successfully.', 'fluent-community'),
995 1007 'lesson' => $lesson,
996 1008 ];
@@ -1068,8 +1080,12 @@
1068 1080 if ($dirtyFields) {
1069 1081 $lesson->save();
1070 1082 $isNewlyPublished = $lesson->status === 'published' && $previousStatus !== 'published';
1071 1083 do_action('fluent_community/lesson/updated', $lesson, $dirtyFields, $isNewlyPublished);
1084 +
1085 + if ($isNewlyPublished) {
1086 + do_action('fluent_community/lesson/published', $lesson);
1087 + }
1072 1088 }
1073 1089
1074 1090 do_action('fluent_community/lesson/additional_media_updated', $request->all(), $lesson, $updateData);
1075 1091
@@ -1086,8 +1102,10 @@
1086 1102 })
1087 1103 ->where('id', $lessionId)
1088 1104 ->firstOrFail();
1089 1105
1106 + $previousStatus = $lesson->status;
1107 +
1090 1108 $acceptedFields = [ 'title', 'status', 'slug' ];
1091 1109
1092 1110 // empty title/slug/status must not overwrite, but a literal "0" is a valid value
1093 1111 // Request::only() is a plain array pick with no sanitization, so each field is
@@ -1101,9 +1119,16 @@
1101 1119 $lessonData['title'] = sanitize_text_field($lessonData['title']);
1102 1120 }
1103 1121
1104 1122 if (isset($lessonData['slug'])) {
1105 - $lessonData['slug'] = sanitize_title($lessonData['slug']);
1123 + // sanitize_title() alone let an author set a slug already taken by a
1124 + // sibling lesson, which getLessonBySlug() then resolves arbitrarily.
1125 + $lessonData['slug'] = CourseLesson::uniqueSlug(
1126 + $lessonData['slug'],
1127 + $lesson->space_id,
1128 + $lesson->id,
1129 + Arr::get($lessonData, 'title', $lesson->title)
1130 + );
1106 1131 }
1107 1132
1108 1133 if (isset($lessonData['status']) && !in_array($lessonData['status'], ['draft', 'published', 'archived'], true)) {
1109 1134 unset($lessonData['status']);
@@ -1121,10 +1146,19 @@
1121 1146 }
1122 1147
1123 1148 if (!empty($lessonData)) {
1124 1149 $lesson->fill($lessonData);
1125 - if ($lesson->isDirty()) {
1150 + $dirtyFields = $lesson->getDirty();
1151 +
1152 + if ($dirtyFields) {
1126 1153 $lesson->save();
1154 +
1155 + $isNewlyPublished = $lesson->status === 'published' && $previousStatus !== 'published';
1156 + do_action('fluent_community/lesson/updated', $lesson, $dirtyFields, $isNewlyPublished);
1157 +
1158 + if ($isNewlyPublished) {
1159 + do_action('fluent_community/lesson/published', $lesson);
1160 + }
1127 1161 }
1128 1162 }
1129 1163
1130 1164 return [
@@ -1199,8 +1233,9 @@
1199 1233 $newLesson = CourseLesson::findOrFail($newLesson->id);
1200 1234
1201 1235 CourseHelper::copyLessonDocuments($lesson, $newLesson);
1202 1236
1237 + do_action('fluent_community/lesson/created', $newLesson, $newLesson->topic);
1203 1238 do_action('fluent_community/lesson/duplicated', $newLesson, $lesson);
1204 1239
1205 1240 return [
1206 1241 'message' => __('Lesson has been duplicated successfully.', 'fluent-community'),