Forum Replies Created
-
x8smileParticipantMake sure to set your email address in the env file 🙂
x8smileParticipantHi,
It’s been awhile and there is no update for Teachify. Can you please add these feature:
1. Manually add student to the course
2. Edit so the Student can see their progress report (with Student report plugin)
3. Change Certificate design
4. Auto updating time and description of course
5. More template
6. Edit and delete comment ?
7. Student can only download their certificate after complete %percentage of the course in ACP?
x8smileParticipantincase you still want to use Teachify, I can help you with some fee 😉
Check it out: https://vdemy.vn
x8smileParticipantyeah, better get your money back and switch to other platform. I see you have already switched to Academy LMS.
x8smileParticipant//Mark, If an user is Super Admin.
if ( Auth::check() ){
if ( $user->isAdmin ){
$isOpen = $user->isAdmin();
}
}Bring these code so admin can check pending course I think.
x8smileParticipantThis course should be this:
//Mark, If an user is Super Admin.
if ( Auth::check() ){
if ( $user->isAdmin ){
$isOpen = $user->isAdmin();
}
}
x8smileParticipantThat properly cause by your Stripe API. Make sure to enable and make the gateway live on Stripe side.
I dont use these gateway so not sure.
x8smileParticipantFind and remove this code:
` //Mark, If an user is Super Admin.
if ( Auth::check() ){
$isOpen = $user->isAdmin();
}`app/Http/Controllers/CourseController.php
x8smileParticipantAll problems have been fixed. thanks
x8smileParticipantYeah, we all think that. But the author did not fix this 😀
x8smileParticipantOr simply remove this from your code:
//Mark, If an user is Super Admin. if ( Auth::check() ){ $isOpen = $user->isAdmin(); }
x8smileParticipantJust replace your app/Http/Controllers/CourseController.php with this:
<?php namespace App\Http\Controllers; use App\AssignmentSubmission; use App\Attachment; use App\Category; use App\Course; use App\Review; use App\Section; use App\Content; use App\User; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; class CourseController extends Controller { /** * @return string * * View Course */ public function view($slug){ $course = Course::whereSlug($slug)->with('sections', 'sections.items', 'sections.items.attachments')->first(); if ( ! $course){ abort(404); } $user = Auth::user(); if ( $course->status != 1){ if ( ! $user || ! $user->isInstructorInCourse($course->id)){ abort(404); } } $title = $course->title; $isEnrolled = false; if (Auth::check()){ $user = Auth::user(); $enrolled = $user->isEnrolled($course->id); if ($enrolled){ $isEnrolled = $enrolled; } } return view(theme('course'), compact('course', 'title', 'isEnrolled')); } /** * @param $slug * @param $lecture_id * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View * * View lecture in full width mode. */ public function lectureView($slug, $lecture_id){ $lecture = Content::find($lecture_id); $course = $lecture->course; $title = $lecture->title; $isEnrolled = false; $isOpen = (bool) $lecture->is_preview; $user = Auth::user(); if ($course->paid && $user){ $isEnrolled = $user->isEnrolled($course->id); if ($course->paid && $isEnrolled){ $isOpen = true; } }elseif ($course->free){ if ($course->require_enroll && $user){ $isEnrolled = $user->isEnrolled($course->id); if ($isEnrolled){ $isOpen = true; } }elseif ($course->require_login){ if ($user) $isOpen = true; }else{ $isOpen = true; } } if ($lecture->drip->is_lock){ $isOpen = false; } return view(theme('lecture'), compact('course', 'title', 'isEnrolled', 'lecture', 'isOpen')); } public function assignmentView($slug, $assignment_id){ $assignment = Content::find($assignment_id); $course = $assignment->course; $title = $assignment->title; $has_submission = $assignment->has_submission; $isEnrolled = false; if (Auth::check()){ $user = Auth::user(); $isEnrolled = $user->isEnrolled($course->id); } return view(theme('assignment'), compact('course', 'title', 'isEnrolled', 'assignment', 'has_submission')); } public function assignmentSubmitting(Request $request, $slug, $assignment_id){ $user = Auth::user(); $user_id = $user->id; $assignment = Content::find($assignment_id); $submission = $assignment->has_submission; if ($submission){ if ($submission->status === 'submitting'){ $submission->text_submission = clean_html($request->assignment_text); $submission->status = 'submitted'; $submission->save(); complete_content($assignment, $user); /** * Save Attachments if any * * @todo, check attachment size, if exceed, delete those attachments */ $attachments = array_filter( (array) $request->assignment_attachments); if (is_array($attachments) && count($attachments) ){ foreach ($attachments as $media_id){ $hash = strtolower(str_random(13).substr(time(),4).str_random(13)); Attachment::create(['assignment_submission_id' => $submission->id, 'user_id' => $user_id, 'media_id' => $media_id, 'hash_id' => $hash ]); } } } }else { $course = $assignment->course; $data = [ 'user_id' => $user_id, 'course_id' => $course->id, 'assignment_id' => $assignment_id, 'status' => 'submitting', ]; AssignmentSubmission::create($data); } return redirect()->back(); } public function create(){ $title = __t('create_new_course'); $categories = Category::parent()->get(); return view(theme('dashboard.courses.create_course'), compact('title', 'categories')); } public function store(Request $request){ $rules = [ 'title' => 'required', 'category_id' => 'required', 'topic_id' => 'required', ]; $this->validate($request, $rules); $user_id = Auth::user()->id; $slug = unique_slug($request->title); $now = Carbon::now()->toDateTimeString(); $category = Category::find($request->category_id); $data = [ 'user_id' => $user_id, 'title' => clean_html($request->title), 'slug' => $slug, 'short_description' => clean_html($request->short_description), 'price_plan' => 'free', 'category_id' => $request->topic_id, 'parent_category_id' => $category->category_id, 'second_category_id' => $category->id, 'thumbnail_id' => $request->thumbnail_id, 'level' => $request->level, 'last_updated_at' => $now, ]; /** * save video data */ $video_source = $request->input('video.source'); if ($video_source === '-1'){ $data['video_src'] = null; }else{ $data['video_src'] = json_encode($request->video); } $course = Course::create($data); $now = Carbon::now()->toDateTimeString(); if ($course){ $course->instructors()->attach($user_id, ['added_at' => $now]); } return redirect(route('edit_course_information', $course->id)); } public function information($course_id){ $title = __t('information'); $course = Course::find($course_id); if ( ! $course || ! $course->i_am_instructor){ abort(404); } $categories = Category::parent()->get(); $topics = Category::whereCategoryId($course->second_category_id)->get(); return view(theme('dashboard.courses.information'), compact('title', 'course', 'categories', 'topics')); } public function informationPost( Request $request, $course_id){ $rules = [ 'title' => 'required|max:120', 'short_description' => 'max:220', 'category_id' => 'required', 'topic_id' => 'required', ]; $this->validate($request, $rules); $course = Course::find($course_id); if ( ! $course || ! $course->i_am_instructor){ abort(404); } $category = Category::find($request->category_id); $data = [ 'title' => clean_html($request->title), 'short_description' => clean_html($request->short_description), 'description' => clean_html($request->description), 'benefits' => clean_html($request->benefits), 'requirements' => clean_html($request->requirements), 'thumbnail_id' => $request->thumbnail_id, 'category_id' => $request->topic_id, 'parent_category_id' => $category->category_id, 'second_category_id' => $category->id, 'level' => $request->level, ]; /** * save video data */ $video_source = $request->input('video.source'); if ($video_source === '-1'){ $data['video_src'] = null; }else{ $data['video_src'] = json_encode($request->video); } $course->update($data); if ($request->save === 'save_next') return redirect(route('edit_course_curriculum', $course_id)); return redirect()->back(); } public function curriculum($course_id){ $title = __t('curriculum'); $course = Course::find($course_id); if ( ! $course || ! $course->i_am_instructor){ abort(404); } return view(theme('dashboard.courses.curriculum'), compact('title', 'course')); } public function newSection($course_id){ $title = __t('curriculum'); $course = Course::find($course_id); return view(theme('dashboard.courses.new_section'), compact('title', 'course')); } public function newSectionPost(Request $request, $course_id){ $rules = [ 'section_name' => 'required', ]; $this->validate($request, $rules); Section::create([ 'course_id' => $course_id, 'section_name' => clean_html($request->section_name) ] ); return redirect(route('edit_course_curriculum', $course_id)); } /** * @param Request $request * @param $id * @throws \Illuminate\Validation\ValidationException * * Update the section */ public function updateSection(Request $request, $id){ $rules = [ 'section_name' => 'required', ]; $this->validate($request, $rules); Section::whereId($id)->update(['section_name' => clean_html($request->section_name)]); } public function deleteSection(Request $request){ if(config('app.is_demo')) return ['success' => false, 'msg' => __t('demo_restriction')]; $section = Section::find($request->section_id); $course = $section->course; Content::query()->where('section_id', $request->section_id)->delete(); $section->delete(); $course->sync_everything(); return ['success' => true]; } public function newLecture(Request $request, $course_id){ $rules = [ 'title' => 'required' ]; $validation = Validator::make($request->input(), $rules); if ($validation->fails()){ $errors = $validation->errors()->toArray(); $error_msg = "<div class='alert alert-danger mb-3'>"; foreach ($errors as $error){ $error_msg .= "<p class='m-0'>{$error[0]}</p>"; } $error_msg .= "</div>"; return ['success' => false, 'error_msg' => $error_msg]; } $user_id = Auth::user()->id; $lesson_slug = unique_slug($request->title, 'Content'); $sort_order = next_curriculum_item_id($course_id); $data = [ 'user_id' => $user_id, 'course_id' => $course_id, 'section_id' => $request->section_id, 'title' => clean_html($request->title), 'slug' => $lesson_slug, 'text' => clean_html($request->description), 'item_type' => 'lecture', 'status' => 1, 'sort_order' => $sort_order, 'is_preview' => $request->is_preview, ]; $lecture = Content::create($data); $lecture->save_and_sync(); return ['success' => true, 'item_id' => $lecture->id]; } public function loadContents(Request $request){ $section = Section::find($request->section_id); $html = view_template_part('dashboard.courses.section-items', compact('section')); return ['success' => true, 'html' => $html]; } public function updateLecture(Request $request, $course_id, $item_id){ $rules = [ 'title' => 'required' ]; $validation = Validator::make($request->input(), $rules); if ($validation->fails()){ $errors = $validation->errors()->toArray(); $error_msg = "<div class='alert alert-danger mb-3'>"; foreach ($errors as $error){ $error_msg .= "<p class='m-0'>{$error[0]}</p>"; } $error_msg .= "</div>"; return ['success' => false, 'error_msg' => $error_msg]; } $user_id = Auth::user()->id; $lesson_slug = unique_slug($request->title, 'Content', $item_id); $data = [ 'title' => clean_html($request->title), 'slug' => $lesson_slug, 'text' => clean_html($request->description), 'is_preview' => clean_html($request->is_preview), ]; /** * save video data */ $video_source = $request->input('video.source'); if ($video_source === '-1'){ $data['video_src'] = null; }else{ $data['video_src'] = json_encode($request->video); } $item = Content::find($item_id); $item->save_and_sync($data); /** * Save Attachments if any */ $attachments = array_filter( (array) $request->attachments); if (is_array($attachments) && count($attachments) ){ foreach ($attachments as $media_id){ $hash = strtolower(str_random(13).substr(time(),4).str_random(13)); Attachment::create(['belongs_course_id' => $item->course_id, 'content_id' => $item->id, 'user_id' => $user_id, 'media_id' => $media_id, 'hash_id' => $hash ]); } } return ['success' => true]; } public function editItem(Request $request){ $item_id = $request->item_id; $item = Content::find($item_id); $form_html = ''; if ($item->item_type === 'lecture'){ $form_html = view_template_part( 'dashboard.courses.edit_lecture_form', compact('item')); }elseif ($item->item_type === 'quiz'){ $form_html = view_template_part( 'dashboard.courses.quiz.edit_quiz', compact('item')); }elseif ($item->item_type === 'assignment'){ $form_html = view_template_part( 'dashboard.courses.edit_assignment_form', compact('item')); } return ['success' => true, 'form_html' => $form_html]; } public function deleteItem(Request $request){ $item_id = $request->item_id; Content::destroy($item_id); return ['success' => true]; } public function pricing($course_id){ $title = __t('course_pricing'); $course = Course::find($course_id); if ( ! $course || ! $course->i_am_instructor){ abort(404); } return view(theme('dashboard.courses.pricing'), compact('title', 'course')); } public function pricingSet(Request $request, $course_id){ if ($request->price_plan == 'paid'){ $rules = [ 'price' => 'required|numeric', ]; if ($request->sale_price){ $rules['sale_price'] = 'numeric'; } $this->validate($request, $rules); } $course = Course::find($course_id); if ( ! $course || ! $course->i_am_instructor){ abort(404); } $data = [ 'price_plan' => $request->price_plan, 'price' => clean_html($request->price), 'sale_price' => clean_html($request->sale_price), 'require_login' => $request->require_login, 'require_enroll' => $request->require_enroll, ]; $course->update($data); return back(); } public function drip($course_id){ $title = __t('drip_content'); $course = Course::find($course_id); if ( ! $course || ! $course->i_am_instructor){ abort(404); } return view(theme('dashboard.courses.drip'), compact('title', 'course')); } public function dripPost(Request $request, $course_id){ $sections = $request->section; foreach ($sections as $sectionId => $section){ Section::whereId($sectionId)->update(array_except($section, 'content')); $contents = array_get($section, 'content'); foreach ($contents as $contentId => $content){ Content::whereId($contentId)->update(array_except($content, 'content')); } } return back()->with('success', __t('drip_preference_saved')); } public function publish($course_id){ $title = __t('publish_course'); $course = Course::find($course_id); if ( ! $course || ! $course->i_am_instructor){ abort(404); } return view(theme('dashboard.courses.publish'), compact('title', 'course')); } public function publishPost(Request $request, $course_id){ $course = Course::find($course_id); if ( ! $course || ! $course->i_am_instructor){ abort(404); } if ($request->publish_btn == 'publish'){ if (get_option("lms_settings.instructor_can_publish_course")){ $course->status = 1; }else{ $course->status = 2; } }elseif ($request->publish_btn == 'unpublish'){ $course->status = 4; } $course->save(); return back(); } /** * Course Free Enroll */ public function freeEnroll(Request $request){ $course_id = $request->course_id; if ( ! Auth::check()){ return redirect(route('login')); } $user = Auth::user(); $course = Course::find($course_id); $isEnrolled = $user->isEnrolled($course_id); if ( ! $isEnrolled){ $carbon = Carbon::now()->toDateTimeString(); $user->enrolls()->attach($course_id, ['status' => 'success', 'enrolled_at' => $carbon ]); $user->enroll_sync(); } return redirect(route('course', $course->slug)); } /** * Content Complete, such as Lecture * return to next after complete * stay current page if there is no next. */ public function contentComplete($content_id){ $content = Content::find($content_id); $user = Auth::user(); complete_content($content, $user); $go_content = $content->next; if ( ! $go_content){ $go_content = $content; } return redirect(route('single_'.$go_content->item_type, [$go_content->course->slug, $go_content->id ] )); } public function complete(Request $request, $course_id){ $user = Auth::user(); $user->complete_course($course_id); return back(); } public function attachmentDownload($hash){ $attachment = Attachment::whereHashId($hash)->first(); if ( ! $attachment || ! $attachment->media){ abort(404); } /** * If Assignment Submission Attachment, download it right now */ if ($attachment->assignment_submission_id){ if (Auth::check()){ return $this->forceDownload($attachment->media); } abort(404); } $item = $attachment->belongs_item; if ($item && $item->item_type === 'lecture' && $item->is_preview){ return $this->forceDownload($attachment->media); } if ( ! Auth::check()){ abort(404); } $user = Auth::user(); $course = $attachment->course; if ( ! $user->isEnrolled($course->id)){ abort(404); } return $this->forceDownload($attachment->media); } public function forceDownload($media){ $source = get_option('default_storage'); $slug_ext = $media->slug_ext; if (substr($media->mime_type, 0, 5) == 'image') { $slug_ext = 'images/'.$slug_ext; } $path = ''; if ($source == 'public'){ $path = ROOT_PATH."/uploads/{$slug_ext}"; }elseif ($source == 's3'){ $path = \Illuminate\Support\Facades\Storage::disk('s3')->url("uploads/".$slug_ext); } return response()->download($path); } public function writeReview(Request $request, $id){ if ($request->rating_value < 1){ return back(); } if ( ! $id){ $id = $request->course_id; } $user = Auth::user(); $data = [ 'user_id' => $user->id, 'course_id' => $id, 'review' => clean_html($request->review), 'rating' => $request->rating_value, 'status' => 1, ]; $review = has_review($user->id, $id); if ( ! $review){ $review = Review::create($data); } $review->save_and_sync($data); return back(); } /** * My Courses page from Dashboard */ public function myCourses(){ $title = __t('my_courses'); return view(theme('dashboard.my_courses'), compact('title')); } public function myCoursesReviews(){ $title = __t('my_courses_reviews'); return view(theme('dashboard.my_courses_reviews'), compact('title')); } }
x8smileParticipantThere is a problem with 2.3.0 update. Just reupload the file from 2.0 to fix 🙂
x8smileParticipantHi,
After update to 2.3.0, the author now can not view content of their courses. Keep going back to enroll to the course button. Please check
x8smileParticipantSo the old css and 2.2.0 version doesnt change ?