first commit

This commit is contained in:
baghizadizn 2025-10-30 10:32:19 +07:00
commit 47cf6d2733
14726 changed files with 684629 additions and 0 deletions

18
.editorconfig Normal file
View File

@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4

61
.env Normal file
View File

@ -0,0 +1,61 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:Cz+OOFAvh0Q7qr7e8OLuPfv2o4v/9b2Q7EPGJhzmjww=
APP_DEBUG=
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=academy_lite_1.0
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_HOST=
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
RAZORPAY_KEY=rzp_test_J60bqBOi1z1aF5
RAZORPAY_SECRET=uk935K7p4j96UCJgHK8kAU4q

58
.env.example Normal file
View File

@ -0,0 +1,58 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_HOST=
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

11
.gitattributes vendored Normal file
View File

@ -0,0 +1,11 @@
* text=auto eol=lf
*.blade.php diff=html
*.css diff=css
*.html diff=html
*.md diff=markdown
*.php diff=php
/.github export-ignore
CHANGELOG.md export-ignore
.styleci.yml export-ignore

30
.gitignore vendored Normal file
View File

@ -0,0 +1,30 @@
/.phpunit.cache
/node_modules
/public/build
/public/hot
/public/storage
/public/uploads/*.jpg
/public/uploads/*.png
/public/uploads/*.mp4
/public/uploads/*.jpg
/public/uploads/*.png
/public/uploads/*.mp4
/public/uploads
/resources/views/components/home_made_by_builder
/storage/*.key
/vendor
.env.backup
.env.production
.phpunit.result.cache
Homestead.json
Homestead.yaml
auth.json
npm-debug.log
yarn-error.log
/.fleet
/.idea
/.vscode
# Ignore macOS .DS_Store files
.DS_Store
/config/database.php

21
.htaccess Normal file
View File

@ -0,0 +1,21 @@
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

68
EXAMPLES.html Normal file
View File

@ -0,0 +1,68 @@
<!-- Title -->
<div class="mainSection-title ps-2px d-flex justify-content-between">
<h4>{{get_phrase('Dashboard')}}</h4>
<a class="btn btn-primary" href="#"> <i class="fi-sr-plus text-10px"></i> {{get_phrase('Create a new category')}}</a>
</div>
<!-- Form -->
<form action="{{route('admin.category.store')}}" method="post" enctype="multipart/form-data">
@CSRF
<input type="hidden" name="parent_id" value="{{$parent_id}}">
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="row">
<div class="col-12">
<div class="mb-3">
<label for="category_name" class="eForm-label">{{get_phrase('Category Name')}}</label>
<input type="text" name="title" class="form-control eForm-control" id="category_name" placeholder="{{get_phrase('Enter your category name')}}" aria-label="{{get_phrase('Enter your category name')}}"/>
</div>
<div class="mb-3">
<label for="icon-picker" class="eForm-label">{{get_phrase('Pick Your Icon')}}</label>
<input type="text" name="icon" class="form-control eForm-control icon-picker" id="icon-picker" placeholder="{{get_phrase('Pick your category icon')}}" aria-label="{{get_phrase('Pick your category icon')}}"/>
</div>
<div class="mb-3">
<label for="thumbnail" class="eForm-label">{{get_phrase('Choose category thumbnail')}}</label>
<input type="file" name="thumbnail" class="form-control eForm-control-file" id="thumbnail" accept="image/*" />
</div>
<div class="mb-2">
<button class="btn btn-primary">{{get_phrase('Submit')}}</button>
</div>
</div>
</div>
</form>
<form>
<div class="row">
<div class="col-12">
<div class="eSection-wrap">
<div class="title">
<h3>Textual Inputs</h3>
</div>
<div class="eMain">
<div class="row">
<div class="col-md-12 pb-3">
<div class="eForm-layouts">
<div class="fpb-7">
<label for="category_name" class="eForm-label">{{get_phrase('Category Name')}}</label>
<input type="email" class="form-control eForm-control" id="category_name" placeholder="{{get_phrase('Enter your category name')}}" aria-label="{{get_phrase('Enter your category name')}}"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>

67
README.md Normal file
View File

@ -0,0 +1,67 @@
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
<p align="center">
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
</p>
## About Laravel
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, powerful, and provides tools required for large, robust applications.
## Learning Laravel
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
## Laravel Sponsors
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
### Premium Partners
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Cubet Techno Labs](https://cubettech.com)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[Many](https://www.many.co.uk)**
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
- **[DevSquad](https://devsquad.com)**
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
- **[OP.GG](https://op.gg)**
- **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)**
- **[Lendio](https://lendio.com)**
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
# academy-laravel

27
app/Console/Kernel.php Normal file
View File

@ -0,0 +1,27 @@
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* Define the application's command schedule.
*/
protected function schedule(Schedule $schedule): void
{
// $schedule->command('inspire')->hourly();
}
/**
* Register the commands for the application.
*/
protected function commands(): void
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of exception types with their corresponding custom log levels.
*
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
*/
protected $levels = [
//
];
/**
* A list of the exception types that are not reported.
*
* @var array<int, class-string<\Throwable>>
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed to the session on validation exceptions.
*
* @var array<int, string>
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*/
public function register(): void
{
$this->reportable(function (Throwable $e) {
//
});
}
function render($request, Throwable $exception)
{
if ($this->isHttpException($exception)) {
if ($exception->getStatusCode() == 404) {
return response()->view('errors.404');
}
if ($exception->getStatusCode() == 500) {
return response()->view('errors.500');
}else{
return response()->view('errors.500');
}
}
return parent::render($request, $exception);
}
}

688
app/Helpers/Api_helper.php Normal file
View File

@ -0,0 +1,688 @@
<?php
// import facade
use App\Models\Addon;
use App\Models\NotificationSetting;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use App\Models\{CartItem, Course, Category, Review};
//Api related
if (!function_exists('enroll_history')) {
function enroll_history($course_id = "", $distinct_data = false)
{
if ($distinct_data) {
$enroll_hoistory = DB::table('enrollments')->select('user_id')
->distinct()
->where('course_id', $course_id)
->get();
return $enroll_hoistory;
} else {
if ($course_id > 0) {
return DB::table('enrollments')->where('course_id', $course_id)->get();
} else {
return DB::table('enrollments')->get();
}
}
}
}
// Return require course data
if (!function_exists('course_data')) {
function course_data($courses = array())
{
foreach ($courses as $key => $course) {
$courses[$key]->requirements = json_decode($course->requirements) == null ? [] : json_decode($course->requirements);
$courses[$key]->outcomes = json_decode($course->outcomes) == null ? [] : json_decode($course->outcomes);
$courses[$key]->faqs = json_decode($course->faqs) == null ? [] : json_decode($course->faqs);
$courses[$key]->instructors = json_decode($course->instructor_ids) == null ? [] : json_decode($course->instructor_ids);
$courses[$key]->thumbnail = get_photo('course_thumbnail', $course->thumbnail);
$courses[$key]->banner = get_photo('course_banner', $course->banner);
// $courses[$key]->preview = get_photo('course_preview', $courses[$key]->preview);
if (strpos($courses[$key]->preview, 'youtube.com') !== false || strpos($courses[$key]->preview, 'youtu.be') !== false) {
} elseif (strpos($courses[$key]->preview, 'vimeo.com') !== false) {
} elseif (strpos($courses[$key]->preview, 'drive.google.com') !== false) {
} elseif (strpos($courses[$key]->preview, '.mp4') !== false && strpos($courses[$key]->preview, 'http') !== false) {
} else {
$courses[$key]->preview = url('public/' . $course->preview);
}
// $courses[$key]->enable_drip_content = $course->enable_drip_content;
if ($course->is_paid == 0) {
$courses[$key]->price = 'Free';
} else {
if ($course->discount_flag == 1) {
$courses[$key]->price = currency($course->discounted_price);
$courses[$key]->price_cart = $course->discounted_price;
} else {
$courses[$key]->price_cart = $course->price;
$courses[$key]->price = currency($course->price);
}
}
// // $total_rating = get_ratings('course', $course->id, true)->row()->rating;
// // $number_of_ratings = get_ratings('course', $course->id)->num_rows();
// if ($number_of_ratings > 0) {
// $courses[$key]->rating = ceil($total_rating / $number_of_ratings);
// } else {
// $courses[$key]->rating = 0;
// }
// $courses[$key]->number_of_ratings = $number_of_ratings;
$instructor_details = get_user_info($course->user_id);
$courses[$key]->instructor_name = $instructor_details->name;
$courses[$key]->instructor_image = url('public/' . $instructor_details->photo);
$courses[$key]->total_enrollment = enroll_history($course->id)->count();
$courses[$key]->shareable_link = url('course/' . slugify($course->title));
$review = Review::where('course_id', $course->id)->get();
$total = $review->count();
$rating = array_sum(array_column($review->toArray(), 'rating'));
$average_rating = 0.0;
if ($total != 0.0) {
$average_rating = round($rating / $total);
}
$courses[$key]->total_reviews = $total;
// $courses[$key]->average_rating = $course->average_rating;
$courses[$key]->average_rating = number_format($average_rating, 1, '.', '');
}
return $courses;
}
}
if (!function_exists('get_photo')) {
function get_photo($type, $identifier)
{ // type is the flag to realize whether it is course, category or user image. For course, user image Identifier is id but for category Identifier is image name
if ($type == 'user_image') {
if (file_exists('public/' . $identifier) && $identifier != "") {
return url('public/' . $identifier);
} else {
return url('public/assets/upload/users/student/placeholder/placeholder.png');
}
} elseif ($type == 'course_thumbnail') {
if (file_exists('public/' . $identifier) && $identifier != "") {
return url('public/' . $identifier);
} else {
return url('public/uploads/course-thumbnail/placeholder/placeholder.png');
}
} elseif ($type == 'course_banner') {
if (file_exists('public/' . $identifier) && $identifier != "") {
return url('public/' . $identifier);
} else {
return url('public/uploads/course-banner/placeholder/placeholder.png');
}
} elseif ($type == 'course_preview') {
if (file_exists('public/' . $identifier) && $identifier != "") {
return url('public/' . $identifier);
} else {
return url('public/uploads/course-preview/placeholder/placeholder.png');
}
} elseif ($type == 'category_thumbnail') {
if (file_exists('public/' . $identifier) && $identifier != "") {
return url('public/' . $identifier);
} else {
return url('public/uploads/category-thumbnail/placeholder/placeholder.png');
}
}
}
}
if (!function_exists('get_category_wise_courses')) {
function get_category_wise_courses($category_id = "")
{
// $category_details = get_category_details_by_id($category_id);
$courses = Course::where('category_id', $category_id)->where('status', 'active')->get();
return $courses;
}
}
if (!function_exists('get_category_details_by_id')) {
function get_category_details_by_id($id)
{
return DB::table('categories')->where('id', $id)->get();
}
}
if (!function_exists('sub_categories')) {
// Get sub categories
function sub_categories($parent_category_id)
{
$response = array();
$categories = DB::table('categories')->where('parent_id', $parent_category_id)->get();
foreach ($categories as $key => $category) {
$number_of_courses = DB::table('courses')->where('status', 'active')->where('category_id', $category->id)->count();
$category->number_of_courses = $number_of_courses;
$category->thumbnail = get_photo('category_thumbnail', $category->thumbnail);
$response[] = $category;
}
return $response;
}
}
if (!function_exists('course_details_by_id')) {
// Get sub categories
function course_details_by_id($user_id = "", $course_id = "")
{
$course_details = get_course_by_id($course_id);
$response = course_data($course_details);
foreach ($response as $key => $resp) {
$response[$key]->sections = sections($course_id);
$response[$key]->is_wishlisted = is_added_to_wishlist($user_id, $course_id);
$response[$key]->is_purchased = is_purchased($user_id, $course_id);
$response[$key]->is_cart = is_cart_item($user_id, $course_id);
$response[$key]->includes = array(
get_total_duration_of_lesson_by_course_id($course_id) . ' On demand videos',
get_lessons('course', $course_id)->count() . ' Lessons',
'High quality videos',
'Life time access'
);
}
return $response;
}
}
function get_course_by_id($course_id = "")
{
return DB::table('courses')->where('id', $course_id)->get();
}
function is_added_to_wishlist($user_id = 0, $course_id = "")
{
if ($user_id > 0) {
$wishlists = array();
$wishlist_check = DB::table('wishlists')->where('user_id', $user_id)->where('course_id', $course_id)->first();
if (!empty($wishlist_check)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
// function is_purchased($user_id = 0, $course_id = "")
// {
// // 0 represents Not purchased, 1 represents Purchased, 2 represents Pending
// if ($user_id > 0) {
// if (enroll_status($course_id, $user_id) == 'valid') {
// return true;
// } else {
// return false;
// }
// } else {
// return false;
// }
// }
// function is_purchased($user_id = 0, $course_id = "")
// {
// // 0 represents not purchased, 1 represents purchased
// if ($user_id > 0) {
// $status = enroll_status($course_id, $user_id);
// return $status === 'valid'; // Return true only if status is 'valid'
// } else {
// return false; // User ID is not valid
// }
// }
if (!function_exists('is_purchased')) {
function is_purchased($user_id = 0, $course_id = "")
{
if ($user_id > 0) {
$status = enroll_status_api($course_id, $user_id);
if ($status == true) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}
if (!function_exists('enroll_status_api')) {
function enroll_status_api($course_id = "", $user_id = "")
{
$enrolled_history = DB::table('enrollments')
->where('user_id', $user_id)
->where('course_id', $course_id)
->first();
if ($enrolled_history) {
return true;
} else {
return false;
}
}
}
function get_total_duration_of_lesson_by_course_id($course_id)
{
$total_duration = 0;
$lessons = get_lessons('course', $course_id);
foreach ($lessons as $lesson) {
if ($lesson->lesson_type != "other" && $lesson->lesson_type != "text") {
$time_array = !empty($lesson->duration) ? explode(':', $lesson->duration) : explode(':', '00:00:00');
$hour_to_seconds = $time_array[0] * 60 * 60;
$minute_to_seconds = $time_array[1] * 60;
$seconds = $time_array[2];
$total_duration += $hour_to_seconds + $minute_to_seconds + $seconds;
}
}
// return gmdate("H:i:s", $total_duration).' '.get_phrase('hours');
$hours = floor($total_duration / 3600);
$minutes = floor(($total_duration % 3600) / 60);
$seconds = $total_duration % 60;
return sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds) . ' ' . get_phrase('hours');
}
if (!function_exists('course_progress')) {
function course_progress($course_id = "", $user_id = "", $return_type = "")
{
$watch_history = DB::table('watch_histories')->where('student_id', $user_id)->where('course_id', $course_id)->first();
$total_lessons = DB::table('lessons')->where('course_id', $course_id)->count();
if (!empty($watch_history)) {
$completed_lessons = json_decode($watch_history->completed_lesson, true);
// Check if completed_lesson is an array and is not empty
if (is_array($completed_lessons) && !empty($completed_lessons)) {
$total_completed_lesson = count($completed_lessons);
$watch_history->course_progress = ($total_completed_lesson / $total_lessons) * 100;
} else {
$total_completed_lesson = 0;
$watch_history->course_progress = 0; // Ensure course_progress is set to 0 if no lessons are completed
}
} else {
$total_completed_lesson = 0;
}
if ($return_type == "completed_lesson_ids") {
// Return completed_lesson as an array, or an empty array if it's empty
return is_array($completed_lessons) ? $completed_lessons : [];
}
if (!empty($watch_history) && $watch_history->course_progress > 0) {
return $watch_history->course_progress;
} else {
return 0;
}
}
}
if (!function_exists('lesson_progress_api')) {
function lesson_progress_api($lesson_id = "", $user_id = "", $course_id = "")
{
if ($course_id == "") {
$course_id = DB::table('lessons')->where('id', $lesson_id)->value('course_id');
}
$query = DB::table('watch_histories')->where('student_id', $user_id)->where('course_id', $course_id)->first();
if (!empty($query)) {
$lesson_ids = json_decode($query->completed_lesson, true);
if (is_array($lesson_ids) && in_array($lesson_id, $lesson_ids)) {
return 1;
} else {
return 0;
}
}
}
}
if (!function_exists('get_lessons')) {
function get_lessons($type = "", $id = "")
{
$lessons = array();
if ($type == "course") {
$lessons = DB::table('lessons')->where('course_id', $id)->orderBy("sort", "asc")->get();
} elseif ($type == "section") {
$lessons = DB::table('lessons')->where('section_id', $id)->orderBy("sort", "asc")->get();
} elseif ($type == "lesson") {
$lessons = DB::table('lessons')->where('id', $id)->orderBy("sort", "asc")->get();
} else {
$lessons = DB::table('lessons')->orderBy("sort", "asc")->get();
}
return $lessons;
}
}
if (!function_exists('update_watch_history_manually')) {
// code of mark this lesson as completed
function update_watch_history_manually($lesson_id = "", $course_id = "", $user_id = "")
{
$is_completed = 0;
$query = DB::table('watch_histories')->where('course_id', $course_id)->where('student_id', $user_id)->first();
$course_progress = course_progress($course_id, $user_id);
if (!empty($query)) {
$lesson_ids = json_decode($query->completed_lesson, true);
if (!is_array($lesson_ids))
$lesson_ids = array();
if (!in_array($lesson_id, $lesson_ids)) {
array_push($lesson_ids, $lesson_id);
$total_lesson = DB::table('lessons')->where('course_id', $course_id)->get();
$course_progress = (100 / count($total_lesson)) * count($lesson_ids);
if ($course_progress >= 100 && $query->completed_date == null) {
$completed_date = time();
} else {
$completed_date = $query->completed_date;
}
DB::table('watch_histories')->where('id', $query->id)->update([
'completed_lesson' => json_encode($lesson_ids),
'completed_date' => $completed_date,
]);
$is_completed = 1;
} else {
if (($key = array_search($lesson_id, $lesson_ids)) !== false) {
unset($lesson_ids[$key]);
}
$total_lesson = DB::table('lessons')->where('course_id', $course_id)->get();
$course_progress = (100 / count($total_lesson)) * count($lesson_ids);
if ($course_progress >= 100 && $query->completed_date == null) {
$completed_date = time();
} else {
$completed_date = $query->completed_date;
}
DB::table('watch_histories')->where('id', $query->id)->update([
'completed_lesson' => json_encode($lesson_ids),
'completed_date' => $completed_date,
]);
$is_completed = 0;
}
} else {
$total_lesson = DB::table('lessons')->where('course_id', $course_id)->get();
$course_progress = (100 / count($total_lesson));
$insert_data['course_id'] = $course_id;
$insert_data['student_id'] = $user_id;
$insert_data['completed_lesson'] = json_encode(array($lesson_id));
$insert_data['watching_lesson_id'] = $lesson_id;
DB::table('watch_histories')->insert($insert_data);
}
return json_encode(array('lesson_id' => $lesson_id, 'course_progress' => round($course_progress), 'is_completed' => $is_completed));
}
}
// if (!function_exists('update_watch_history_manually')) {
// // code of mark this lesson as completed
// function update_watch_history_manually($lesson_id = "", $course_id = "", $user_id = "")
// {
// $is_completed = 0;
// $query = DB::table('watch_histories')->where('course_id', $course_id)->where('student_id', $user_id)->first();
// $course_progress = course_progress($course_id, $user_id);
// if (!empty($query)) {
// $lesson_ids = json_decode($query->completed_lesson, true);
// if (!is_array($lesson_ids))
// $lesson_ids = array();
// if (!in_array($lesson_id, $lesson_ids)) {
// array_push($lesson_ids, $lesson_id);
// $total_lesson = DB::table('lessons')->where('course_id', $course_id)->get();
// $course_progress = (100 / count($total_lesson)) * count($lesson_ids);
// if ($course_progress >= 100 && $query->completed_date == null) {
// $completed_date = time();
// } else {
// $completed_date = $query->completed_date;
// }
// DB::table('watch_histories')->where('id', $query->id)->update([
// 'completed_lesson' => json_encode($lesson_ids),
// 'completed_date' => $completed_date,
// ]);
// $is_completed = 1;
// } else {
// if (($key = array_search($lesson_id, $lesson_ids)) !== false) {
// unset($lesson_ids[$key]);
// }
// $total_lesson = DB::table('lessons')->where('course_id', $course_id)->get();
// $course_progress = (100 / count($total_lesson)) * count($lesson_ids);
// if ($course_progress >= 100 && $query->completed_date == null) {
// $completed_date = time();
// } else {
// $completed_date = $query->completed_date;
// }
// DB::table('watch_histories')->where('id', $query->id)->update([
// 'completed_lesson' => json_encode($lesson_ids),
// 'completed_date' => $completed_date,
// ]);
// $is_completed = 0;
// }
// } else {
// $total_lesson = DB::table('lessons')->where('course_id', $course_id)->get();
// $course_progress = (100 / count($total_lesson));
// $insert_data['course_id'] = $course_id;
// $insert_data['student_id'] = $user_id;
// $insert_data['completed_lesson'] = json_encode(array($lesson_id));
// $insert_data['watching_lesson_id'] = $lesson_id;
// DB::table('watch_histories')->create($insert_data);
// }
// return json_encode(array('lesson_id' => $lesson_id, 'course_progress' => round($course_progress), 'is_completed' => $is_completed));
// }
// }
function course_completion_data($course_id = "", $user_id = "")
{
$response = array();
$response['course_id'] = $course_id;
$response['number_of_lessons'] = get_lessons('course', $course_id)->count();
$response['number_of_completed_lessons'] = get_completed_number_of_lesson($user_id, 'course', $course_id);
$response['course_progress'] = round(course_progress($course_id, $user_id));
return $response;
}
if (!function_exists('get_completed_number_of_lesson')) {
function get_completed_number_of_lesson($user_id = "", $type = "", $id = "")
{
$counter = 0;
if ($type == 'section') {
$lessons = get_lessons('section', $id);
} else {
$lessons = get_lessons('course', $id);
}
foreach ($lessons as $key => $lesson) {
if (lesson_progress_api($lesson->id, $user_id)) {
$counter = $counter + 1;
}
}
return $counter;
}
}
//get all sections
function sections($course_id = "", $user_id = "")
{
$response = array();
$lesson_counter_starts = 0;
$lesson_counter_ends = 0;
$sections = api_get_section('course', $course_id);
foreach ($sections as $key => $section) {
$sections[$key]->lessons = section_wise_lessons($section->id, $user_id);
$sections[$key]->total_duration = str_replace(' Hours', "", get_total_duration_of_lesson_by_section_id($section->id));
if ($key == 0) {
$lesson_counter_starts = 1;
$lesson_counter_ends = count($sections[$key]->lessons);
} else {
$lesson_counter_starts = $lesson_counter_ends + 1;
$lesson_counter_ends = $lesson_counter_starts + count($sections[$key]->lessons);
}
$sections[$key]->lesson_counter_starts = $lesson_counter_starts;
$sections[$key]->lesson_counter_ends = $lesson_counter_ends;
if ($user_id > 0) {
$sections[$key]->completed_lesson_number = get_completed_number_of_lesson($user_id, 'section', $section->id);
} else {
$sections[$key]->completed_lesson_number = 0;
}
}
$response = add_user_validity($sections);
return $response;
}
function api_get_section($type_by, $id)
{
$sections = array();
if ($type_by == 'course') {
$sections = DB::table('sections')->where('course_id', $id)->orderBy("sort", "asc")->get();
} elseif ($type_by == 'section') {
$sections = DB::table('sections')->where('id', $id)->orderBy("sort", "asc")->get();
}
return $sections;
}
function section_wise_lessons($section_id = "", $user_id = "")
{
$response = array();
$lessons = get_lessons('section', $section_id);
foreach ($lessons as $key => $lesson) {
$response[$key]['id'] = $lesson->id;
$response[$key]['title'] = $lesson->title;
$response[$key]['duration'] = readable_time_for_humans($lesson->duration);
$response[$key]['course_id'] = $lesson->course_id;
$response[$key]['section_id'] = $lesson->section_id;
$response[$key]['video_type'] = ($lesson->video_type == "" ? "" : $lesson->video_type);
if ($lesson->lesson_type == 'system-video') {
$response[$key]['video_url'] = ($lesson->lesson_src == "" ? "" : url('/public/assets/upload/lesson_file/videos') . '/' . $lesson->lesson_src);
} else {
$response[$key]['video_url'] = ($lesson->lesson_src == "" ? "" : $lesson->lesson_src);
}
// $response[$key]['video_url_web'] = $lesson->video_url;
// $response[$key]['video_type_web'] = $lesson->video_type;
$response[$key]['lesson_type'] = $lesson->lesson_type;
$response[$key]['is_free'] = $lesson->is_free;
if ($lesson->lesson_type == 'text') {
$response[$key]['attachment'] = remove_js(htmlspecialchars_decode_($lesson->attachment));
} else {
$response[$key]['attachment'] = $lesson->attachment;
}
$response[$key]['attachment_url'] = $lesson->attachment ? url('/public/uploads/lesson_file/attachment') . '/' . $lesson->attachment : $lesson->attachment;
$response[$key]['attachment_type'] = $lesson->attachment_type;
$response[$key]['summary'] = remove_js(htmlspecialchars_decode_($lesson->summary));
if ($user_id > 0) {
$response[$key]['is_completed'] = lesson_progress_api($lesson->id, $user_id);
} else {
$response[$key]['is_completed'] = 0;
}
$response[$key]['user_validity'] = true;
}
return $response;
}
function add_user_validity($responses = array())
{
foreach ($responses as $key => $response) {
$responses[$key]->user_validity = true;
}
return $responses;
}
function get_total_duration_of_lesson_by_section_id($section_id)
{
$total_duration = 0;
$lessons = get_lessons('section', $section_id);
foreach ($lessons as $lesson) {
if ($lesson->lesson_type != "other" && $lesson->lesson_type != "text") {
$time_array = !empty($lesson->duration) ? explode(':', $lesson->duration) : explode(':', '00:00:00');
$hour_to_seconds = $time_array[0] * 60 * 60;
$minute_to_seconds = $time_array[1] * 60;
$seconds = $time_array[2];
$total_duration += $hour_to_seconds + $minute_to_seconds + $seconds;
}
}
//return gmdate("H:i:s", $total_duration).' '.get_phrase('hours');
$hours = floor($total_duration / 3600);
$minutes = floor(($total_duration % 3600) / 60);
$seconds = $total_duration % 60;
return sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds);
}
// Human readable time
if (!function_exists('readable_time_for_humans')) {
function readable_time_for_humans($duration)
{
if ($duration) {
$duration_array = explode(':', $duration);
$hour = $duration_array[0];
$minute = $duration_array[1];
$second = $duration_array[2];
if ($hour > 0) {
$duration = $hour . ' ' . get_phrase('hr') . ' ' . $minute . ' ' . get_phrase('min');
} elseif ($minute > 0) {
if ($second > 0) {
$duration = ($minute + 1) . ' ' . get_phrase('min');
} else {
$duration = $minute . ' ' . get_phrase('min');
}
} elseif ($second > 0) {
$duration = $second . ' ' . get_phrase('sec');
} else {
$duration = '00:00';
}
} else {
$duration = '00:00';
}
return $duration;
}
}
if (!function_exists('remove_js')) {
function remove_js($description = '')
{
return preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', "", $description);
}
}
if (!function_exists('is_cart_item')) {
function is_cart_item($user_id = "", $course_id = "")
{
$is_cart = CartItem::where('course_id', $course_id)
->where('user_id', $user_id)
->exists();
return $is_cart ? true : false;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,125 @@
<?php
namespace App\Http\Controllers\admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Knowledge_base;
use App\Models\Knowledge_base_topick;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
class ArticleController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$request->validate([
'title' => 'required | max:200',
'description'=> 'required'
]);
$article = new Knowledge_base_topick;
$article->topic_name = $request->title;
$article->description = $request->description;
$article->knowledge_base_id = $request->topick_id;
$done = $article->save();
if ($done) {
return redirect()->route('admin.articles',['id'=> $request->topick_id])->with('success', get_phrase('article saved.'));
} else {
return redirect()->route('admin.articles',['id'=> $request->topick_id])->with('error', get_phrase('article not saved.'));
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
$articleTitle = Knowledge_base::where('id', $id)->first();
if (!$articleTitle) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$articles = Knowledge_base_topick::where('knowledge_base_id', $id)->orderBy('updated_at', 'desc')->paginate(10);
return view("admin.articles.index" , ["articleTitle"=> $articleTitle], ['articles'=> $articles]);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
$articleTitle = Knowledge_base::where('id', $id)->first();
if (!$articleTitle) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
return view('admin.articles.create', ['articleTitle'=>$articleTitle]);
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
$article = Knowledge_base_topick::where('id', $id)->first();
if (!$article) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$knowledgeBaseId = $article->knowledge_base_id;
$article->topic_name = $request->topic_name;
$article->description = $request->description;
$done = $article->update();
if ($done) {
return redirect()->route('admin.articles',['id'=> $knowledgeBaseId])->with('success', get_phrase('successfully updated.'));
} else {
return redirect()->route('admin.articles',['id'=> $knowledgeBaseId])->with('error', get_phrase('not updated.'));
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
$article = Knowledge_base_topick::where('id', $id)->first();
if (!$article) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$knowledgeBaseId = $article->knowledge_base_id;
$done = $article->delete();
if ($done) {
return redirect()->route('admin.articles', ['id'=> $knowledgeBaseId])->with('success', get_phrase('article deleted'));
} else {
return redirect()->route('admin.articles', ['id'=> $knowledgeBaseId])->with('error', get_phrase('article not deleted'));
}
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\BootcampCategory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class BootcampCategoryController extends Controller
{
public function index()
{
$page_data['categories'] = BootcampCategory::paginate(32);
return view('admin.bootcamp_category.index', $page_data);
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|string|unique:bootcamp_categories,title',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
BootcampCategory::insert($data);
Session::flash('success', get_phrase('Category has been created.'));
return redirect()->back();
}
public function delete($id)
{
$category = BootcampCategory::where('id', $id);
if ($category->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$category->delete();
Session::flash('success', get_phrase('Category has been deleted.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$category = BootcampCategory::where('id', $id);
if ($category->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$validator = Validator::make($request->all(), [
'title' => 'required|string|unique:bootcamp_categories,title,' . $id,
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$category->update($data);
Session::flash('success', get_phrase('Category has been updated.'));
return redirect()->back();
}
}

View File

@ -0,0 +1,346 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Bootcamp;
use App\Models\BootcampCategory;
use App\Models\BootcampModule;
use App\Models\BootcampPurchase;
use App\Models\FileUploader;
use App\Models\SeoField;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class BootcampController extends Controller
{
public function __construct()
{
date_default_timezone_set('Asia/Dhaka');
}
public function index($type = '')
{
$query = Bootcamp::join('bootcamp_categories', 'bootcamps.category_id', 'bootcamp_categories.id')
->select('bootcamps.*', 'bootcamp_categories.title as category', 'bootcamp_categories.slug as category_slug')
->where('bootcamps.user_id', auth()->user()->id);
if (request()->has('search')) {
$query = $query->where('bootcamps.title', 'LIKE', "%" . request()->query('search') . "%");
}
if (request()->has('category') && request()->query('category') != 'all') {
$category = BootcampCategory::where('slug', request()->query('category'))->first();
$query = $query->where('bootcamps.category_id', $category->id);
}
if (request()->has('status') && request()->query('status') != 'all') {
$status = request()->query('status') == 'active' ? 1 : 0;
$query = $query->where('bootcamps.status', $status);
}
if (request()->has('instructor') && request()->query('instructor') != 'all') {
$query = $query->where('bootcamps.user_id', request()->query('instructor'));
}
if (request()->has('price') && request()->query('price') != 'all') {
$price = request()->query('price');
$value = 1;
if ($price == 'free') {
$column = 'is_paid';
$value = 0;
} elseif ($price == 'discounted') {
$column = 'discount_flag';
} elseif ($price == 'paid') {
$column = 'is_paid';
}
$query = $query->where('bootcamps.' . $column, $value);
}
$page_data['bootcamps'] = $query->paginate(20)->appends(request()->query());
return view('admin.bootcamp.index', $page_data);
}
public function create()
{
return view('admin.bootcamp.create');
}
public function edit($id)
{
$bootcamp = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id)->first();
if (! $bootcamp) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->route('admin.bootcamps');
}
$page_data['bootcamp_details'] = $bootcamp;
$page_data['modules'] = BootcampModule::where('bootcamp_id', $id)->orderBy('sort', 'asc')->get();
return view('admin.bootcamp.edit', $page_data);
}
public function store(Request $request)
{
$rules = [
'title' => 'required|string',
'description' => 'required|string',
'category_id' => 'required',
'is_paid' => Rule::in(['0', '1']),
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
'discount_flag' => Rule::in(['', '1']),
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$title = Bootcamp::where('user_id', auth()->user()->id)->where('title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
$data['user_id'] = auth()->user()->id;
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['short_description'] = $request->short_description;
$data['description'] = $request->description;
$data['publish_date'] = strtotime($request->publish_date);
$data['category_id'] = $request->category_id;
$data['is_paid'] = $request->is_paid;
$data['price'] = $request->price;
$data['discount_flag'] = $request->discount_flag;
$data['discounted_price'] = $request->discounted_price;
$data['status'] = 1;
if ($request->thumbnail) {
$data['thumbnail'] = "uploads/bootcamp/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail']);
}
$insert_id = Bootcamp::insertGetId($data);
Session::flash('success', get_phrase('Bootcamp has been created.'));
return redirect()->route('admin.bootcamp.edit', [$insert_id, 'tab' => 'basic']);
}
public function delete($id)
{
$bootcamp = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id);
if ($bootcamp->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$bootcamp->delete();
Session::flash('success', get_phrase('Bootcamp has been deleted.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$query = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id);
if ($query->doesntExist() || $request->tab == '') {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$rules = $data = [];
if ($request->tab == 'basic') {
$rules = [
'title' => 'required|string',
'description' => 'required|string',
'category_id' => 'required',
];
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['short_description'] = $request->short_description;
$data['description'] = $request->description;
$data['publish_date'] = strtotime($request->publish_date);
$data['category_id'] = $request->category_id;
$title = Bootcamp::where('user_id', auth()->user()->id)
->where('id', '!=', $id)
->where('title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
} elseif ($request->tab == 'pricing') {
$rules = [
'is_paid' => Rule::in(['0', '1']),
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
'discount_flag' => Rule::in(['', '1']),
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
];
$data['is_paid'] = $request->is_paid;
$data['price'] = $request->price;
$data['discount_flag'] = $request->discount_flag;
$data['discounted_price'] = $request->discounted_price;
} elseif ($request->tab == 'info') {
$rules = [
'requirements' => 'array',
'outcomes' => 'array',
'faqs' => 'array',
];
//Remove empty value by using array filter function
$data['requirements'] = json_encode(array_filter($request->requirements, fn($value) => ! is_null($value) && $value !== ''));
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn($value) => ! is_null($value) && $value !== ''));
$faqs = [];
foreach ($request->faq_title as $key => $title) {
if ($title != '') {
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
}
}
$data['faqs'] = json_encode($faqs);
} elseif ($request->tab == 'media') {
if ($request->thumbnail) {
$data['thumbnail'] = "uploads/bootcamp/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail']);
remove_file($query->first()->thumbnail);
}
} elseif ($request->tab == 'seo') {
$bootcamp_details = $query->first();
$SeoField = SeoField::where('bootcamp_id', $bootcamp_details->id)->first();
$seo_data['bootcamp_id'] = $id;
$seo_data['route'] = 'Bootcamp Details';
$seo_data['name_route'] = 'bootcamp.details';
$seo_data['meta_title'] = $request->meta_title;
$seo_data['meta_description'] = $request->meta_description;
$seo_data['meta_robot'] = $request->meta_robot;
$seo_data['canonical_url'] = $request->canonical_url;
$seo_data['custom_url'] = $request->custom_url;
$seo_data['json_ld'] = $request->json_ld;
$seo_data['og_title'] = $request->og_title;
$seo_data['og_description'] = $request->og_description;
$seo_data['created_at'] = date('Y-m-d H:i:s');
$seo_data['updated_at'] = date('Y-m-d H:i:s');
$meta_keywords_arr = json_decode($request->meta_keywords, true);
$meta_keywords = '';
if (is_array($meta_keywords_arr)) {
foreach ($meta_keywords_arr as $arr_key => $arr_val) {
$meta_keywords .= $meta_keywords == '' ? $arr_val['value'] : ', ' . $arr_val['value'];
}
$seo_data['meta_keywords'] = $meta_keywords;
}
if ($request->og_image) {
$originalFileName = $bootcamp_details->id . '-' . $request->og_image->getClientOriginalName();
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
// Move the file to the destination path
FileUploader::upload($request->og_image, $destinationPath, 600);
$seo_data['og_image'] = $destinationPath;
}
if ($SeoField) {
if ($request->og_image) {
remove_file($SeoField->og_image);
}
SeoField::where('bootcamp_id', $bootcamp_details->id)->update($seo_data);
} else {
SeoField::insert($seo_data);
}
}
//For ajax form submission
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$query->update($data);
//For ajax form submission
// return ['success' => get_phrase('Course updated successfully')];
//for normal form submission
Session::flash('success', get_phrase('Bootcamp has been updated successfully.'));
return redirect()->back();
}
public function duplicate($id)
{
$bootcamp = Bootcamp::where('id', $id);
if ($bootcamp->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$bootcamp = $bootcamp->first()->toArray();
$bootcamp['title'] = $bootcamp['title'] . ' copy';
$bootcamp['slug'] = slugify($bootcamp['title']);
$bootcamp['user_id'] = auth()->user()->id;
$bootcamp['status'] = 1;
unset($bootcamp['id'], $bootcamp['created_at'], $bootcamp['updated_at']);
$insert_id = Bootcamp::insertGetId($bootcamp);
Session::flash('success', get_phrase('Bootcamp has been duplicated.'));
return redirect()->route('admin.bootcamp.edit', [$insert_id, 'tab' => 'basic']);
}
public function status($id)
{
$bootcamp = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id);
if ($bootcamp->doesntExist()) {
$response = [
'error' => get_phrase('Data not found.'),
];
return json_encode($response);
}
$status = $bootcamp->first()->status ? 0 : 1;
Bootcamp::where('id', $id)->update(['status' => $status]);
return redirect()->back()->with('success', get_phrase('Status has been updated.'));
}
public function purchase_history()
{
$page_data['purchases'] = BootcampPurchase::join('bootcamps', 'bootcamp_purchases.bootcamp_id', 'bootcamps.id')
->select(
'bootcamp_purchases.*',
'bootcamps.user_id as author',
'bootcamps.title',
'bootcamps.slug',
'bootcamps.price as amount',
)
->latest('bootcamp_purchases.id')->paginate(20)->appends(request()->query());
return view('admin.bootcamp.purchase_history', $page_data);
}
public function invoice($id)
{
$invoice = BootcampPurchase::join('bootcamps', 'bootcamp_purchases.bootcamp_id', 'bootcamps.id')
->where('bootcamp_purchases.id', $id)
->select(
'bootcamp_purchases.*',
'bootcamps.title',
'bootcamps.slug',
)->first();
if (! $invoice) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$page_data['invoice'] = $invoice;
return view('admin.bootcamp.invoice', $page_data);
}
}

View File

@ -0,0 +1,261 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Controllers\ZoomMeetingController;
use App\Models\BootcampLiveClass;
use App\Models\BootcampModule;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class BootcampLiveClassController extends Controller
{
public function __construct()
{
date_default_timezone_set('Asia/Dhaka');
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|string',
'date' => 'required|date',
'start_time' => 'required|string',
'end_time' => 'required|string|after:start_time',
'module_id' => 'required',
'description' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
// check selected module
$module = BootcampModule::where('id', $request->module_id)->first();
if (! $module) {
Session::flash('error', get_phrase('Module does not exist.'));
return redirect()->back();
}
// process class schedule
$start = $request->date . ' ' . $request->start_time;
$start_timestamp = strtotime($start);
$end = $request->date . ' ' . $request->end_time;
$end_timestamp = strtotime($end);
// check module and class schedule
if ($module->restriction) {
if ($module->restriction == 1 && $start_timestamp < $module->publish_date) {
Session::flash('error', get_phrase('Please set class schedule properly.'));
return redirect()->back();
}
if ($module->restriction == 2 && (($start_timestamp < $module->publish_date || $start_timestamp > $module->expiry_date) && ($end_timestamp < $module->publish_date || $end_timestamp > $module->expiry_date))) {
Session::flash('error', get_phrase('Please set class schedule properly.'));
return redirect()->back();
}
}
// check duplicate title for same bootcamp id
$title = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamps.user_id', auth()->user()->id)
->where('bootcamp_modules.id', $request->module_id)
->where('bootcamp_live_classes.title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['description'] = $request->description;
$data['status'] = $request->status;
$data['module_id'] = $request->module_id;
$data['start_time'] = $start_timestamp;
$data['end_time'] = $end_timestamp;
// Calculate the difference in seconds
$difference_in_seconds = $data['end_time'] - $data['start_time'];
// Convert the difference to minutes
$difference_in_minutes = $difference_in_seconds / 60;
$joiningData = ZoomMeetingController::createMeeting($request->title, $start_timestamp, $difference_in_minutes);
$joiningInfoArr = json_decode($joiningData, true);
if (array_key_exists('code', $joiningInfoArr) && $joiningInfoArr) {
return redirect(route('admin.bootcamp.edit', ['id' => $module->bootcamp_id, 'tab' => 'curriculum']))->with('error', get_phrase($joiningInfoArr['message']));
}
$data['provider'] = 'zoom';
$data['joining_data'] = $joiningData;
BootcampLiveClass::insert($data);
Session::flash('success', get_phrase('Live class has been created.'));
return redirect()->route('admin.bootcamp.edit', ['id' => $module->bootcamp_id, 'tab' => 'curriculum']);
}
public function update(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'title' => 'required|string',
'start_time' => 'required',
'end_time' => 'required',
'module_id' => 'required',
'description' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_live_classes.id', $id)
->where('bootcamp_live_classes.module_id', $request->module_id)
->where('bootcamps.user_id', auth()->user()->id)
->select('bootcamp_live_classes.*', 'bootcamp_modules.restriction', 'bootcamp_modules.publish_date', 'bootcamp_modules.expiry_date')
->first();
if (! $class) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
// process class schedule
$start = $request->date . ' ' . $request->start_time;
$start_timestamp = strtotime($start);
$end = $request->date . ' ' . $request->end_time;
$end_timestamp = strtotime($end);
// check module and class schedule
if ($class->restriction) {
if ($class->restriction == 1 && $start_timestamp < $class->publish_date) {
Session::flash('error', get_phrase('Please set class schedule properly.'));
return redirect()->back();
}
if ($class->restriction == 2 && (($start_timestamp < $class->publish_date || $start_timestamp > $class->expiry_date) && ($end_timestamp < $class->publish_date || $end_timestamp > $class->expiry_date))) {
Session::flash('error', get_phrase('Please set class schedule properly.'));
return redirect()->back();
}
}
// check duplicate title for same bootcamp id
$title = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamps.user_id', auth()->user()->id)
->where('bootcamp_modules.id', $request->module_id)
->where('bootcamp_live_classes.id', '!=', $id)
->where('bootcamp_live_classes.title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
if ($class->start_time != $start_timestamp || $class->end_time != $end_timestamp) {
$data['force_stop'] = 0;
}
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['description'] = $request->description;
$data['status'] = $request->status;
$data['module_id'] = $request->module_id;
$data['start_time'] = $start_timestamp;
$data['end_time'] = $end_timestamp;
if ($class->provider == 'zoom') {
$oldMeetingData = json_decode($class->joining_data, true);
ZoomMeetingController::updateMeeting($request->title, $request->start_time, $oldMeetingData['id']);
$oldMeetingData["start_time"] = date('Y-m-d\TH:i:s', strtotime($request->start_time));
$oldMeetingData["topic"] = $request->class_topic;
$data['joining_data'] = json_encode($oldMeetingData);
}
$class->update($data);
Session::flash('success', get_phrase('Live class has been updated.'));
return redirect()->back();
}
public function delete($id)
{
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_live_classes.id', $id)
->where('bootcamps.user_id', auth()->user()->id)->first();
if (! $class) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$oldMeetingData = json_decode($class->joining_data, true);
ZoomMeetingController::deleteMeeting($oldMeetingData['id']);
$class->delete();
Session::flash('success', get_phrase('Live class has been deleted.'));
return redirect()->back();
}
public function join_class($slug)
{
$current_time = time();
$extended_time = $current_time + (60 * 15);
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_live_classes.slug', $slug)
->where('bootcamps.user_id', auth()->user()->id)
->select('bootcamp_live_classes.*', 'bootcamps.id as bootcamp_id', 'bootcamps.user_id as host_id')
->first();
if (! $class) {
Session::flash('error', get_phrase('Class not found.'));
return redirect()->back();
}
if (get_settings('zoom_web_sdk') == 'active') {
$page_data['class'] = $class;
$page_data['user'] = get_user_info($class->host_id);
$page_data['is_host'] = 1;
return view('bootcamp_online_class.index', $page_data);
} else {
$meeting_info = json_decode($class->joining_data, true);
return redirect($meeting_info['start_url']);
}
}
public function stop_class($id)
{
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_live_classes.id', $id)
->where('bootcamps.user_id', auth()->user()->id)
->select('bootcamp_live_classes.*', 'bootcamps.id as bootcamp_id')
->first();
if (! $class) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$class->update(['force_stop' => 1]);
Session::flash('success', get_phrase('Class has been ended.'));
return redirect()->back();
}
public function sort(Request $request)
{
$classes = json_decode($request->itemJSON);
foreach ($classes as $key => $value) {
$updater = $key + 1;
BootcampLiveClass::where('id', $value)->update(['sort' => $updater]);
}
return response()->json([
'status' => true,
'success' => get_phrase('Classes sorted successfully'),
]);
}
}

View File

@ -0,0 +1,118 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\BootcampModule;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class BootcampModuleController extends Controller
{
public function __construct()
{
date_default_timezone_set('Asia/Dhaka');
}
public function store(Request $request)
{
$rules = [
'title' => 'required|string',
'validity' => 'required',
'bootcamp_id' => 'required',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
// check duplicate title for same bootcamp id
$title = BootcampModule::join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamps.user_id', auth()->user()->id)->where('bootcamp_modules.title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['restriction'] = $request->restriction;
$data['bootcamp_id'] = $request->bootcamp_id;
$date = explode('-', $request->validity);
$data['publish_date'] = strtotime($date[0]);
$data['expiry_date'] = strtotime($date[1]);
BootcampModule::insert($data);
Session::flash('success', get_phrase('Module has been created.'));
return redirect()->back();
}
public function delete($id)
{
$module = BootcampModule::where('id', $id);
if ($module->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$module->delete();
Session::flash('success', get_phrase('Module has been deleted.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$module = BootcampModule::where('id', $id)->where('bootcamp_id', $request->bootcamp_id);
if ($module->doesntExist()) {
Session::flash('error', get_phrase('Data not fount.'));
return redirect()->back();
}
// check duplicate title for same bootcamp id
$title = BootcampModule::join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_modules.id', '!=', $id)
->where('bootcamps.user_id', auth()->user()->id)
->where('bootcamp_modules.title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
$rules = [
'title' => 'required|string',
'validity' => 'required',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$data['title'] = $request->title;
$data['restriction'] = $request->restriction;
$date = explode('-', $request->validity);
$data['publish_date'] = strtotime($date[0]);
$data['expiry_date'] = strtotime($date[1]);
$module->update($data);
Session::flash('success', get_phrase('Module has been updated.'));
return redirect()->back();
}
public function sort(Request $request)
{
$modules = json_decode($request->itemJSON);
foreach ($modules as $key => $value) {
$updater = $key + 1;
BootcampModule::where('id', $value)->update(['sort' => $updater]);
}
return response()->json([
'status' => true,
'success' => get_phrase('Modules sorted successfully'),
]);
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Bootcamp;
use App\Models\BootcampLiveClass;
use App\Models\BootcampModule;
use App\Models\BootcampResource;
use App\Models\FileUploader;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class BootcampResourceController extends Controller
{
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'module_id' => 'required|numeric',
'upload_type' => 'required|in:resource,record',
'files' => 'required|array',
'files.*' => 'required|file',
]);
if ($validator->fails()) {
return response()->back()->withErrors($validator)->withInput();
}
$module = BootcampModule::join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->select('bootcamp_modules.*', 'bootcamps.title as bootcamp_title')
->where('bootcamp_modules.id', $request->module_id)->first();
if (! $module) {
Session::flash('error', get_phrase('Module not found.'));
return redirect()->back();
}
$data['module_id'] = $module->id;
$data['upload_type'] = $request->upload_type;
$allowed_extensions = ['mp4', 'mov', 'avi', 'wmv', 'webm'];
$files = $request->file('files');
foreach ($files as $file) {
if ($request->upload_type == 'record' && ! in_array($file->getClientOriginalExtension(), $allowed_extensions)) {
Session::flash('error', get_phrase("Failed to upload. File type must be a video."));
return redirect()->back();
}
$file_name = $file->getClientOriginalName();
$data['title'] = replace_url_symbol($file_name);
$data['file'] = 'uploads/bootcamp/resource/' . auth()->user()->name . '/' . $module->bootcamp_title . '/' . $module->title . '/' . $data['title'];
$query = BootcampResource::where('title', $data['title']);
if ($query->exists()) {
Session::flash('error', get_phrase("File already exists."));
return redirect()->back();
}
$query->insert($data);
FileUploader::upload($file, $data['file']);
}
Session::flash('success', get_phrase(ucfirst($request->upload_type) . ' has been uploaded.'));
return redirect()->back();
}
public function delete($id)
{
$resource = BootcampResource::where('id', $id)->first();
if (! $resource) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$file_path = public_path($resource->file);
if (file_exists($file_path)) {
remove_file($file_path);
}
$resource->delete();
Session::flash('success', get_phrase(ucfirst($resource->upload_type) . ' has been deleted.'));
return redirect()->back();
}
public function download($id)
{
$resource = BootcampResource::where('id', $id);
if ($resource->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$file = $resource->first();
$file_path = public_path($file->file);
if (! file_exists($file_path)) {
Session::flash('error', get_phrase('File does not exists.'));
return redirect()->back();
}
return response()->download($file_path);
}
}

View File

@ -0,0 +1,130 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Category;
use App\Models\FileUploader;
class CategoryController extends Controller
{
//
public function index()
{
$page_data['categories'] = Category::where('parent_id', 0)->orderBy('sort', 'asc')->get();
return view('admin.category.index', $page_data);
}
public function create()
{
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|max:255',
'parent_id' => 'required|numeric|min:0',
'icon' => 'required',
'keywords' => 'max:400',
'description' => 'max:500',
]);
if (Category::where('slug', slugify($request->title))->count() > 0) {
return redirect(route('admin.categories'))->with('error', get_phrase('There cannot be more than one category with the same name. Please change your category name'));
}
$data['parent_id'] = $request->parent_id;
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['icon'] = $request->icon;
$data['sort'] = 0;
$data['keywords'] = $request->keywords;
$data['description'] = $request->description;
$data['created_at'] = date('Y-m-d H:i:s');
$data['updated_at'] = date('Y-m-d H:i:s');
if(isset($request->thumbnail)){
$data['thumbnail'] = "uploads/category-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 500, null, 200, 200);
}
if(isset($request->category_logo)){
$data['category_logo'] = "uploads/category-logo/" . nice_file_name($request->title.' logo', $request->category_logo->extension());
FileUploader::upload($request->category_logo, $data['category_logo'], 400, null, 200, 200);
}
Category::insert($data);
return redirect(route('admin.categories'))->with('success', get_phrase('Category added successfully'));
}
public function edit()
{
}
public function update(Request $request, $id)
{
$query = Category::where('id', $id);
$pre_data = Category::where('id', $id)->first();
$validated = $request->validate([
'title' => 'required|max:255',
'parent_id' => 'required|numeric|min:0',
'icon' => 'required',
'keywords' => 'max:400',
'description' => 'max:500',
]);
if (Category::where('slug', slugify($request->title))->where('id', '!=', $id)->count() > 0) {
return redirect(route('admin.categories'))->with('error', get_phrase('There cannot be more than one category with the same name. Please change your category name'));
}
$data['parent_id'] = $request->parent_id;
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['icon'] = $request->icon;
$data['keywords'] = $request->keywords;
$data['description'] = $request->description;
$data['updated_at'] = date('Y-m-d H:i:s');
if (isset($request->thumbnail) && $request->thumbnail != '') {
$data['thumbnail'] = "uploads/category-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 500, null, 200, 200);
remove_file($pre_data->thumbnail);
}
if(isset($request->category_logo)){
$data['category_logo'] = "uploads/category-logo/" . nice_file_name($request->title.'-logo', $request->category_logo->extension());
FileUploader::upload($request->category_logo, $data['category_logo'], 400, null, 200, 200);
remove_file($pre_data->category_logo);
}
$query->update($data);
return redirect(route('admin.categories'))->with('success', get_phrase('Category updated successfully'));
}
public function delete($id)
{
$query = Category::where('id', $id);
if ($query->first()->parent_id > 0) {
remove_file($query->first()->thumbnail);
$query->delete();
} else {
foreach ($query->first()->childs as $sub_category) {
$sub_query = Category::where('id', $sub_category->id);
remove_file($sub_query->first()->thumbnail);
$sub_query->delete();
}
remove_file($query->first()->thumbnail);
$query->delete();
}
return redirect(route('admin.categories'))->with('success', get_phrase('Category deleted successfully'));
}
}

View File

@ -0,0 +1,106 @@
<?php
namespace App\Http\Controllers\admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Knowledge_base;
use App\Models\Knowledge_base_topick;
use Illuminate\Support\Facades\Session;
class KnowledgeBaseController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$datas = Knowledge_base::orderBy("created_at","desc")->paginate(10);
return view('admin.knowledge_base.index', compact('datas'));
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$request->validate([
'title' => 'required | max:200 '
]);
$query = new Knowledge_base;
$query->title = $request->title;
$done = $query->save();
if ($done) {
return redirect()->back()->with('success', get_phrase('successfullly added'));
} else {
return redirect()->back()->with('error', get_phrase('something wrong!'));
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
$request->validate([
'title' => 'required | max:200 '
]);
$query = Knowledge_base::where('id', $id)->first();
$query->title = $request->title;
$done = $query->update();
if ($done) {
return redirect()->back()->with('success', get_phrase('updated successfully.'));
} else {
return redirect()->back()->with('error', get_phrase('no data found'));
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
$done = Knowledge_base_topick::where('knowledge_base_id', $id)->delete();
$ok = Knowledge_base::where('id', $id)->delete();
if ($done || $ok) {
return redirect()->back()->with('success', get_phrase('successfully deleted.'));
} else {
return redirect()->back()->with('error', get_phrase('something went wrong.'));
}
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Message;
use App\Models\MessageThread;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class MessageController extends Controller
{
public function message($message_thread_code = "")
{
$page_data['thread_code'] = $message_thread_code;
$page_data['thread_details'] = MessageThread::where('code', $message_thread_code)->first();
$contact = MessageThread::where('contact_one', auth()->user()->id)->orWhere('contact_two', auth()->user()->id)->count();
if (!$message_thread_code) {
$thread = MessageThread::latest('id')->value('code');
if ($contact > 0) {
return redirect()->route('admin.message', $thread);
}
} else {
Message::where('thread_id', $page_data['thread_details']->id)->where('read', '!=', '1')->update(['read' => 1]);
}
return view('admin.message.message', $page_data);
}
public function store(Request $request)
{
$validated = $request->validate([
'message' => 'required',
'sender_id' => 'required|integer|exists:App\Models\User,id',
'receiver_id' => 'required|integer|exists:App\Models\User,id',
'thread_id' => 'required|integer',
]);
$data['message'] = $request->message;
$data['sender_id'] = $request->sender_id;
$data['receiver_id'] = $request->receiver_id;
$data['thread_id'] = $request->thread_id;
$data['created_at'] = date('Y-m-d H:i:s');
$data['read'] = null;
Message::insert($data);
MessageThread::where('id', $request->thread_id)->update(['updated_at' => date('Y-m-d H:i:s')]);
$message_thread = MessageThread::find($request->thread_id)->code;
Session::flash('success', get_phrase('Your message successfully has been sent'));
return redirect(route('admin.message', ['message_thread' => $message_thread]));
}
public function thread_store(Request $request)
{
$validated = $request->validate([
'receiver_id' => 'required|integer|exists:App\Models\User,id',
]);
$auth = auth()->user()->id;
$user_id = $request->receiver_id;
$has_thread = MessageThread::where(function ($query) use ($auth, $user_id) {
$query->where('contact_one', $auth)->where('contact_two', $user_id);
})
->orWhere(function ($query) use ($auth, $user_id) {
$query->where('contact_one', $user_id)->where('contact_two', $auth);
})
->first();
$thread = $has_thread ? $has_thread->code : random(20);
if (!$has_thread) {
$data['contact_one'] = auth()->user()->id;
$data['contact_two'] = $request->receiver_id;
$data['code'] = $thread;
$data['created_at'] = date('Y-m-d H:i:s');
MessageThread::insert($data);
Session::flash('success', get_phrase('Message thread successfully created'));
}
return redirect(route('admin.message', ['message_thread' => $thread]));
}
public function searchThreads(Request $request)
{
$user_id_arr = array();
$user_id = $request->user()->id; // Assuming you're using Laravel's authentication
$search = $request->input('search');
$users = User::where('name', 'like', '%' . $search . '%')->orWhere('email', 'like', '%' . $search . '%')->limit(50)->get();
foreach ($users as $users) {
$user_id_arr[] = $users->id;
}
$messageThreads = MessageThread::where(function ($query) use ($user_id_arr) {
$query->whereIn('sender', $user_id_arr)->where('receiver', auth()->user()->id);
})
->orWhere(function ($query) use ($user_id_arr) {
$query->whereIn('receiver', $user_id_arr)->where('sender', auth()->user()->id);
})
->get();
$page_data['message_threads'] = $messageThreads;
$page_data['search'] = $search;
$page_data['thread'] = $request->thread;
return view('admin.message.message_left_side_bar', $page_data);
}
}

View File

@ -0,0 +1,218 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Bootcamp;
use App\Models\BootcampPurchase;
use App\Models\CartItem;
use App\Models\Coupon;
use App\Models\Course;
use App\Models\Enrollment;
use App\Models\OfflinePayment;
use App\Models\Payment_history;
use App\Models\TeamPackagePurchase;
use App\Models\TeamTrainingPackage;
use App\Models\TutorBooking;
use App\Models\TutorSchedule;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class OfflinePaymentController extends Controller
{
public function index(Request $request)
{
$payments = OfflinePayment::orderBY('id', 'DESC');
if ($request->status == 'approved') {
$payments->where('status', 1);
} elseif ($request->status == 'suspended') {
$payments->where('status', 2);
} elseif ($request->status == 'pending') {
$payments->where('status', 0)->orWhere('status', null);
}
$page_data['payments'] = $payments->paginate(10);
return view('admin.offline_payments.index', $page_data);
}
public function download_doc($id)
{
// validate id
if (empty($id)) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
// payment details
$payment_details = OfflinePayment::where('id', $id)->first();
$filePath = public_path($payment_details->doc);
if (! file_exists($filePath)) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
// download file
return Response::download($filePath);
}
public function accept_payment($id)
{
// validate id
if (empty($id)) {
Session::flash('error', get_phrase('Id can not be empty.'));
return redirect()->back();
}
// payment details
$query = OfflinePayment::where('id', $id)->where('status', 0);
if ($query->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$payment_details = $query->first();
$payment['invoice'] = Str::random(20);
$payment['user_id'] = $payment_details['user_id'];
$payment['payment_type'] = 'offline';
$payment['coupon'] = $payment_details->coupon;
if ($payment_details->item_type == 'course') {
$items = json_decode($payment_details->items);
foreach ($items as $item) {
$course = Course::where('id', $item)->first();
$payment['course_id'] = $course->id;
// Calculate base amount
$amount = $course->discount_flag == 1 ? $course->discounted_price : $course->price;
// Apply coupon discount if applicable
$discounted_price = 0;
if ($payment_details->coupon) {
$coupon = Coupon::where('code', $payment_details->coupon)->first();
if ($coupon) {
$discounted_price = $amount * ($coupon->discount / 100);
}
}
// Final payment amount and tax
$final_amount = $amount - $discounted_price;
$payment['amount'] = $final_amount;
$payment['tax'] = (get_settings('course_selling_tax') / 100) * $final_amount;
// Calculate admin and instructor revenue
if (get_course_creator_id($course->id)->role == 'admin') {
$payment['admin_revenue'] = $final_amount;
} else {
$payment['instructor_revenue'] = $final_amount * (get_settings('instructor_revenue') / 100);
$payment['admin_revenue'] = $final_amount - $payment['instructor_revenue'];
}
// Insert payment record
$accept_payment = Payment_history::insert($payment);
// Enroll user in course if payment succeeds
if ($accept_payment) {
$enroll['user_id'] = $payment_details['user_id'];
$enroll['course_id'] = $course->id;
$enroll['enrollment_type'] = "paid";
$enroll['entry_date'] = time();
$enroll['created_at'] = date('Y-m-d H:i:s');
$enroll['updated_at'] = date('Y-m-d H:i:s');
if ($course->expiry_period > 0) {
$days = $course->expiry_period * 30;
$enroll['expiry_date'] = strtotime("+" . $days . " days");
} else {
$enroll['expiry_date'] = null;
}
Enrollment::insert($enroll);
}
}
} elseif ($payment_details->item_type == 'bootcamp') {
$bootcamps = Bootcamp::whereIn('id', json_decode($payment_details->items, true))->get();
foreach($bootcamps as $bootcamp){
$bootcamp_payment['invoice'] = '#' . Str::random(20);
$bootcamp_payment['user_id'] = $payment_details['user_id'];
$bootcamp_payment['bootcamp_id'] = $bootcamp->id;
$bootcamp_payment['price'] = $bootcamp->discount_flag == 1 ? $bootcamp->price - $bootcamp->discounted_price : $bootcamp->price;
$bootcamp_payment['tax'] = 0;
$bootcamp_payment['payment_method'] = 'offline';
$bootcamp_payment['status'] = 1;
// insert bootcamp purchase
BootcampPurchase::insert($bootcamp_payment);
}
} elseif ($payment_details->item_type == 'package') {
$packages = TeamTrainingPackage::whereIn('id', json_decode($payment_details->items, true))->get();
foreach($packages as $package){
$package_payment['invoice'] = '#' . Str::random(20);
$package_payment['user_id'] = $payment_details['user_id'];
$package_payment['package_id'] = $package->id;
$package_payment['price'] = $package->price;
$package_payment['tax'] = 0;
$package_payment['payment_method'] = 'offline';
$package_payment['status'] = 1;
// insert package purchase
TeamPackagePurchase::insert($package_payment);
}
} elseif ($payment_details->item_type == 'tutor_booking') {
$schedules = TutorSchedule::whereIn('id', json_decode($payment_details->items, true))->get();
foreach($schedules as $schedule){
$schedule_payment['invoice'] = '#' . Str::random(20);
$schedule_payment['student_id'] = $payment_details['user_id'];
$schedule_payment['schedule_id'] = $schedule->id;
$schedule_payment['price'] = $payment_details['total_amount'];
$schedule_payment['tax'] = $payment_details['tax'];
$schedule_payment['payment_method'] = 'offline';
$schedule = TutorSchedule::find($schedule->id);
if (get_user_info($schedule->tutor_id)->role == 'admin') {
$schedule_payment['admin_revenue'] = $payment_details['payable_amount'];
} else {
$schedule_payment['instructor_revenue'] = $payment_details['total_amount'] * (get_settings('instructor_revenue') / 100);
$schedule_payment['admin_revenue'] = $payment_details['total_amount'] - $schedule_payment['instructor_revenue'];
}
$schedule_payment['tutor_id'] = $schedule->tutor_id;
$schedule_payment['start_time'] = $schedule->start_time;
$schedule_payment['end_time'] = $schedule->end_time;
// insert tutor bookings
TutorBooking::insert($schedule_payment);
}
}
// remove items from offline payment
OfflinePayment::where('id', $id)->update(['status' => 1]);
// go back
Session::flash('success', 'Payment has been accepted.');
return redirect()->route('admin.offline.payments');
}
public function decline_payment($id)
{
// remove items from offline payment
OfflinePayment::where('id', $id)->update(['status' => 2]);
// go back
Session::flash('success', 'Payment has been suspended');
return redirect()->route('admin.offline.payments');
}
public function delete_payment($id)
{
OfflinePayment::where('id', $id)->delete();
Session::flash('success', get_phrase('Admin revenue delete successfully'));
return redirect()->route('admin.offline.payments');
}
}

View File

@ -0,0 +1,129 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Category;
use App\Models\FileUploader;
use App\Models\Setting;
class OpenAiController extends Controller
{
function settings()
{
return view('admin.open_ai.settings');
}
function settings_update(Request $request)
{
$validated = $request->validate([
'open_ai_model' => 'in:gpt-3.5-turbo-0125,gpt-4-0125-preview',
'open_ai_max_token' => 'required|numeric|min:0',
'open_ai_secret_key' => 'required|max:255',
]);
foreach ($request->all() as $type => $value) {
if (Setting::where('type', $type)->count() == 0) {
Setting::where('type', $type)->insert(['type' => $type, 'description' => $value]);
} else {
Setting::where('type', $type)->update(['description' => $value]);
}
}
return redirect(route('admin.open.ai.settings'))->with('success', get_phrase('Open ai settings changed successfully'));
}
function generate(Request $request)
{
if ($request->service_type == 'Course thumbnail') {
$prompt = "We have run a online LMS system. Please generate course thumbnails for me. \n Course topic: " . $request->ai_keywords;
return $this->curl_call_to_generate_image_openai($prompt);
} else {
$prompt = "Write me a ";
$prompt .= $request->service_type;
$prompt .= " on ";
$prompt .= $request->ai_keywords;
$prompt .= " in ";
$prompt .= $request->language;
$prompt .= " language";
$instructions = "You are a " . $request->service_type . " writer.";
return $this->curl_call_to_generate_text_by_openai($prompt, $instructions);
}
}
function curl_call_to_generate_image_openai($prompt)
{
$open_ai_secret_key = get_settings('open_ai_secret_key');
$curlopt_post = ['prompt' => $prompt, 'model' => 'dall-e-3', 'size' => '1024x1024', 'n' => 1];
$curlopt_post_url = 'https://api.openai.com/v1/images/generations';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $curlopt_post_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $open_ai_secret_key,
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($curlopt_post));
$response = curl_exec($ch);
curl_close($ch);
$response_arr = json_decode($response, true);
if (array_key_exists('error', $response_arr)) {
return 'Error: ' . $response_arr['error']['message'];
} else {
return json_encode($response_arr['data']);
}
}
function curl_call_to_generate_text_by_openai($instructions, $prompt)
{
$open_ai_secret_key = get_settings('open_ai_secret_key');
$open_ai_model = get_settings('open_ai_model');
$endpoint = "https://api.openai.com/v1/chat/completions";
$data = array(
"model" => $open_ai_model,
"messages" => array(
array(
"role" => "system",
"content" => $instructions
),
array(
"role" => "user",
"content" => "$prompt"
)
)
);
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Authorization: Bearer " . $open_ai_secret_key
));
$response = curl_exec($ch);
curl_close($ch);
if ($response) {
$response = json_decode($response, true);
if(isset($response['error'])){
return json_encode($response);
}elseif(is_array($response)) {
return $response['choices'][0]['message']['content'] ?? '';
}
}
}
}

View File

@ -0,0 +1,209 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Builder_page;
use App\Models\FileUploader;
use App\Models\FrontendSetting;
use Illuminate\Http\Request;
class PageBuilderController extends Controller
{
function page_list()
{
return view('admin.page_builder.page_list');
}
function page_store(Request $request)
{
$validated = $request->validate([
'name' => 'required'
]);
Builder_page::insert(['name' => $request->name, 'created_at' => date('Y-m-d H:i:s')]);
return redirect(route('admin.pages'))->with('success', get_phrase('New home page layout has been added'));
}
function page_update(Request $request, $id)
{
$validated = $request->validate([
'name' => 'required'
]);
Builder_page::where('id', $id)->update(['name' => $request->name, 'updated_at' => date('Y-m-d H:i:s')]);
return redirect(route('admin.pages'))->with('success', get_phrase('Home page name has been updated'));
}
function page_delete($id)
{
Builder_page::where('id', $id)->delete();
return redirect(route('admin.pages'))->with('success', get_phrase('The page name has been updated'));
}
function page_status($id)
{
$query = Builder_page::where('id', $id);
if ($query->first()->status == 1) {
$query->update(['status' => 0]);
$response = [
'success' => get_phrase('Home page deactivated')
];
} else {
FrontendSetting::where('key', 'home_page')->update(['value' => $query->first()->identifier]);
$query->update(['status' => 1]);
$response = [
'success' => get_phrase('Home page activated')
];
}
Builder_page::where('id', '!=', $id)->update(['status' => 0]);
return json_encode($response);
}
function page_layout_edit($id)
{
return view('admin.page_builder.page_layout_edit', ['id' => $id]);
}
function page_layout_update(Request $request, $id)
{
$validated = $request->validate([
'developer_elements' => 'required',
'builder_elements' => 'required',
]);
$built_file_names = [];
foreach($request->builder_elements as $file_name => $builder_elements){
$built_file_names[] = $file_name;
$developer_file_content = file_get_contents(base_path('resources/views/components/home_made_by_developer/'.$file_name.'.blade.php'));
$developer_file_content = $this->replace_special_character($developer_file_content);
foreach($builder_elements as $key => $builder_element){
$developer_element = $request->developer_elements[$file_name][$key];
if($builder_element['tag'] == 'img'){
$builder_element_src = explode('/public/', $builder_element['src']);
if(array_key_exists(1, $builder_element_src)){
$updated_url_from_builder = "{{asset('".$builder_element_src[1]."')}}";
}else{
$updated_url_from_builder = "{{asset('".$builder_element['src']."')}}";
}
$prepared_single_element = str_replace($developer_element['src'], $updated_url_from_builder, $developer_element['element']);
$developer_file_content = str_replace($developer_element['element'], $prepared_single_element, $developer_file_content);
}elseif($builder_element['tag'] != 'null'){
$developer_element_tag = $this->replace_special_character($developer_element['element']);
$developer_element_content = $this->replace_special_character($developer_element['content']);
$prepared_single_element = str_replace($developer_element_content, '{{ get_phrase("'.$builder_element['content'].'") }}', $developer_element_tag);
$prepared_single_element = str_replace('(""', '("', $prepared_single_element);
$prepared_single_element = str_replace('"")', '")', $prepared_single_element);
$developer_file_content = str_replace($developer_element_tag, $prepared_single_element, $developer_file_content);
}
}
file_put_contents(base_path("resources/views/components/home_made_by_builder/".$file_name.'.blade.php'), $developer_file_content);
}
Builder_page::where('id', $id)->update(['html' => json_encode($built_file_names)]);
return redirect(route('admin.pages'))->with('success', get_phrase('Page layout has been updated'));
}
function replace_special_character($text){
if($text){
$text = str_replace('&amp;', '&', $text);
}
return $text;
}
function replace_builder_content($html_1 = "", $html_2 = "")
{
//REPLACE $html_1 BY $html_2
// Extract src and builder-identity attributes from html_2
preg_match_all('/<img\s+class="builder-editable"\s+builder-identity="(\d+)"\s+src="([^"]+)"/', $html_2, $matches2, PREG_SET_ORDER);
// Create an associative array to map builder-identity to src
$srcMap = [];
foreach ($matches2 as $match) {
$srcMap[$match[1]] = $match[2];
}
// Replace src attributes in html_1 using the srcMap
$html_1 = preg_replace_callback('/<img\s+class="builder-editable"\s+builder-identity="(\d+)"\s+src="([^"]+)"/', function ($matches) use ($srcMap) {
$identity = $matches[1];
if (isset($srcMap[$identity])) {
return '<img class="builder-editable" builder-identity="' . $identity . '" src="{{asset("' . $srcMap[$identity] . '")}}"';
}
return $matches[0];
}, $html_1);
// Extract content and builder-identity attributes from html_2 (excluding img tags)
preg_match_all('/<([^img][^>]*)builder-identity="(\d+)"[^>]*>(.*?)<\/[^>]+>/', $html_2, $matches2, PREG_SET_ORDER);
// Create an associative array to map builder-identity to content
$contentMap = [];
foreach ($matches2 as $match) {
$contentMap[$match[2]] = $match[3];
}
// Replace content in html_1 using the contentMap
$html_1 = preg_replace_callback('/<([^img][^>]*)builder-identity="(\d+)"[^>]*>(.*?)<\/[^>]+>/', function ($matches) use ($contentMap) {
$identity = $matches[2];
if (isset($contentMap[$identity])) {
return '<' . $matches[1] . 'builder-identity="' . $identity . '">' . $contentMap[$identity] . '<' . substr(strrchr($matches[0], '<'), 1);
}
return $matches[0];
}, $html_1);
return $html_1;
}
function find_builder_block_elements($html)
{
// Define a regex pattern to match all divs with builder-block-file-name attribute
$pattern = '/<div\s+[^>]*builder-block-file-name="([^"]+)"[^>]*>(.*?)<\/div>/s';
// Use preg_match_all to find all matches
preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
// Collect the file name and HTML content inside each matched element
$elements = [];
foreach ($matches as $match) {
$elements[] = [
'file_name' => $match[1], // The value of the builder-block-file-name attribute
'content' => $match[2] // The inner HTML content of the div
];
}
return $elements;
}
function developer_file_content(){
//return developer file content
$developer_file_content = '';
$files = array_diff(scandir(base_path('resources/views/components/home_made_by_developer')), array('.', '..'));
foreach ($files as $file){
$file_name = str_replace('.blade.php', '', $file);
$developer_file_content .= '<div builder-block-file-name="'.$file_name.'">'.file_get_contents(base_path('resources/views/components/home_made_by_developer/'.$file)).'</div>';
}
return $developer_file_content;
}
function page_layout_image_update(Request $request)
{
$remove_file_arr = explode('/', $request->remove_file);
$previous_image_path = 'uploads/home-page-builder/' . end($remove_file_arr);
remove_file($previous_image_path);
$image_path = FileUploader::upload($request->file, 'uploads/home-page-builder');
return get_image($image_path);
}
function preview($page_id)
{
$page_data['page_id'] = $page_id;
return view('frontend.default.home.preview', $page_data);
}
}

View File

@ -0,0 +1,143 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Question;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class QuestionController extends Controller
{
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required',
'type' => 'required',
'answer' => 'required',
'options' => 'required_if:type,mcq',
], [
'options.required_if' => 'When type is MCQ, options are required.',
]);
if ($validator->fails()) {
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
}
$answer = null;
if ($request->type == 'mcq') {
$answer = json_encode($request->answer);
$data['options'] = json_encode(array_column(json_decode($request->options, true), 'value'));
} elseif ($request->type == 'fill_blanks') {
$answers = json_decode($request->answer);
$answer = json_encode(array_column($answers, 'value'));
} elseif ($request->type == 'true_false') {
$answer = $request->answer;
}
$data['quiz_id'] = $request->quiz_id;
$data['title'] = $request->title;
$data['type'] = $request->type;
$data['answer'] = $answer;
Question::insert($data);
return response()->json([
'status' => true,
'success' => get_phrase('Question has been added.'),
'functionCall' => 'responseBack()',
]);
}
public function delete($id)
{
$question = Question::where('id', $id)->first();
if (! $question) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$question->delete();
Session::flash('success', get_phrase('Question has been deleted.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$question = Question::where('id', $id)->first();
if (! $question) {
return response()->json_encode([
'error' => get_phrase('Data not found.'),
]);
}
$validator = Validator::make($request->all(), [
'title' => 'required',
'type' => 'required',
'answer' => 'required',
'options' => 'required_if:type,mcq',
], [
'options.required_if' => 'When type is MCQ, options are required.',
]);
if ($validator->fails()) {
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
}
$answer = $data['options'] = null;
if ($request->type == 'mcq') {
$answer = json_encode($request->answer);
$data['options'] = json_encode(array_column(json_decode($request->options, true), 'value'));
} elseif ($request->type == 'fill_blanks') {
$answers = json_decode($request->answer);
$answer = json_encode(array_column($answers, 'value'));
} elseif ($request->type == 'true_false') {
$answer = $request->answer;
}
$data['quiz_id'] = $request->quiz_id;
$data['title'] = $request->title;
$data['type'] = $request->type;
$data['answer'] = $answer;
Question::where('id', $id)->update($data);
return response()->json([
'status' => true,
'success' => get_phrase('Question has been updated.'),
'functionCall' => 'responseBack()',
]);
}
public function sort(Request $request)
{
$question = json_decode($request->itemJSON);
foreach ($question as $key => $value) {
$updater = $key + 1;
Question::where('id', $value)->update(['sort' => $updater]);
}
Session::flash('success', get_phrase('Questions has been sorted.'));
}
public function load_type(Request $request)
{
$page_data = [];
$types = [
'mcq' => 'mcq',
'fill_blanks' => 'fill_blanks',
'true_false' => 'true_false',
];
if (isset($types[$request->type])) {
$action = $request->id ? 'edit' : 'create';
$path = "admin.questions.{$action}_{$types[$request->type]}";
if ($request->id) {
$page_data['question'] = Question::where('id', $request->id)->first();
}
}
return view($path, $page_data);
}
}

View File

@ -0,0 +1,162 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Lesson;
use App\Models\Question;
use App\Models\Quiz;
use App\Models\QuizSubmission;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class QuizController extends Controller
{
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required',
'section' => 'required|numeric',
'second' => 'max:59',
'minute' => 'max:59',
'hour' => 'max:23',
'total_mark' => 'required|numeric',
'pass_mark' => 'required|numeric',
'retake' => 'required|numeric|min:1',
])->after(function ($validator) use ($request) {
$hour = $request->hour;
$minute = $request->minute;
$second = $request->second;
if ($hour == 0 && $minute == 0 && $second == 0) {
$validator->errors()->add('second', 'If hour and minute are 0, second must be greater than 0.');
} elseif ($hour == 0 && $minute == 0 && $second < 1) {
$validator->errors()->add('minute', 'If hour is 0, minute must be greater than 0.');
} elseif ($minute == 0 && $second == 0 && $hour < 1) {
$validator->errors()->add('hour', 'If minute and second are 0, hour must be greater than 0.');
}
if ($request->pass_mark > $request->total_mark) {
$validator->errors()->add('pass_mark', 'The pass mark must be less than the total mark.');
}
});
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$title = Lesson::join('sections', 'lessons.section_id', 'sections.id')
->join('courses', 'sections.course_id', 'courses.id')
->where('courses.user_id', auth()->user()->id)
->where('lessons.title', $request->title)
->first();
if ($title) {
Session::flash('error', get_phrase('Title has been taken.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['course_id'] = $request->course_id;
$data['section_id'] = $request->section;
$data['total_mark'] = $request->total_mark;
$data['pass_mark'] = $request->pass_mark;
$data['retake'] = $request->retake;
$data['description'] = $request->description;
$data['lesson_type'] = 'quiz';
$data['status'] = 1;
$hour = $request->hour ?? 0;
$minute = $request->minute ?? 0;
$second = $request->second ?? 0;
$data['duration'] = $hour . ':' . $minute . ':' . $second;
Lesson::insert($data);
Session::flash('success', get_phrase('Quiz has been created.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'title' => 'required',
'section' => 'required|numeric',
'second' => 'max:59',
'minute' => 'max:59',
'hour' => 'max:23',
'total_mark' => 'required|numeric',
'pass_mark' => 'required|numeric',
'retake' => 'required|numeric|min:1',
])->after(function ($validator) use ($request) {
$hour = $request->hour;
$minute = $request->minute;
$second = $request->second;
if ($hour == 0 && $minute == 0 && $second == 0) {
$validator->errors()->add('second', 'If hour and minute are 0, second must be greater than 0.');
} elseif ($hour == 0 && $minute == 0 && $second < 1) {
$validator->errors()->add('minute', 'If hour is 0, minute must be greater than 0.');
} elseif ($minute == 0 && $second == 0 && $hour < 1) {
$validator->errors()->add('hour', 'If minute and second are 0, hour must be greater than 0.');
}
if ($request->pass_mark > $request->total_mark) {
$validator->errors()->add('pass_mark', 'The pass mark must be less than the total mark.');
}
});
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$title = Lesson::join('sections', 'lessons.section_id', 'sections.id')
->join('courses', 'sections.course_id', 'courses.id')
->where('lessons.id', '!=', $id)
->where('lessons.title', $request->title)
->where('courses.user_id', auth()->user()->id)
->first();
if ($title) {
Session::flash('error', get_phrase('Title has been taken.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['section_id'] = $request->section;
$data['total_mark'] = $request->total_mark;
$data['pass_mark'] = $request->pass_mark;
$data['retake'] = $request->retake;
$data['description'] = $request->description;
$data['lesson_type'] = 'quiz';
$data['status'] = 1;
$hour = $request->hour ?? 0;
$minute = $request->minute ?? 0;
$second = $request->second ?? 0;
$data['duration'] = $hour . ':' . $minute . ':' . $second;
Lesson::where('id', $id)->update($data);
Session::flash('success', get_phrase('Quiz has been updated.'));
return redirect()->back();
}
public function result(Request $request)
{
$submissions = QuizSubmission::where('quiz_id', $request->quizId)
->where('user_id', $request->participant)->get();
$result[] = "<option>" . get_phrase('Select an option') . "</option>";
foreach ($submissions as $key => $submission) {
$result[] = "<option value=" . $submission->id . ">Attempt " . ++$key . "</option>";
}
return $result;
}
public function result_preview(Request $request)
{
$page_data['quiz'] = Lesson::where('id', $request->quizId)->first();
$page_data['results'] = QuizSubmission::where('quiz_id', $request->quizId)->where('user_id', $request->participantId)->get();
$page_data['questions'] = Question::where('quiz_id', $request->quizId)->get();
return view('admin.quiz_result.preview', $page_data);
}
}

View File

@ -0,0 +1,231 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Course;
use App\Models\FileUploader;
use App\Models\TeamPackagePurchase;
use App\Models\TeamTrainingPackage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class TeamTrainingController extends Controller
{
public function index()
{
$query = TeamTrainingPackage::join('courses', 'team_training_packages.course_id', 'courses.id')
->select('team_training_packages.*', 'courses.title as course_title', 'courses.slug as course_slug', 'courses.price as course_price')
->where('team_training_packages.user_id', auth()->user()->id);
if (request()->has('search')) {
$query = $query->where('team_training_packages.title', 'LIKE', "%" . request()->query('search') . "%");
}
$page_data['packages'] = $query->paginate(20)->appends(request()->query());
return view('admin.team_training.index', $page_data);
}
public function store(Request $request)
{
$package['title'] = $request->title;
$package['slug'] = slugify($request->title);
$package['course_privacy'] = $request->course_privacy;
$package['course_id'] = $request->course_id;
$package['allocation'] = $request->allocation;
$package['pricing_type'] = $request->pricing_type;
$package['price'] = $request->price;
$package['expiry_type'] = $request->expiry_type;
$package['date'] = $request->expiry_date;
$package['thumbnail'] = $request->thumbnail;
$validator = Validator::make($package, [
'title' => [
'required',
Rule::unique('team_training_packages')->where(function ($query) {
return $query->where('user_id', auth()->user()->id);
}),
],
'slug' => [
'required',
Rule::unique('team_training_packages')->where(function ($query) {
return $query->where('user_id', auth()->user()->id);
}),
],
'course_privacy' => 'required|in:public,private',
'allocation' => 'required|numeric|min:0',
'pricing_type' => 'required|in:0,1',
'price' => 'required_if:is_paid,1',
'expiry_type' => 'required_if:is_paid,1|in:limited,lifetime',
'date' => 'required_if:expiry_type,limited',
'thumbnail' => 'required|file|mimes:jpg,jpeg,png',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
if ($request->expiry_type == 'limited') {
$date = explode('-', $request->expiry_date);
$package['start_date'] = strtotime($date[0]);
$package['expiry_date'] = strtotime($date[1]);
}
unset($package['thumbnail']);
if ($request->thumbnail) {
$package['thumbnail'] = "uploads/team_training/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $package['thumbnail']);
}
$filter_features = array_filter($request->features, function ($value) {
return ! is_null($value);
});
$package['features'] = json_encode($filter_features);
$package['user_id'] = auth()->user()->id;
$package['status'] = 1;
TeamTrainingPackage::create($package);
return redirect()->back()->with('success', get_phrase('Package has been created.'));
}
public function edit($id)
{
$page_data['package'] = TeamTrainingPackage::join('courses', 'team_training_packages.course_id', 'courses.id')
->select('team_training_packages.*', 'courses.title as course_title', 'courses.slug as course_slug', 'courses.price as course_price')
->where('team_training_packages.id', $id)->first();
return view('admin.team_training.edit', $page_data);
}
public function update(Request $request, $id)
{
$package['title'] = $request->title;
$package['slug'] = slugify($request->title);
$package['course_privacy'] = $request->course_privacy;
$package['course_id'] = $request->course_id;
$package['allocation'] = $request->allocation;
$package['pricing_type'] = $request->pricing_type;
$package['price'] = $request->price;
$package['expiry_type'] = $request->expiry_type;
$package['date'] = $request->expiry_date;
$package['thumbnail'] = $request->thumbnail;
$validator = Validator::make($package, [
'title' => [
'required',
Rule::unique('team_training_packages')->where(function ($query) use ($id) {
return $query->where(['id' => ! $id, 'user_id' => auth()->user()->id]);
}),
],
'slug' => [
'required',
Rule::unique('team_training_packages')->where(function ($query) use ($id) {
return $query->where(['id' => ! $id, 'user_id' => auth()->user()->id]);
}),
],
'course_privacy' => 'required|in:public,private',
'allocation' => 'required|numeric|min:0',
'pricing_type' => 'required|in:0,1',
'price' => 'required_if:is_paid,1',
'expiry_type' => 'required_if:is_paid,1|in:limited,lifetime',
'date' => 'required_if:expiry_type,limited',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
if ($request->expiry_type == 'limited') {
$date = explode('-', $request->expiry_date);
$package['start_date'] = strtotime($date[0]);
$package['expiry_date'] = strtotime($date[1]);
}
unset($package['thumbnail']);
if ($request->thumbnail) {
$package['thumbnail'] = "uploads/team_training/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $package['thumbnail']);
}
$filter_features = array_filter($request->features, function ($value) {
return ! is_null($value);
});
$package['features'] = json_encode(array_values($filter_features));
$package['user_id'] = auth()->user()->id;
TeamTrainingPackage::find($id)->update($package);
return redirect()->back()->with('success', get_phrase('Package has been updated.'));
}
public function delete($id)
{
TeamTrainingPackage::find($id)->delete();
return redirect()->back()->with('error', get_phrase('Package has been deleted.'));
}
public function duplicate($id)
{
$package = TeamTrainingPackage::find($id)->toArray();
$package['title'] = $package['title'] . ' copy';
$package['slug'] = slugify($package['title']);
unset($package['id'], $package['created_at'], $package['updated_at']);
$insert_id = TeamTrainingPackage::insertGetId($package);
return to_route('admin.team.packages.edit', $insert_id)->with('success', get_phrase('Package has been copied.'));
}
public function get_courses(Request $request)
{
if (isset($request->privacy) && in_array($request->privacy, ['public', 'private'])) {
$privacy = $request->privacy == 'public' ? 'active' : 'private';
$courses = Course::where('status', $privacy)->get();
return view('admin.team_training.load_courses', compact('courses'));
}
}
public function get_course_price(Request $request)
{
if (isset($request->course_id) && $request->course_id != '') {
$price = Course::where('id', $request->course_id)->value('price');
return $price;
}
}
public function toggle_status($id)
{
$package = TeamTrainingPackage::find($id);
$status = $package->status ? 0 : 1;
$package->update(['status' => $status]);
return redirect()->back()->with('success', get_phrase('Status has been updated.'));
}
public function purchase_history()
{
$page_data['purchases'] = TeamPackagePurchase::join('team_training_packages', 'team_package_purchases.package_id', 'team_training_packages.id')
->select(
'team_package_purchases.*',
'team_training_packages.user_id as author',
'team_training_packages.title',
'team_training_packages.slug',
'team_training_packages.price as amount',
)
->latest('team_package_purchases.id')->paginate(20)->appends(request()->query());
return view('admin.team_training.purchase_history', $page_data);
}
public function invoice($id)
{
$page_data['invoice'] = TeamPackagePurchase::join('team_training_packages', 'team_package_purchases.package_id', 'team_training_packages.id')
->where('team_training_packages.user_id', auth()->user()->id)
->where('team_package_purchases.id', $id)
->select('team_package_purchases.*', 'team_training_packages.title', 'team_training_packages.slug')
->first();
return view('admin.team_training.invoice', $page_data);
}
}

View File

@ -0,0 +1,180 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\TutorSubject;
use App\Models\TutorCategory;
use App\Models\TutorBooking;
use App\Models\TutorSchedule;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class TutorBookingController extends Controller
{
public function subjects()
{
$page_data['subjects'] = TutorSubject::orderBy('id', 'asc')->paginate(10);
return view('admin.tutor_booking.subjects', $page_data);
}
public function tutor_subject_create()
{
}
public function tutor_subject_store(Request $request)
{
$validated = $request->validate([
'name' => 'required|max:255',
]);
if (TutorSubject::where('slug', slugify($request->name))->count() > 0) {
return redirect(route('admin.tutor_subjects'))->with('error', get_phrase('There cannot be more than one subject with the same name. Please change your subject name'));
}
$data['name'] = $request->name;
$data['slug'] = slugify($request->name);
$data['status'] = 1;
$data['created_at'] = date('Y-m-d H:i:s');
$data['updated_at'] = date('Y-m-d H:i:s');
TutorSubject::insert($data);
return redirect(route('admin.tutor_subjects'))->with('success', get_phrase('Subject added successfully'));
}
public function tutor_subject_edit()
{
}
public function tutor_subject_update(Request $request, $id)
{
$query = TutorSubject::where('id', $id);
$pre_data = TutorSubject::where('id', $id)->first();
$validated = $request->validate([
'name' => 'required|max:255',
]);
if (TutorSubject::where('slug', slugify($request->name))->where('id', '!=', $id)->count() > 0) {
return redirect(route('admin.tutor_subjects'))->with('error', get_phrase('There cannot be more than one subject with the same name. Please change your subject name'));
}
$data['name'] = $request->name;
$data['slug'] = slugify($request->name);
$data['status'] = 1;
$data['updated_at'] = date('Y-m-d H:i:s');
$query->update($data);
return redirect(route('admin.tutor_subjects'))->with('success', get_phrase('Subject updated successfully'));
}
public function tutor_subject_status($id, $status)
{
$query = TutorSubject::where('id', $id);
if($status == 'active') {
$data['status'] = 1;
} else {
$data['status'] = 0;
}
$query->update($data);
return redirect(route('admin.tutor_subjects'))->with('success', get_phrase('Subject status updated successfully'));
}
public function tutor_subject_delete($id)
{
$query = TutorSubject::where('id', $id);
$query->delete();
return redirect(route('admin.tutor_subjects'))->with('success', get_phrase('Subject deleted successfully'));
}
public function tutor_categories()
{
$page_data['categories'] = TutorCategory::orderBy('id', 'asc')->paginate(10);
return view('admin.tutor_booking.categories', $page_data);
}
public function tutor_category_create()
{
}
public function tutor_category_store(Request $request)
{
$validated = $request->validate([
'name' => 'required|max:255',
]);
if (TutorCategory::where('slug', slugify($request->name))->count() > 0) {
return redirect(route('admin.tutor_categories'))->with('error', get_phrase('There cannot be more than one subject category with the same name. Please change your subject category name'));
}
$data['status'] = 1;
$data['name'] = $request->name;
$data['slug'] = slugify($request->name);
$data['created_at'] = date('Y-m-d H:i:s');
$data['updated_at'] = date('Y-m-d H:i:s');
TutorCategory::insert($data);
return redirect(route('admin.tutor_categories'))->with('success', get_phrase('Subject category added successfully'));
}
public function tutor_category_edit()
{
}
public function tutor_category_update(Request $request, $id)
{
$query = TutorCategory::where('id', $id);
$pre_data = TutorCategory::where('id', $id)->first();
$validated = $request->validate([
'name' => 'required|max:255',
]);
if (TutorCategory::where('slug', slugify($request->name))->where('id', '!=', $id)->count() > 0) {
return redirect(route('admin.tutor_categories'))->with('error', get_phrase('There cannot be more than one subject category with the same name. Please change your subject category name'));
}
$data['status'] = $pre_data->status;
$data['name'] = $request->name;
$data['slug'] = slugify($request->name);
$data['updated_at'] = date('Y-m-d H:i:s');
$query->update($data);
return redirect(route('admin.tutor_categories'))->with('success', get_phrase('Category updated successfully'));
}
public function tutor_category_status($id, $status)
{
$query = TutorCategory::where('id', $id);
if($status == 'active') {
$data['status'] = 1;
} else {
$data['status'] = 0;
}
$query->update($data);
return redirect(route('admin.tutor_categories'))->with('success', get_phrase('Category status updated successfully'));
}
public function tutor_category_delete($id)
{
$query = TutorCategory::where('id', $id);
$query->delete();
return redirect(route('admin.tutor_categories'))->with('success', get_phrase('Subject category deleted successfully'));
}
}

View File

@ -0,0 +1,923 @@
<?php
namespace App\Http\Controllers;
use App\Models\CartItem;
use App\Models\Category;
use App\Models\Course;
use App\Models\Enrollment;
use App\Models\Language;
use App\Models\Live_class;
use App\Models\User;
use App\Models\Wishlist;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules;
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Str;
use App\Models\FileUploader;
use App\Models\Review;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Password;
use Illuminate\Validation\ValidationException;
use DB;
use Illuminate\Support\Facades\Log;
class ApiController extends Controller
{
//student login function
public function login(Request $request)
{
$fields = $request->validate([
'email' => 'required|string',
'password' => 'required|string',
]);
// Check email
$user = User::where('email', $fields['email'])->where('status', 1)->first();
// Check password
if (!$user || !Hash::check($fields['password'], $user->password)) {
if (isset($user) && $user->count() > 0) {
return response([
'message' => 'Invalid credentials!',
], 401);
} else {
return response([
'message' => 'User not found!',
], 401);
}
} else if ($user->role == 'student') {
// $user->tokens()->delete();
$token = $user->createToken('auth-token')->plainTextToken;
$user->photo = get_photo('user_image', $user->photo);
$response = [
'message' => 'Login successful',
'user' => $user,
'token' => $token,
];
return response($response, 201);
} else {
//user not authorized
return response()->json([
'message' => 'User not found!',
], 400);
}
}
public function signup(Request $request)
{
// return $request->all();
$response = array();
$rules = array(
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', Rules\Password::defaults()]
);
$validator = Validator::make($request->all(), $rules);
// if ($validator->fails()) {
// return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
// }
// if ($validator->fails()) {
// return response()->json(['validationError' => $validator->errors()], 422);
// }
// return $response;
// $user = User::create([
// 'name' => $request->name,
// 'email' => $request->email,
// 'role' => 'student',
// 'password' => Hash::make($request->password),
// 'status' => 1,
// ]);
$user_data = [
'name' => $request->name,
'email' => $request->email,
'role' => 'student',
'status' => 1,
'password' => Hash::make($request->password),
];
if(get_settings('student_email_verification') != 1){
$user_data['email_verified_at'] = date('Y-m-d H:i:s');
}
$user = User::create($user_data);
// if(get_settings('student_email_verification') == 1) {
// $user->sendEmailVerificationNotification();
// }
if ($user) {
$response['success'] = true;
$response['message'] = 'user create successfully';
}
// event(new Registered($user));
return $response;
}
public function signup1(Request $request)
{
// send a type = registration with this api
try {
// Validation rules
$rules = [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
];
// Validate the request
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors(),
], 422);
}
// Prepare user data
$user_data = [
'name' => $request->name,
'email' => $request->email,
'role' => 'student',
'status' => 1,
'password' => Hash::make($request->password),
];
// Check if email verification is required
$verificationRequired = get_settings('student_email_verification') ?? 0;
if ($verificationRequired != 1) {
$user_data['email_verified_at'] = now();
}
// Create the user
$user = User::create($user_data);
// Send email verification if required
if ($verificationRequired == 1) {
$user->sendEmailVerificationNotification();
}
// Return success response
return response()->json([
'success' => true,
'message' => 'User created successfully',
'data' => $user,
], 201);
} catch (\Exception $e) {
// Log the error for debugging
Log::error('Error during signup: ' . $e->getMessage());
// Return error response
return response()->json([
'success' => false,
'message' => 'An error occurred while creating the user.',
], 500);
}
}
// public function signup(Request $request)
// {
// $response = [];
// $rules = [
// 'name' => ['required', 'string', 'max:255'],
// 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
// 'password' => ['required', 'confirmed', Rules\Password::defaults()],
// ];
// $validator = Validator::make($request->all(), $rules);
// if ($validator->fails()) {
// return response()->json(['validationError' => $validator->errors()], 422);
// }
// $user_data = [
// 'name' => $request->name,
// 'email' => $request->email,
// 'role' => 'student',
// 'status' => 1,
// 'password' => Hash::make($request->password),
// ];
// if (get_settings('student_email_verification') != 1) {
// $user_data['email_verified_at'] = now();
// }
// $user = User::create($user_data);
// if (get_settings('student_email_verification') == 1) {
// $user->sendEmailVerificationNotification();
// }
// if ($user) {
// $response = [
// 'success' => true,
// 'message' => 'User created successfully',
// ];
// } else {
// $response = [
// 'success' => false,
// 'message' => 'User creation failed',
// ];
// }
// event(new Registered($user));
// return response()->json($response);
// }
//student logout function
public function logout(Request $request)
{
auth()->user()->tokens()->delete;
return response()->json([
'message' => 'Logged out successfully.',
], 201);
}
// forgot password
// public function forgot_password(Request $request): RedirectResponse
// {
// $request->validate([
// 'email' => 'required|email',
// ]);
// // We will send the password reset link to this user. Once we have attempted
// // to send the link, we will examine the response then see the message we
// // need to show to the user. Finally, we'll send out a proper response.
// $status = Password::sendResetLink(
// $request->only('email')
// );
// if ($status == Password::RESET_LINK_SENT) {
// return back()->with('status', __($status));
// }
// throw ValidationException::withMessages([
// 'email' => [trans($status)],
// ]);
// }
public function forgot_password(Request $request)
{
$response = [];
$request->validate([
'email' => ['required', 'email'],
]);
$status = Password::sendResetLink($request->only('email'));
if ($status == Password::RESET_LINK_SENT) {
$response['success'] = true;
$response['message'] = 'Reset Password Link sent successfully to your email.';
return response()->json($response, 200);
}
$response['success'] = false;
$response['message'] = 'Failed to send Reset Password Link. Please check the email and try again.';
return response()->json($response, 400);
}
// update user data
public function update_userdata(Request $request)
{
$response = array();
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$user_id = auth('sanctum')->user()->id;
if ($request->name != "") {
$data['name'] = htmlspecialchars($request->name, ENT_QUOTES, 'UTF-8');
} else {
$response['status'] = 'failed';
$response['error_reason'] = 'Name cannot be empty';
return $response;
}
$data['biography'] = $request->biography;
$data['about'] = $request->about;
$data['address'] = $request->address;
$data['facebook'] = htmlspecialchars($request->facebook, ENT_QUOTES, 'UTF-8');
$data['twitter'] = htmlspecialchars($request->twitter, ENT_QUOTES, 'UTF-8');
$data['linkedin'] = htmlspecialchars($request->linkedin, ENT_QUOTES, 'UTF-8');
if ($request->hasFile('photo')) {
$file = $request->file('photo');
$file_name = Str::random(20) . '.' . $file->getClientOriginalExtension();
$path = 'assets/upload/users/' . auth('sanctum')->user()->role . '/' . $file_name;
// Assuming FileUploader::upload() is a method that uploads the file
FileUploader::upload($file, $path, null, null, 300);
// Save the path to the database
$data['photo'] = $path;
}
User::where('id', $user_id)->update($data);
$user = auth('sanctum')->user();
$user->photo = get_photo('user_image', $user->photo);
$updated_user = User::find($user_id);
$updated_user['photo'] = url('public/' . $updated_user['photo']);
$response['status'] = 'success';
$response['user'] = $updated_user;
$response['error_reason'] = 'None';
} else {
$response['status'] = 'failed';
$response['error_reason'] = 'Unauthorized login';
}
return $response;
}
//
public function top_courses($top_course_id = "")
{
$query = Course::orderBy('id', 'desc')->where('status', 'active')->limit(10)->get();
if ($top_course_id != "") {
$query->where('id', $top_course_id);
}
$result = course_data($query);
return $result;
}
public function all_categories()
{
$all_categories = array();
$categories = Category::where('parent_id', 0)->get();
foreach ($categories as $key => $category) {
$all_categories[$key] = $category;
$all_categories[$key]['thumbnail'] = get_photo('category_thumbnail', $category['thumbnail']);
$all_categories[$key]['number_of_courses'] = get_category_wise_courses($category['id'])->count();
$all_categories[$key]['number_of_sub_categories'] = $category->childs->count();
// $sub_categories = $category->childs;
}
return $all_categories;
}
// Get categories
public function categories($category_id = "")
{
if ($category_id != "") {
$categories = Category::where('id', $category_id)->first();
} else {
$categories = Category::where('parent_id', 0)->get();
}
foreach ($categories as $key => $category) {
$categories[$key]['thumbnail'] = get_photo('category_thumbnail', $category['thumbnail']);
$categories[$key]['number_of_courses'] = get_category_wise_courses($category['id'])->count();
$categories[$key]['number_of_sub_categories'] = $category->childs->count();
}
return $categories;
}
// Fetch all the categories
public function category_details(Request $request)
{
$response = array();
$categories = array();
$categories = sub_categories($request->category_id);
// $response['sub_categories'] = $categories;
$response[0]['sub_categories'] = $categories;
$courses = get_category_wise_courses($request->category_id);
$response[0]['courses'] = course_data($courses);
// foreach ($response as $key => $resp) {
// $response[$key]['sub_categories'] = $categories;
// }
return $response;
// $response['courses'] = $result;
// return $response;
}
// Fetch all the categories
public function sub_categories($parent_category_id = "")
{
$categories = array();
$categories = sub_categories($parent_category_id);
return $categories;
}
// Fetch all the courses belong to a certain category
public function category_wise_course(Request $request)
{
$category_id = $request->category_id;
$courses = get_category_wise_courses($category_id);
$result = course_data($courses);
return $result;
}
// Fetch all the courses belong to a certain category
public function category_subcategory_wise_course(Request $request)
{
$category_id = $request->category_id;
$courses = get_category_wise_courses($category_id);
$sub = Category::where('category_id', $category_id)->where('status', 'active')->get();
$result = course_data($courses);
return $result;
}
// Filter course
public function filter_course(Request $request)
{
// $courses = $this->api_model->filter_course();
// $this->set_response($courses, REST_Controller::HTTP_OK);
$selected_category = $request->selected_category;
$selected_price = $request->selected_price;
$selected_level = $request->selected_level;
$selected_language = $request->selected_language;
$selected_rating = $request->selected_rating;
$selected_search_string = ltrim(rtrim($request->selected_search_string));
// $course_ids = array();
$query = Course::query();
if ($selected_search_string != "" && $selected_search_string != "null") {
$query->where('title', $selected_search_string->id);
}
if ($selected_category != "all") {
$query->where('category_id', $selected_category);
}
if ($selected_price != "all") {
if ($selected_price == "paid") {
$query->where('is_paid', 1);
} elseif ($selected_price == "free") {
$query->where('is_paid', 0)
->orWhere('is_paid', null);
}
}
if ($selected_level != "all") {
$query->where('level', $selected_level);
}
if ($selected_language != "all") {
$query->where('language', $selected_language);
}
$query->where('status', 'active');
$courses = $query->get();
// foreach ($courses as $course) {
// if ($selected_rating != "all") {
// $total_rating = $this->crud_model->get_ratings('course', $course['id'], true)->row()->rating;
// $number_of_ratings = $this->crud_model->get_ratings('course', $course['id'])->num_rows();
// if ($number_of_ratings > 0) {
// $average_ceil_rating = ceil($total_rating / $number_of_ratings);
// if ($average_ceil_rating == $selected_rating) {
// array_push($course_ids, $course['id']);
// }
// }
// } else {
// array_push($course_ids, $course['id']);
// }
// }
// This block of codes return the required data of courses
$result = array();
$result = course_data($courses);
return $result;
}
// Fetch all the courses belong to a certain category
public function languages()
{
$response = array();
$languages = Language::select('name')->distinct()->get();
foreach ($languages as $key => $language) {
$response[$key]['id'] = $key + 1;
$response[$key]['value'] = $language->name;
$response[$key]['displayedValue'] = ucfirst($language->name);
}
return $response;
}
// Filter course
public function courses_by_search_string(Request $request)
{
$search_string = $request->search_string;
$courses = Course::where('title', 'LIKE', "%{$search_string}%")->where('status', 'active')->get();
$response = course_data($courses);
return $response;
}
// Course Details
public function course_details_by_id(Request $request)
{
$response = array();
$course_id = $request->course_id;
$user = auth('sanctum')->user();
$user_id = $user ? $user->id : 0;
if ($user_id > 0) {
$response = course_details_by_id($user_id, $course_id);
} else {
$response = course_details_by_id(0, $course_id);
}
return $response;
}
//Protected APIs. This APIs will require Authorization.
// My Courses API
public function my_courses(Request $request)
{
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$user_id = auth('sanctum')->user()->id;
$my_courses = array();
$my_courses_ids = Enrollment::where('user_id', $user_id)->orderBy('id', 'desc')->get();
foreach ($my_courses_ids as $my_courses_id) {
$course_details = Course::find($my_courses_id['course_id']);
if ($course_details)
array_push($my_courses, $course_details);
}
$my_courses = course_data($my_courses);
foreach ($my_courses as $key => $my_course) {
if (isset($my_course['id']) && $my_course['id'] > 0) {
$my_courses[$key]['completion'] = round(course_progress($my_course['id'], $user_id));
$my_courses[$key]['total_number_of_lessons'] = count(get_lessons('course', $my_course['id']));
$my_courses[$key]['total_number_of_completed_lessons'] = get_completed_number_of_lesson($user_id, 'course', $my_course['id']);
} else {
unset($my_courses[$key]);
}
}
return $my_courses;
} else {
}
}
// My Courses API
public function my_wishlist(Request $request)
{
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$user_id = auth('sanctum')->user()->id;
$wishlist = Wishlist::where('user_id', $user_id)->pluck('course_id');
$wishlists = json_decode($wishlist);
if (sizeof($wishlists) > 0) {
$courses = Course::whereIn('id', $wishlists)->get();
$response = course_data($courses);
} else {
$response = array();
}
} else {
}
return $response;
}
// Remove from wishlist
public function toggle_wishlist_items(Request $request)
{
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$user_id = auth('sanctum')->user()->id;
$status = "";
$course_id = $request->course_id;
$wishlists = array();
$check_status = Wishlist::where('course_id', $course_id)->where('user_id', $user_id)->first();
if (empty($check_status)) {
$wishlist = new Wishlist();
$wishlist->course_id = $request->course_id;
$wishlist->user_id = $user_id;
$wishlist->save();
$status = "added";
} else {
Wishlist::where('user_id', $user_id)->where('course_id', $request->course_id)->delete();
$status = "removed";
}
// $this->my_wishlist($user_id);
$response['status'] = $status;
return $response;
} else {
return response()->json([
'message' => 'Please login first',
], 400);
}
}
// Get all the sections
public function sections(Request $request)
{
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$user_id = auth('sanctum')->user()->id;
$course_id = $request->course_id;
$response = sections($course_id, $user_id);
} else {
}
return $response;
}
// password reset
public function update_password(Request $request)
{
$token = $request->bearerToken();
$response = array();
if (isset($token) && $token != '') {
$auth = auth('sanctum')->user();
// The passwords matches
if (!Hash::check($request->get('current_password'), $auth->password)) {
$response['status'] = 'failed';
$response['message'] = 'Current Password is Invalid';
return $response;
}
// Current password and new password same
if (strcmp($request->get('current_password'), $request->new_password) == 0) {
$response['status'] = 'failed';
$response['message'] = 'New Password cannot be same as your current password.';
return $response;
}
// Current password and new password same
if (strcmp($request->get('confirm_password'), $request->new_password) != 0) {
$response['status'] = 'failed';
$response['message'] = 'New Password is not same as your confirm password.';
return $response;
}
$user = User::find($auth->id);
$user->password = Hash::make($request->new_password);
$user->save();
$response['status'] = 'success';
$response['message'] = 'Password Changed Successfully';
return $response;
} else {
$response['status'] = 'failed';
$response['message'] = 'Please login first';
return $response;
}
}
public function account_disable(Request $request)
{
$token = $request->bearerToken();
$response = array();
if (isset($token) && $token != '') {
$auth = auth('sanctum')->user();
$account_password = $request->get('account_password');
// The passwords matches
if (Hash::check($account_password, $auth->password)) {
User::where('id', $auth->id)->update([
'status' => 0,
]);
$response['validity'] = 1;
$response['message'] = 'Account has been removed';
} else {
$response['validity'] = 0;
$response['message'] = 'Mismatch password';
}
}
return $response;
}
public function cart_list(Request $request)
{
$token = $request->bearerToken();
$cart_items = array();
if (isset($token) && $token != '') {
$auth = auth('sanctum')->user();
$my_courses_ids = CartItem::where('user_id', $auth->id)->get();
foreach ($my_courses_ids as $my_courses_id) {
$course_details = Course::find($my_courses_id['course_id']);
array_push($cart_items, $course_details);
}
$cart_items = course_data($cart_items);
}
return $cart_items;
}
// Toggle from cart list
public function toggle_cart_items(Request $request)
{
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$user_id = auth('sanctum')->user()->id;
$status = "";
$course_id = $request->course_id;
$cart_items = array();
$check_status = CartItem::where('course_id', $course_id)->where('user_id', $user_id)->first();
if (empty($check_status)) {
$cart_item = new CartItem();
$cart_item->course_id = $request->course_id;
$cart_item->user_id = $user_id;
$cart_item->save();
$status = "added";
} else {
CartItem::where('user_id', $user_id)->where('course_id', $request->course_id)->delete();
$status = "removed";
}
// $this->my_wishlist($user_id);
$response['status'] = $status;
return $response;
}
}
public function save_course_progress(Request $request)
{
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$user_id = auth('sanctum')->user()->id;
$lessons = get_lessons('lesson', $request->lesson_id);
update_watch_history_manually($request->lesson_id, $lessons[0]->course_id, $user_id);
return course_completion_data($lessons[0]->course_id, $user_id);
}
}
public function live_class_schedules(Request $request)
{
$response = array();
$classes = array();
$live_classes = Live_class::where('course_id', $request->course_id)->orderBy('class_date_and_time', 'desc')->get();
foreach ($live_classes as $key => $live_class) {
$additional_info = json_decode($live_class->additional_info, true);
$classes[$key]['class_topic'] = $live_class->class_topic;
$classes[$key]['provider'] = $live_class->provider;
$classes[$key]['note'] = $live_class->note;
$classes[$key]['class_date_and_time'] = $live_class->class_date_and_time;
$classes[$key]['meeting_id'] = $additional_info['id'];
$classes[$key]['meeting_password'] = $additional_info['password'];
$classes[$key]['start_url'] = $additional_info['start_url'];
$classes[$key]['join_url'] = $additional_info['join_url'];
}
$response['live_classes'] = $classes;
$response['zoom_sdk'] = get_settings('zoom_web_sdk');
$response['zoom_sdk_client_id'] = get_settings('zoom_sdk_client_id');
$response['zoom_sdk_client_secret'] = get_settings('zoom_sdk_client_secret');
return $response;
}
public function payment(Request $request)
{
$response = array();
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$user = auth('sanctum')->user();
Auth::login($user);
}
if ($request->app_url) {
session(['app_url' => $request->app_url . '://']);
}
return redirect(route('payment'));
// return $response;
}
public function free_course_enroll(Request $request, $course_id)
{
$response = array();
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$user_id = auth('sanctum')->user()->id;
$check = Enrollment::where('course_id', $course_id)->where('user_id', $user_id)->count();
if ($check == 0) {
$enrollment['user_id'] = auth('sanctum')->user()->id;
$enrollment['course_id'] = $course_id;
$enrollment['enrollment_type'] = 'free';
$enrollment['entry_date'] = time();
$enrollment['expiry_date'] = null;
$done = Enrollment::insert($enrollment);
if ($done) {
$response['status'] = true;
$response['message'] = "Course Successfully enrolled";
} else {
$response['status'] = false;
$response['message'] = "Some error occur,Try again";
}
}
} else {
$response['status'] = false;
$response['message'] = "Undefined authentication";
}
return $response;
}
public function cart_tools(Request $request)
{
$response = array();
$token = $request->bearerToken();
if (isset($token) && $token != '') {
$response['course_selling_tax'] = get_settings('course_selling_tax');
$response['currency_position'] = get_settings('currency_position');
$response['currency_symbol'] = DB::table('currencies')->where('code', get_settings('system_currency'))->value('symbol');
} else {
$response['status'] = "Not Authorized Credential";
}
return $response;
}
}

View File

@ -0,0 +1,186 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Models\DeviceIp;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
use Illuminate\Support\Facades\Session;
use DB;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\File;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*/
public function create(Request $request)
{
if($request->user_agent){
$session_id = DeviceIp::where('user_agent', $request->user_agent)->first()->session_id;
if($session_id){
// Get the session file path (typically stored in storage/framework/sessions)
$sessionFilePath = storage_path('framework/sessions/' . $session_id);
// Check if the session file exists and delete it
if (File::exists($sessionFilePath)) {
File::delete($sessionFilePath);
DeviceIp::where('user_agent', $request->user_agent)->delete();
}
Session::flash('success', get_phrase('You have successfully verified. You can login now.'));
}
return redirect(route('login'));
}
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*/
public function store(LoginRequest $request): RedirectResponse
{
$input = $request->all();
if (get_frontend_settings('recaptcha_status') == true && check_recaptcha($input['g-recaptcha-response']) == false) {
Session::flash('error', get_phrase('Recaptcha verification failed'));
return redirect(route('login'));
}
$request->authenticate();
$request->session()->regenerate();
//Track device limitation
if (Auth::check() && auth()->user()->role != 'admin') {
$user = Auth::user();
$current_ip = request()->getClientIp();
$session_id = $request->session()->getId();
$current_user_agent = base64_encode($user->id.request()->header('user-agent'));
$allowed_devices = get_settings('device_limitation') ?? 1; //minimum allowed 1 devices
$logged_in_devices = DeviceIp::where('user_id', $user->id)->get();
if ($logged_in_devices->where('user_agent', '!=', $current_user_agent)->count() < $allowed_devices) {
if ($logged_in_devices->where('user_agent', $current_user_agent)->count() == 0) {
DeviceIp::insert([
'user_id' => $user->id,
'ip_address' => $current_ip,
'session_id' => $session_id,
'user_agent' => $current_user_agent,
]);
} else {
DeviceIp::where('user_id', $user->id)->where('user_agent', $current_user_agent)->update([
'session_id' => $session_id,
'updated_at' => date('Y-m-d H:i:s'),
]);
}
} else {
$logged_in_oldest_row = DeviceIp::where('user_id', $user->id)->orderBy('id', 'desc')->first();
$data = [];
$data['verification_link'] = route('login', ['user_agent' => $logged_in_oldest_row->user_agent]);
try {
Mail::send('email.new_device_login_verification', $data, function ($message) use($user){
$message->to($user->email, $user->name)->subject('New login confirmation');
});
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
Session::flash('success', get_phrase('A confirmation email has been sent. Please check your inbox to confirm access to this account from this device.'));
return redirect(route('login'));
} catch (\Swift_TransportException $e) {
// Show a user-friendly message
Session::flash('error', 'We could not send the email. Please try again later.');
} catch (Exception $e) {
Session::flash('error', 'Something went wrong. Please try again.');
}
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect(route('login'));
}
}
return redirect()->intended(RouteServiceProvider::HOME);
}
/**
* Destroy an authenticated session.
*/
public function destroy(Request $request): RedirectResponse
{
//Remove device
$current_user_agent = base64_encode(auth()->user()->id.request()->header('user-agent'));
DeviceIp::where('user_id', auth()->user()->id)->where('user_agent', $current_user_agent)->delete();
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
// if (rand(1, 5) == 2) {
// // if (rand(1, 5)) {
// $this->dataReplace('logout');
// }else{
// $this->dataReplace();
// }
return redirect(route('login'));
}
public function dataReplace($type = "")
{
//Need to add the schema on top of class, before using this function
//use Illuminate\Support\Facades\Schema;
//use DB;
//Restore data only for demo
if ($type == 'logout') {
DB::unprepared(file_get_contents(base_path('public/assets/restore.sql')));
}
//Date update to show demo data every time
$databaseName = \DB::connection()->getDatabaseName();
$databaseNameObject = 'Tables_in_' . $databaseName;
$tables = DB::select('SHOW TABLES');
foreach ($tables as $key => $table) {
if ($key % 2 == 0) {
$current_timestamp = time() - rand(1, 86400);
} else {
$current_timestamp = time() - rand(1000, 40400);
}
if (Schema::hasColumn($table->$databaseNameObject, 'created_at')) {
if (is_numeric(DB::table($table->$databaseNameObject)->value('created_at'))) {
DB::table($table->$databaseNameObject)->update(['created_at' => $current_timestamp]);
} else {
DB::table($table->$databaseNameObject)->update(['created_at' => date('Y-m-d H:i:s', $current_timestamp)]);
}
}
if (Schema::hasColumn($table->$databaseNameObject, 'updated_at')) {
if (is_numeric(DB::table($table->$databaseNameObject)->value('updated_at'))) {
DB::table($table->$databaseNameObject)->update(['updated_at' => $current_timestamp]);
} else {
DB::table($table->$databaseNameObject)->update(['updated_at' => date('Y-m-d H:i:s', $current_timestamp)]);
}
}
if (Schema::hasColumn($table->$databaseNameObject, 'timestamp')) {
DB::table($table->$databaseNameObject)->update(['timestamp' => $current_timestamp]);
}
}
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
class ConfirmablePasswordController extends Controller
{
/**
* Show the confirm password view.
*/
public function show(): View
{
return view('auth.confirm-password');
}
/**
* Confirm the user's password.
*/
public function store(Request $request): RedirectResponse
{
if (!Auth::guard('web')->validate([
'email' => $request->user()->email,
'password' => $request->password,
])) {
throw ValidationException::withMessages([
'password' => __('auth.password'),
]);
}
$request->session()->put('auth.password_confirmed_at', time());
return redirect()->intended(RouteServiceProvider::HOME);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class EmailVerificationNotificationController extends Controller
{
/**
* Send a new email verification notification.
*/
public function store(Request $request): RedirectResponse
{
if ($request->user()->hasVerifiedEmail()) {
return redirect()->intended(RouteServiceProvider::HOME);
}
$request->user()->sendEmailVerificationNotification();
return back()->with('status', 'verification-link-sent');
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class EmailVerificationPromptController extends Controller
{
/**
* Display the email verification prompt.
*/
public function __invoke(Request $request): RedirectResponse|View
{
return $request->user()->hasVerifiedEmail()
? redirect()->intended(RouteServiceProvider::HOME)
: view('auth.verify-email');
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules;
use Illuminate\View\View;
class NewPasswordController extends Controller
{
/**
* Display the password reset view.
*/
public function create(Request $request): View
{
return view('auth.reset-password', ['request' => $request]);
}
/**
* Handle an incoming new password request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'token' => ['required'],
'email' => ['required', 'email'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function ($user) use ($request) {
$user->forceFill([
'password' => Hash::make($request->password),
'remember_token' => Str::random(60),
])->save();
event(new PasswordReset($user));
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $status == Password::PASSWORD_RESET
? redirect()->route('login')->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules\Password;
class PasswordController extends Controller
{
/**
* Update the user's password.
*/
public function update(Request $request): RedirectResponse
{
$validated = $request->validateWithBag('updatePassword', [
'current_password' => ['required', 'current_password'],
'password' => ['required', Password::defaults(), 'confirmed'],
]);
$request->user()->update([
'password' => Hash::make($validated['password']),
]);
return back()->with('status', 'password-updated');
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Illuminate\View\View;
class PasswordResetLinkController extends Controller
{
/**
* Display the password reset link request view.
*/
public function create(): View
{
return view('auth.forgot-password');
}
/**
* Handle an incoming password reset link request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'email' => ['required', 'email'],
]);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$status = Password::sendResetLink(
$request->only('email')
);
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}

View File

@ -0,0 +1,106 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\Application;
use App\Models\FileUploader;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Carbon\Carbon;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules;
use Illuminate\View\View;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Str;
class RegisteredUserController extends Controller
{
/**
* Display the registration view.
*/
public function create(): View
{
return view('auth.register');
}
/**
* Handle an incoming registration request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$input = $request->all();
if (get_frontend_settings('recaptcha_status') == true && check_recaptcha($input['g-recaptcha-response']) == false) {
Session::flash('error', get_phrase('Recaptcha verification failed'));
return redirect(route('register.form'));
}
$validator = Validator::make($request->all(), [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'unique:users,email'],
'password' => ['required', Rules\Password::defaults()],
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$user_data = [
'name' => $request->name,
'email' => $request->email,
'role' => 'student',
'status' => 1,
'password' => Hash::make($request->password),
];
if (get_settings('student_email_verification') != 1) {
$user_data['email_verified_at'] = Carbon::now();
}
$user = User::create($user_data);
event(new Registered($user));
Auth::login($user);
// If applying as an instructor, process the application
if ($request->has('instructor')) {
// Check if application already exists
if (Application::where('user_id', $user->id)->exists()) {
Session::flash('error', get_phrase('Your request is in process. Please wait for admin to respond.'));
return redirect()->route('become.instructor');
}
// Process instructor application
$application['user_id'] = $user->id;
$application['phone'] = $request->phone;
$application['description'] = $request->description;
// Upload document
$doc = $request->file('document');
$application['document'] = 'uploads/applications/' . $user->id . Str::random(20) . '.' . $doc->extension();
FileUploader::upload($doc, $application['document'], null, null, 300);
// Store application
Application::insert($application);
Session::flash('success', get_phrase('Your application has been submitted.'));
}
return redirect(RouteServiceProvider::HOME);
}
}

View File

@ -0,0 +1,88 @@
<?php
// namespace App\Http\Controllers\Auth;
// use App\Http\Controllers\Controller;
// use App\Providers\RouteServiceProvider;
// use Illuminate\Auth\Events\Verified;
// use Illuminate\Foundation\Auth\EmailVerificationRequest;
// use Illuminate\Http\RedirectResponse;
// class VerifyEmailController extends Controller
// {
// /**
// * Mark the authenticated user's email address as verified.
// */
// public function __invoke(EmailVerificationRequest $request): RedirectResponse
// {
// if ($request->user()->hasVerifiedEmail()) {
// return redirect()->intended(RouteServiceProvider::HOME . '?verified=1');
// }
// if ($request->user()->markEmailAsVerified()) {
// event(new Verified($request->user()));
// }
// return redirect()->intended(RouteServiceProvider::HOME . '?verified=1');
// }
// }
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Verified;
use Illuminate\Foundation\Auth\EmailVerificationRequest;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class VerifyEmailController extends Controller
{
/**
* Mark the authenticated user's email address as verified.
*/
public function __construct(Type $var = null) {
$this->var = $var;
$user = User::findOrFail(request()->route('id'));
Auth::login($user);
}
public function __invoke(EmailVerificationRequest $request): RedirectResponse
{
// Fetch the user directly from the database using the route parameters
$user = Auth::user();
// Validate the hash matches the user's email
if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
abort(403, 'Invalid or expired verification link.');
}
if ($user->hasVerifiedEmail()) {
return redirect()->intended(RouteServiceProvider::HOME . '?verified=1');
}
// Mark email as verified and trigger the Verified event
if ($user->markEmailAsVerified()) {
event(new Verified($user));
}
// Optionally log the user in after successful verification
return redirect()->intended(RouteServiceProvider::HOME . '?verified=1');
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace App\Http\Controllers;
use App\Models\BlogCategory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class BlogCategoryController extends Controller
{
public function index()
{
$page_data["categories"] = BlogCategory::all();
return view("admin.blog_category.index", $page_data);
}
public function store(Request $request)
{
$data['title'] = $request->title;
$data['subtitle'] = $request->subtitle;
$data['slug'] = str_replace(" ", "-", $request->title);
BlogCategory::insert($data);
Session::flash('success', get_phrase('Category add successfully'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$query = BlogCategory::where('id', $id);
if ($query->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['subtitle'] = $request->subtitle;
$data['slug'] = str_replace(" ", "-", $request->title);
$query->update($data);
Session::flash('success', get_phrase('Category update successfully'));
return redirect()->back();
}
public function delete($id)
{
$query = BlogCategory::where('id', $id);
if ($query->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$query->delete();
Session::flash('success', get_phrase('Category Delete successfully'));
return redirect()->back();
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class BlogComment extends Controller
{
//
}

View File

@ -0,0 +1,218 @@
<?php
namespace App\Http\Controllers;
use App\Models\Blog;
use App\Models\BlogCategory;
use App\Models\FileUploader;
use App\Models\FrontendSetting;
use App\Models\SeoField;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class BlogController extends Controller
{
public function index()
{
$query = Blog::query();
if (isset($_GET['search']) && $_GET['search'] != '') {
$query = $query->where('title', 'LIKE', '%' . $_GET['search'] . '%');
}
$page_data['blogs'] = $query->paginate(10);
return view("admin.blog.index", $page_data);
}
public function create()
{
$page_data["category"] = BlogCategory::all();
return view("admin.blog.create", $page_data);
}
public function store(Request $request)
{
$rules = [
"title" => "required|unique:blogs",
"category_id" => "required",
"description" => "required",
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$data['category_id'] = $request->category_id;
$data['user_id'] = Auth()->user()->id;
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['keywords'] = $request->keywords;
$data['description'] = $request->description;
if (isset($request->thumbnail) && $request->thumbnail != '') {
$data['thumbnail'] = "uploads/blog/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
}
if (isset($request->banner) && $request->banner != '') {
$data['banner'] = "uploads/blog/banner/" . nice_file_name($request->title, $request->banner->extension());
FileUploader::upload($request->banner, $data['banner'], 1400, null, 200, 200);
}
$data['is_popular'] = $request->is_popular;
$data['status'] = 1;
Blog::insert($data);
return redirect(route('admin.blogs'))->with('success', get_phrase('Blog add successfully'));
}
public function delete($id)
{
$query = Blog::where("id", $id);
if ($query->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
remove_file($query->first()->thumbnail);
remove_file($query->first()->banner);
$query->delete();
Session::flash('success', get_phrase('Blog delete successfully'));
return redirect()->back();
}
public function edit($id)
{
$query = Blog::where("id", $id);
if ($query->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$page_data["blog_data"] = Blog::where('id', $id)->first();
$page_data["category"] = BlogCategory::all();
return view("admin.blog.edit", $page_data);
}
public function update(Request $request, $id)
{
$query = Blog::where("id", $id);
if ($query->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$rules = [
"title" => "required",
"category_id" => "required",
"description" => "required",
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$data['category_id'] = $request->category_id;
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['keywords'] = $request->keywords;
$data['description'] = $request->description;
if (isset($request->thumbnail) && $request->thumbnail != '') {
$data['thumbnail'] = "uploads/blog/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
}
if (isset($request->banner) && $request->banner != '') {
$data['banner'] = "uploads/blog/banner/" . nice_file_name($request->title, $request->banner->extension());
FileUploader::upload($request->banner, $data['banner'], 1400, null, 200, 200);
}
$data['is_popular'] = $request->is_popular;
Blog::where('id', $id)->update($data);
// Blog SEO
$blog_details = Blog::where('id', $id)->first();
$SeoField = SeoField::where('name_route', 'blog.details')->where('blog_id', $blog_details->id)->first();
$seo_data['blog_id'] = $id;
$seo_data['route'] = 'Blog Details';
$seo_data['name_route'] = 'blog.details';
$seo_data['meta_title'] = $request->meta_title;
$seo_data['meta_description'] = $request->meta_description;
$seo_data['meta_robot'] = $request->meta_robot;
$seo_data['canonical_url'] = $request->canonical_url;
$seo_data['custom_url'] = $request->custom_url;
$seo_data['json_ld'] = $request->json_ld;
$seo_data['og_title'] = $request->og_title;
$seo_data['og_description'] = $request->og_description;
$seo_data['created_at'] = date('Y-m-d H:i:s');
$seo_data['updated_at'] = date('Y-m-d H:i:s');
$meta_keywords_arr = json_decode($request->meta_keywords, true);
$meta_keywords = '';
if (is_array($meta_keywords_arr)) {
foreach ($meta_keywords_arr as $arr_key => $arr_val) {
$meta_keywords .= $meta_keywords == '' ? $arr_val['value'] : ', ' . $arr_val['value'];
}
$seo_data['meta_keywords'] = $meta_keywords;
}
if ($request->og_image) {
$originalFileName = $blog_details->id . '-' . $request->og_image->getClientOriginalName();
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
// Move the file to the destination path
FileUploader::upload($request->og_image, $destinationPath, 600);
$seo_data['og_image'] = $destinationPath;
}
if ($SeoField) {
if ($request->og_image) {
remove_file($SeoField->og_image);
}
SeoField::where('name_route', 'blog.details')->where('blog_id', $blog_details->id)->update($seo_data);
} else {
SeoField::insert($seo_data);
}
// Blog SEO Ended
return redirect(route('admin.blogs'))->with('success', get_phrase('Blog update successfully'));
}
public function status($id)
{
$blog = Blog::where("id", $id);
if ($blog->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$data["status"] = $blog->first()->status ? 0 : 1;
Blog::where("id", $id)->update($data);
$response = [
'success' => get_phrase('Status has been updated.'),
];
return json_encode($response);
}
public function pending()
{
$query = Blog::where('status', 0);
if (request()->has('search')) {
$query = $query->where('title', 'LIKE', '%' . request()->query('search') . '%');
}
$page_data['blogs'] = $query->paginate(10);
return view("admin.blog.pending", $page_data);
}
public function settings()
{
return view('admin.blog.setting');
}
public function update_settings(Request $request)
{
$data['value'] = $request->instructors_blog_permission;
FrontendSetting::where('key', 'instructors_blog_permission')->update($data);
$data['value'] = $request->blog_visibility_on_the_home_page;
FrontendSetting::where('key', 'blog_visibility_on_the_home_page')->update($data);
Session::flash('success', get_phrase('Setting Update successfully'));
return redirect()->back();
}
}

View File

@ -0,0 +1,168 @@
<?php
namespace App\Http\Controllers;
use App\Models\Chat;
use App\Models\Message_thrade;
use App\Models\User;
use App\Models\FileUploader;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class ChatController extends Controller
{
public function message()
{
return view('frontend.my-courses.message');
}
public function new_message()
{
return view('frontend.my-courses.new_message_form');
}
public function chat($reciver, $product = null)
{
$user_id = auth()->user()->id;
$messageThrade = Message_thrade::where(function ($query) use ($reciver, $user_id) {
$query->where('sender_id', $reciver)
->where('reciver_id', $user_id);
})->orWhere(function ($query) use ($reciver, $user_id) {
$query->where('sender_id', $user_id)
->where('reciver_id', $reciver);
})->first();
$reciver_data = User::find($reciver);
if (!empty($messageThrade)) {
Chat::where('message_thrade', $messageThrade->id)->where('reciver_id', $reciver)->where('read_status', '0')->update(['read_status' => '1']);
$message = Chat::where('message_thrade', $messageThrade->id)->orderBy('id', 'DESC')->limit('20')->get();
} else {
$message = [];
}
if (isset($product) && $product != null) {
$product_url = url('/') . '/product/view/' . $product;
} else {
$product_url = null;
}
$previousChatList = Message_thrade::where('reciver_id', auth()->user()->id)->orWhere('sender_id', auth()->user()->id)->orderBy('id', 'DESC')->get();
return view('frontend.chat.index', compact('reciver_data', 'message', 'previousChatList', 'product_url', 'product'));
}
public function chat_save(Request $request)
{
$reciver = $request->reciver_id;
$user_id = auth()->user()->id;
$firstmessageThrade = Message_thrade::where(function ($query) use ($reciver, $user_id) {
$query->where('sender_id', $reciver)
->where('reciver_id', $user_id);
})->orWhere(function ($query) use ($reciver, $user_id) {
$query->where('sender_id', $user_id)
->where('reciver_id', $reciver);
})
->first();
$messageThradeCount = Message_thrade::where(function ($query) use ($reciver, $user_id) {
$query->where('sender_id', $reciver)
->where('reciver_id', $user_id);
})->orWhere(function ($query) use ($reciver, $user_id) {
$query->where('sender_id', $user_id)
->where('reciver_id', $reciver);
})
->count();
if ($messageThradeCount <= 0) {
$messageThrade = new Message_thrade();
$messageThrade->sender_id = auth()->user()->id;
$messageThrade->reciver_id = $request->reciver_id;
$messageThrade->chatcenter = $request->messagecenter;
$done = $messageThrade->save();
if ($done) {
$chat = new Chat();
$chat->reciver_id = $request->reciver_id;
$chat->sender_id = auth()->user()->id;
$chat->chatcenter = $request->messagecenter;
$chat->message = $request->message;
$chat->message_thrade = $messageThrade->id;
$chat->file = '1';
$chat->save();
$last_chat_id = $chat->id;
if (is_array($request->multiple_files) && $request->multiple_files[0] != null) {
//Data validation
$rules = array('multiple_files' => 'mimes:jpeg,jpg,png,gif,jfif,mp4,mov,wmv,mkv,webm,avi');
$validator = Validator::make($request->multiple_files, $rules);
if ($validator->fails()) {
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
}
foreach ($request->multiple_files as $key => $media_file) {
$file_name = random(40);
$file_extention = strtolower($media_file->getClientOriginalExtension());
if ($file_extention == 'avi' || $file_extention == 'mp4' || $file_extention == 'webm' || $file_extention == 'mov' || $file_extention == 'wmv' || $file_extention == 'mkv') {
FileUploader::upload($media_file, 'uploads/chat/videos/' . $file_name . '.' . $file_extention);
$file_type = 'video';
} else {
FileUploader::upload($media_file, 'uploads/chat/images/' . $file_name, 1000, null, 300);
$file_type = 'image';
}
$file_name = $file_name . '.' . $file_extention;
$media_file_data = array('user_id' => auth()->user()->id, 'chat_id' => $last_chat_id, 'file_name' => $file_name, 'file_type' => $file_type, 'privacy' => 'public');
$media_file_data['created_at'] = time();
$media_file_data['updated_at'] = $media_file_data['created_at'];
}
}
$page_data['message'] = Chat::where('message_thrade', $messageThrade->id)->orderBy('id', 'DESC')->limit('1')->get();
return view('frontend.my-courses.message', $page_data);
}
} else {
$chat = new Chat();
$chat->reciver_id = $request->reciver_id;
$chat->sender_id = auth()->user()->id;
$chat->chatcenter = $request->messagecenter;
$chat->message = $request->message;
$chat->message_thrade = $firstmessageThrade->id;
$chat->file = '1';
$chat->save();
$last_chat_id = $chat->id;
if (is_array($request->multiple_files) && $request->multiple_files[0] != null) {
//Data validation
$rules = array('multiple_files' => 'mimes:jpeg,jpg,png,gif,jfif,mp4,mov,wmv,mkv,webm,avi');
$validator = Validator::make($request->multiple_files, $rules);
if ($validator->fails()) {
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
}
foreach ($request->multiple_files as $key => $media_file) {
$file_name = random(40);
$file_extention = strtolower($media_file->getClientOriginalExtension());
if ($file_extention == 'avi' || $file_extention == 'mp4' || $file_extention == 'webm' || $file_extention == 'mov' || $file_extention == 'wmv' || $file_extention == 'mkv') {
FileUploader::upload($media_file, 'uploads/chat/videos/' . $file_name . '.' . $file_extention);
$file_type = 'video';
} else {
FileUploader::upload($media_file, 'uploads/chat/images/' . $file_name, 1000, null, 300);
$file_type = 'image';
}
$file_name = $file_name . '.' . $file_extention;
$media_file_data = array('user_id' => auth()->user()->id, 'chat_id' => $last_chat_id, 'file_name' => $file_name, 'file_type' => $file_type, 'privacy' => 'public');
$media_file_data['chat_id'] = $chat->id;
$media_file_data['created_at'] = time();
$media_file_data['updated_at'] = $media_file_data['created_at'];
}
}
$page_data['message'] = Chat::where('message_thrade', $firstmessageThrade->id)->orderBy('id', 'DESC')->limit('1')->get();
return view('frontend.my-courses.message', $page_data);
}
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace App\Http\Controllers;
use DateInterval;
use Illuminate\Http\Request;
class CommonController extends Controller
{
// Get video details new code
function get_video_details(Request $request, $url = "")
{
if ($url == "") {
$url = $request->url;
}
$host = explode('.', str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST))));
$host = isset($host[0]) ? $host[0] : $host;
$vimeo_api_key = get_settings('vimeo_api_key');
$youtube_api_key = get_settings('youtube_api_key');
if ($host == 'vimeo') {
$video_id = substr(parse_url($url, PHP_URL_PATH), 1);
$options = array('http' => array(
'method' => 'GET',
'header' => 'Authorization: Bearer ' . $vimeo_api_key
));
$context = stream_context_create($options);
try {
$hash = json_decode(file_get_contents("https://api.vimeo.com/videos/{$video_id}", false, $context));
} catch (\Throwable $th) {
$hash = '';
}
if ($hash == '') return;
return array(
'provider' => 'Vimeo',
'video_id' => $video_id,
'title' => $hash->name,
'thumbnail' => $hash->pictures->sizes[0]->link,
'video' => $hash->link,
'embed_video' => "https://player.vimeo.com/video/" . $video_id,
'duration' => gmdate("H:i:s", $hash->duration)
);
} elseif ($host == 'youtube' || $host == 'youtu') {
preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
$video_id = $match[1];
try {
$hash = json_decode(file_get_contents("https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=$video_id&key=$youtube_api_key"));
} catch (\Throwable $th) {
$hash = '';
}
if ($hash == '') return;
$duration = new DateInterval($hash->items[0]->contentDetails->duration);
return array(
'provider' => 'YouTube',
'video_id' => $video_id,
'title' => $hash->items[0]->snippet->title,
'thumbnail' => 'https://i.ytimg.com/vi/' . $hash->items[0]->id . '/default.jpg',
'video' => "http://www.youtube.com/watch?v=" . $hash->items[0]->id,
'embed_video' => "http://www.youtube.com/embed/" . $hash->items[0]->id,
'duration' => $duration->format('%H:%I:%S'),
);
} elseif ($host == 'drive') {
}
}
public function rendered_view(Request $request, $path = "")
{
$page_data = array();
foreach ($request->all() as $key => $value) :
$page_data[$key] = $value;
endforeach;
return view($path, $page_data)->render();
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Http\Controllers;
use App\Mail\Mailer;
use App\Models\Contact;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;
class ContactController extends Controller
{
public function index(Request $request)
{
Contact::where('has_read', null)->update(['has_read' => 1]);
if($request->search){
$contact = Contact::where('email', 'like', "%$request->search%")
->orWhere('address', 'like', "%$request->search%")
->orWhere('phone', 'like', "%$request->search%")
->orWhere('message', 'like', "%$request->search%")
->orWhere('name', 'like', "%$request->search%")->paginate(20);
}else{
$contact = Contact::paginate(20);
}
$page_data['contacts'] = $contact;
return view('admin.contact.index', $page_data);
}
public function contact_delete($id)
{
Contact::where('id', $id)->delete();
Session::flash('success', get_phrase('Contact delete successfully'));
return redirect()->back();
}
public function reply(Request $request)
{
$email = Contact::where('id', $request->send_to)->first();
//$this->send_mail($email->email, $request->subject, $request->reply_message);
Mail::raw($request->reply_message, function ($message) use ($email, $request){
$message->to($email->email)
->subject(get_settings('system_title'));
});
$data['replied'] = 1;
$email = Contact::where('id', $request->send_to)->update($data);
Session::flash('success', get_phrase('Email sent successfully'));
return redirect()->route('admin.contacts');
}
public function send_mail($user_email, $subject, $description)
{
config([
'mail.mailers.smtp.transport' => get_settings('protocol'),
'mail.mailers.smtp.host' => get_settings('smtp_host'),
'mail.mailers.smtp.port' => get_settings('smtp_port'),
'mail.mailers.smtp.encryption' => get_settings('smtp_crypto'),
'mail.mailers.smtp.username' => get_settings('smtp_from_email'),
'mail.mailers.smtp.password' => get_settings('smtp_pass'),
'mail.from.address' => get_settings('smtp_from_email'),
'mail.from.name' => get_settings('smtp_user'),
]);
$mail_data['subject'] = $subject;
$mail_data['description'] = $description;
$send = Mail::to($user_email)->send(new Mailer($mail_data));
return $send;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, ValidatesRequests;
}

View File

@ -0,0 +1,142 @@
<?php
namespace App\Http\Controllers;
use App\Models\Coupon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class CouponController extends Controller
{
public function index(Request $request)
{
$query = Coupon::where('user_id', auth()->user()->id);
if (request()->has('search') && request()->query('search') != '') {
$query = $query->where('code', request()->query('search'));
}
$page_data['coupons'] = $query->paginate(10)->appends(request()->query());
return view('admin.coupon.index', $page_data);
}
public function create()
{
return view('admin.coupon.create');
}
public function store(Request $request)
{
$rules = [
'code' => 'required|string|unique:coupons,code',
'discount' => 'required|numeric|between:1,100',
'expiry' => 'required|date|after_or_equal:today',
'status' => 'required|in:0,1',
];
$messages = [
'expiry.after_or_equal' => 'Expiry date must be a future date.',
'status.in' => 'Status must be either 0 or 1.',
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$coupon['code'] = $request->code;
$coupon['user_id'] = auth()->user()->id;
$coupon['discount'] = $request->discount;
$coupon['expiry'] = strtotime($request->expiry);
$coupon['status'] = $request->status;
// insert data
Coupon::insert($coupon);
Session::flash('success', get_phrase('Coupon has been created successfully.'));
return redirect()->back();
}
public function delete($id)
{
// check user data exists or not
$query = Coupon::where('id', $id)->where('user_id', auth()->user()->id);
if ($query->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
// delete data
$query->delete();
Session::flash('success', get_phrase('Coupon has ben deleted successfully.'));
return redirect()->back();
}
public function edit($id)
{
// check user data exists or not
$query = Coupon::where('id', $id)->where('user_id', auth()->user()->id);
if ($query->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$page_data['coupon_details'] = $query->first();
return view('admin.coupon.edit', $page_data);
}
public function update(Request $request, $id)
{
// check user data exists or not
$query = Coupon::where('id', $id)->where('user_id', auth()->user()->id);
if ($query->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$rules = [
'code' => "required|string|unique:coupons,code,$id",
'discount' => 'required|numeric|between:1,100',
'expiry' => 'required|date|after_or_equal:today',
'status' => 'required|in:0,1',
];
$messages = [
'expiry.after_or_equal' => 'Expiry date must be a future date.',
'status.in' => 'Status must be either 0 or 1.',
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$coupon['code'] = $request->code;
$coupon['user_id'] = auth()->user()->id;
$coupon['discount'] = $request->discount;
$coupon['expiry'] = strtotime($request->expiry);
$coupon['status'] = $request->status;
// insert data
Coupon::where('id', $id)->update($coupon);
Session::flash('success', get_phrase('Coupon has been updated successfully.'));
return redirect()->back();
}
public function status($id)
{
// check user data exists or not
$query = Coupon::where('id', $id)->where('user_id', auth()->user()->id);
if ($query->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$coupon = $query->first();
$query->update(['status' => $coupon->status ? 0 : 1]);
Session::flash('success', get_phrase('Status has been updated'));
return redirect(route('admin.coupons'));
}
}

View File

@ -0,0 +1,545 @@
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Mail\Mailer;
use App\Models\Category;
use App\Models\Course;
use App\Models\Lesson;
use App\Models\Question;
use App\Models\QuizSubmission;
use App\Models\FileUploader;
use App\Models\Section;
use App\Models\SeoField;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
class CourseController extends Controller
{
public function index(Request $request)
{
$category = 'all';
$status = 'all';
$instructor = 'all';
$price = 'all';
$query = Course::query();
$query1 = Course::query();
if (isset($request->category) && $request->category != '' && $request->category != 'all') {
$category_details = Category::where('slug', $request->category)->first();
if ($category_details->parent_id > 0) {
$page_data['child_cat'] = $request->category;
$query = $query->where('category_id', $category_details->id);
} else {
$sub_cat_id = Category::where('parent_id', $category_details->id)->pluck('id')->toArray();
$sub_cat_id[] = $category_details->id;
$query = $query->whereIn('category_id', $sub_cat_id);
$page_data['parent_cat'] = $request->category;
}
}
// search filter
if (isset($_GET['search']) && $_GET['search'] != '') {
$query = $query->where('title', 'LIKE', '%' . $_GET['search'] . '%');
}
// selected price
if (isset($_GET['price']) && $_GET['price'] != '' && $_GET['price'] != 'all') {
$search_price = 2;
if ($_GET['price'] == 'free') {
$search_price = 0;
} elseif ($_GET['price'] == 'paid') {
$search_price = 1;
}
$query = $query->where('is_paid', $search_price);
$price = $_GET['price'];
}
// selected instructor
if (isset($_GET['instructor']) && $_GET['instructor'] != '' && $_GET['instructor'] != 'all') {
$query = $query->where('user_id', $_GET['instructor']);
$instructor = $_GET['instructor'];
}
// status filter
if (isset($_GET['status']) && $_GET['status'] != '' && $_GET['status'] != 'all') {
if ($_GET['status'] == 'active') {
$search_status = 'active';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'inactive') {
$search_status = 'inactive';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'pending') {
$search_status = 'pending';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'private') {
$search_status = 'private';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'upcoming') {
$search_status = 'upcoming';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'draft') {
$search_status = 'draft';
$query = $query->where('status', $search_status);
}
$status = $_GET['status'];
}
$page_data['status'] = $status;
$page_data['instructor'] = $instructor;
$page_data['price'] = $price;
$page_data['courses'] = $query->orderBy('id', 'desc')->paginate(20)->appends(request()->query());
$page_data['pending_courses'] = Course::where('status', 'pending')->count();
$page_data['active_courses'] = Course::where('status', 'active')->count();
$page_data['upcoming_courses'] = Course::where('status', 'upcoming')->count();
$page_data['paid_courses'] = Course::where('is_paid', 1)->count();
$page_data['free_courses'] = Course::where('is_paid', 0)->count();
return view('admin.course.index', $page_data);
}
public function create()
{
return view('admin.course.create');
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|max:255',
'category_id' => 'required|numeric|min:1',
'course_type' => 'required|in:general,scorm',
'status' => 'required|in:active,pending,draft,private,upcoming,inactive',
'level' => 'required|in:everyone,beginner,intermediate,advanced',
'language' => 'required',
'is_paid' => Rule::in(['0', '1']),
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
'discount_flag' => Rule::in(['', '1']),
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
'enable_drip_content' => Rule::in(['0', '1']),
'requirements' => 'array',
'outcomes' => 'array',
'faqs' => 'array',
'instructors' => 'required|array|min:1',
]);
//for normal form submission
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['user_id'] = auth()->user()->id;
$data['category_id'] = $request->category_id;
$data['course_type'] = $request->course_type;
$data['status'] = $request->status;
$data['level'] = $request->level;
$data['language'] = strtolower($request->language);
$data['is_paid'] = $request->is_paid;
$data['price'] = $request->price;
$data['discount_flag'] = $request->discount_flag;
$data['discounted_price'] = $request->discounted_price;
$data['enable_drip_content'] = $request->enable_drip_content;
$drip_content_settings = '{"lesson_completion_role":"percentage","minimum_duration":15,"minimum_percentage":"30","locked_lesson_message":"&lt;h3 xss=&quot;removed&quot; style=&quot;text-align: center; &quot;&gt;&lt;span xss=&quot;removed&quot;&gt;&lt;strong&gt;Permission denied!&lt;\/strong&gt;&lt;\/span&gt;&lt;\/h3&gt;&lt;p xss=&quot;removed&quot; style=&quot;text-align: center; &quot;&gt;&lt;span xss=&quot;removed&quot;&gt;This course supports drip content, so you must complete the previous lessons.&lt;\/span&gt;&lt;\/p&gt;"}';
$data['drip_content_settings'] = $drip_content_settings;
$meta_keywords = '';
$meta_keywords_arr = json_decode($request->meta_keywords, true);
if (is_array($meta_keywords_arr)) {
foreach ($meta_keywords_arr as $key => $keyword) {
if ($key > 0) {
$meta_keywords .= ',' . $keyword['value'];
} else {
$meta_keywords .= $keyword['value'];
}
}
}
$data['meta_keywords'] = $meta_keywords;
$data['meta_description'] = $request->meta_description;
$data['short_description'] = $request->short_description;
$data['description'] = $request->description;
//Course expiry period
if ($request->expiry_period == 'limited_time' && is_numeric($request->number_of_month) && $request->number_of_month > 0) {
$data['expiry_period'] = $request->number_of_month;
} else {
$data['expiry_period'] = null;
}
//Remove empty value by using array filter function
if (isset($request->requirements) && $request->requirements != '') {
$data['requirements'] = json_encode(array_filter($request->requirements, fn ($value) => !is_null($value) && $value !== ''));
}
if (isset($request->outcomes) && $request->outcomes != '') {
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn ($value) => !is_null($value) && $value !== ''));
}
if (isset($request->faq_title) && $request->faq_title != '') {
$faqs = [];
foreach ($request->faq_title as $key => $title) {
if ($title != '') {
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
}
}
$data['faqs'] = json_encode($faqs);
}
$data['instructor_ids'] = json_encode($request->instructors);
$data['created_at'] = date('Y-m-d H:i:s');
$data['updated_at'] = date('Y-m-d H:i:s');
if ($request->thumbnail) {
$data['thumbnail'] = "uploads/course-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
}
if ($request->banner) {
$data['banner'] = "uploads/course-banner/" . nice_file_name($request->title, $request->banner->extension());
FileUploader::upload($request->banner, $data['banner'], 1400, null, 300, 300);
}
if ($request->preview) {
$data['preview'] = "uploads/course-preview/" . nice_file_name($request->title, $request->preview->extension());
FileUploader::upload($request->preview, $data['preview']);
}
$course_id = Course::insertGetId($data);
Course::where('id', $course_id)->update(['slug' => slugify($request->title . '-' . $course_id)]);
//for normal form submission
return redirect(route('admin.course.edit', ['id' => $course_id]))->with('success', get_phrase('Course added successfully'));
}
public function edit($course_id = "", Request $request)
{
$data['course_details'] = Course::where('id', $course_id)->first();
$data['sections'] = Section::where('course_id', $course_id)->orderBy('sort')->get();
return view('admin.course.edit', $data);
}
public function update(Request $request, $id)
{
$query = Course::where('id', $id);
if ($request->tab == '') {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$rules = $data = [];
if ($request->tab == 'basic') {
$rules = [
'title' => 'required|max:255',
'category_id' => 'required|numeric|min:1',
'level' => 'required|in:everyone,beginner,intermediate,advanced',
'language' => 'required',
'status' => 'required|in:active,pending,draft,private,upcoming,inactive',
'instructors' => 'required|array|min:1',
];
$data['title'] = $request->title;
$data['slug'] = slugify($request->title . '-' . $id);
$data['short_description'] = $request->short_description;
$data['description'] = removeScripts($request->description);
$data['category_id'] = $request->category_id;
$data['level'] = $request->level;
$data['language'] = strtolower($request->language);
$data['status'] = $request->status;
$data['instructor_ids'] = json_encode($request->instructors);
} elseif ($request->tab == 'pricing') {
$rules = [
'is_paid' => Rule::in(['0', '1']),
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
'discount_flag' => Rule::in(['', '1']),
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
];
$data['is_paid'] = $request->is_paid;
$data['price'] = $request->price;
$data['discount_flag'] = $request->discount_flag;
$data['discounted_price'] = $request->discounted_price;
//Course expiry period
if ($request->expiry_period == 'limited_time' && is_numeric($request->number_of_month) && $request->number_of_month > 0) {
$data['expiry_period'] = $request->number_of_month;
} else {
$data['expiry_period'] = null;
}
} elseif ($request->tab == 'info') {
$rules = [
'requirements' => 'array',
'outcomes' => 'array',
'faqs' => 'array',
];
//Remove empty value by using array filter function
$data['requirements'] = json_encode(array_filter($request->requirements, fn ($value) => !is_null($value) && $value !== ''));
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn ($value) => !is_null($value) && $value !== ''));
$faqs = [];
foreach ($request->faq_title as $key => $title) {
if ($title != '') {
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
}
}
$data['faqs'] = json_encode($faqs);
} elseif ($request->tab == 'media') {
if ($request->thumbnail) {
$data['thumbnail'] = "uploads/course-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
remove_file($query->first()->thumbnail);
}
if ($request->banner) {
$data['banner'] = "uploads/course-banner/" . nice_file_name($request->title, $request->banner->extension());
FileUploader::upload($request->banner, $data['banner'], 1400, null, 300, 300);
remove_file($query->first()->banner);
}
if($request->preview_video_provider == 'link'){
$data['preview'] = $request->preview_link;
}elseif($request->preview_video_provider == 'file' && $request->preview){
$data['preview'] = "uploads/course-preview/" . nice_file_name($request->title, $request->preview->extension());
FileUploader::upload($request->preview, $data['preview']);
remove_file($query->first()->preview);
}
} elseif ($request->tab == 'seo') {
$course_details = $query->first();
$SeoField = SeoField::where('name_route', 'course.details')->where('course_id', $course_details->id)->first();
$seo_data['course_id'] = $id;
$seo_data['route'] = 'Course Details';
$seo_data['name_route'] = 'course.details';
$seo_data['meta_title'] = $request->meta_title;
$seo_data['meta_description'] = $request->meta_description;
$seo_data['meta_robot'] = $request->meta_robot;
$seo_data['canonical_url'] = $request->canonical_url;
$seo_data['custom_url'] = $request->custom_url;
$seo_data['json_ld'] = $request->json_ld;
$seo_data['og_title'] = $request->og_title;
$seo_data['og_description'] = $request->og_description;
$seo_data['created_at'] = date('Y-m-d H:i:s');
$seo_data['updated_at'] = date('Y-m-d H:i:s');
$meta_keywords_arr = json_decode($request->meta_keywords, true);
$meta_keywords = '';
if (is_array($meta_keywords_arr)) {
foreach ($meta_keywords_arr as $arr_key => $arr_val) {
$meta_keywords .= $meta_keywords == '' ? $arr_val['value'] : ', ' . $arr_val['value'];
}
$seo_data['meta_keywords'] = $meta_keywords;
}
if ($request->og_image) {
$originalFileName = $course_details->id . '-' . $request->og_image->getClientOriginalName();
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
// Move the file to the destination path
FileUploader::upload($request->og_image, $destinationPath, 600);
$seo_data['og_image'] = $destinationPath;
}
if ($SeoField) {
if ($request->og_image) {
remove_file($SeoField->og_image);
}
SeoField::where('name_route', 'course.details')->where('course_id', $course_details->id)->update($seo_data);
} else {
SeoField::insert($seo_data);
}
} elseif ($request->tab == 'drip-content') {
$rules = [
'enable_drip_content' => Rule::in(['0', '1']),
];
$data['enable_drip_content'] = $request->enable_drip_content;
$lesson_completion_role = htmlspecialchars($request->input('lesson_completion_role'));
$minimum_duration_input = htmlspecialchars($request->input('minimum_duration'));
$minimum_percentage = htmlspecialchars($request->input('minimum_percentage'));
$locked_lesson_message = htmlspecialchars($request->input('locked_lesson_message'));
// Convert time (HH:MM:SS) to seconds
$time_parts = explode(':', $minimum_duration_input);
$seconds = ($time_parts[0] * 3600) + ($time_parts[1] * 60) + $time_parts[2];
$drip_data = [
'lesson_completion_role' => $lesson_completion_role,
'minimum_duration' => $seconds,
'minimum_percentage' => $minimum_percentage,
'locked_lesson_message' => $locked_lesson_message,
];
$data['drip_content_settings'] = json_encode($drip_data);
}
//For ajax form submission
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
}
$query->update($data);
//For ajax form submission
return ['success' => get_phrase('Course updated successfully')];
}
public function status($type, $id)
{
if ($type == 'active') {
Course::where('id', $id)->update(['status' => 'active']);
} elseif ($type == 'pending') {
Course::where('id', $id)->update(['status' => 'pending']);
} elseif ($type == 'inactive') {
Course::where('id', $id)->update(['status' => 'inactive']);
} elseif ($type == 'upcoming') {
Course::where('id', $id)->update(['status' => 'upcoming']);
} elseif ($type == 'private') {
Course::where('id', $id)->update(['status' => 'private']);
} else {
Course::where('id', $id)->update(['status' => 'draft']);
}
return redirect(route('admin.courses'))->with('success', get_phrase('Course status changed successfully'));
}
public function delete($id)
{
// Find the course
$course = Course::find($id);
if (!$course) {
Session::flash('error', get_phrase('Course not found'));
return redirect()->back();
}
// Get all lessons associated with the course
$lessons = Lesson::where('course_id', $id)->get();
foreach ($lessons as $lesson) {
// Remove lesson files
remove_file($lesson->lesson_src);
remove_file('uploads/lesson_file/attachment/' . $lesson->attachment);
// If the lesson is a quiz, delete related questions and submissions
if ($lesson->lesson_type == 'quiz') {
Question::where('quiz_id', $lesson->id)->each(function ($question) {
$question->delete();
});
QuizSubmission::where('quiz_id', $lesson->id)->each(function ($submission) {
$submission->delete();
});
}
// Delete the lesson
$lesson->delete();
}
// Remove course files
remove_file($course->thumbnail);
remove_file($course->banner);
remove_file($course->preview);
// Delete the course
$course->delete();
// Redirect with success message
return redirect(route('admin.courses'))->with('success', get_phrase('Course deleted successfully'));
}
public function draft($id)
{
$course = Course::where('id', $id)->first();
if (!$course) {
$response = [
'error' => get_phrase('Data not found.'),
];
return json_encode($response);
}
$status = $course->status == 'active' ? 'deactivate' : 'active';
Course::where('id', $id)->update(['status' => $status]);
$response = [
'success' => get_phrase('Status has been updated.'),
];
return json_encode($response);
}
public function duplicate($id)
{
$course = Course::where('id', $id);
if (auth()->user()->role != 'admin') {
$course = $course->where('user_id', auth()->user()->id);
}
// check course existence
if ($course->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
// collect course and remove unnecessary fields
$data = $course->first()->toArray();
if (auth()->user()->role == 'admin') {
$data['user_id'] = auth()->user()->id;
}
unset($data['id'], $data['created_at'], $data['updated_at']);
// insert as new course
$course_id = Course::insertGetId($data);
Course::where('id', $course_id)->update(['slug' => slugify($data['title']).'-'.$course_id]);
// go to edit
Session::flash('success', get_phrase('Course duplicated.'));
return redirect()->route('admin.course.edit', $course_id);
}
function approval(Request $request, $id)
{
Course::where('id', $id)->update(['status' => 'active']);
$course = Course::where('id', $id)->first();
config([
'mail.mailers.smtp.transport' => get_settings('protocol'),
'mail.mailers.smtp.host' => get_settings('smtp_host'),
'mail.mailers.smtp.port' => get_settings('smtp_port'),
'mail.mailers.smtp.encryption' => get_settings('smtp_crypto'),
'mail.mailers.smtp.username' => get_settings('smtp_from_email'),
'mail.mailers.smtp.password' => get_settings('smtp_pass'),
'mail.from.address' => get_settings('smtp_from_email'),
'mail.from.name' => get_settings('smtp_user'),
]);
$mail_data['subject'] = $request->subject;
$mail_data['description'] = $request->message;
try {
Mail::to($course->creator->email)->send(new Mailer($mail_data));
} catch (Exception $e) {
}
Session::flash('success', get_phrase('Course activated successfully'));
return redirect()->route('admin.courses');
}
}

View File

@ -0,0 +1,487 @@
<?php
namespace App\Http\Controllers;
use App\Models\Course;
use App\Models\FileUploader;
use App\Models\Lesson;
use App\Models\Quiz;
use App\Models\Question;
use App\Models\QuizSubmission;
use App\Models\Section;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class CurriculumController extends Controller
{
public function store(Request $request)
{
$maximum_sort_value = Section::where('course_id', $request->course_id)->orderBy('sort', 'desc')->firstOrNew()->sort;
$request->validate([
'title' => 'required',
]);
$section = new Section();
$section->title = $request->title;
$section->user_id = auth()->user()->id;
$section->course_id = $request->course_id;
$section->sort = $maximum_sort_value + 1;
$done = $section->save();
Session::flash('success', get_phrase('Section added successfully'));
return redirect()->back();
}
public function update(Request $request)
{
Section::where('id', $request->section_id)->update(['title' => $request->up_title]);
Session::flash('success', get_phrase('update successfully'));
return redirect()->back();
}
public function delete($id)
{
Section::where('id', $id)->delete();
Session::flash('success', get_phrase('Delete successfully'));
return redirect()->back();
}
public function section_sort(Request $request)
{
$sections = json_decode($request->itemJSON);
foreach ($sections as $key => $value) {
$updater = $key + 1;
Section::where('id', $value)->update(['sort' => $updater]);
}
Session::flash('success', get_phrase('Sections sorted successfully'));
}
public function lesson_store(Request $request)
{
$maximum_sort_value = Lesson::where('course_id', $request->course_id)->orderBy('sort', 'desc')->firstOrNew()->sort;
$data['title'] = $request->title;
$data['user_id'] = auth()->user()->id;
$data['course_id'] = $request->course_id;
$data['section_id'] = $request->section_id;
$data['sort'] = $maximum_sort_value + 1;
$data['is_free'] = $request->free_lesson;
$data['lesson_type'] = $request->lesson_type;
$data['summary'] = $request->summary;
if ($request->lesson_type == 'text') {
$data['attachment'] = $request->text_description;
$data['attachment_type'] = $request->lesson_provider;
} elseif ($request->lesson_type == 'video-url') {
$data['video_type'] = $request->lesson_provider;
$data['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$data['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$data['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'html5') {
$data['video_type'] = $request->lesson_provider;
$data['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$data['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$data['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'document_type') {
if ($request->attachment == '') {
$file = '';
} else {
$item = $request->file('attachment');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/attachment');
if (!File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
} else {
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
}
$file = $file_name;
}
$data['attachment'] = $file;
$data['attachment_type'] = $request->attachment_type;
} elseif ($request->lesson_type == 'scorm') {
if ($request->scorm_file == '') {
$file = '';
} else {
$item = $request->file('scorm_file');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$upload_path = public_path('uploads/lesson_file/scorm_content');
if (! File::isDirectory($upload_path)) {
File::makeDirectory($upload_path, 0777, true, true);
}
$item->move($upload_path, $file_name);
$zip = new \ZipArchive();
$zip_path = $upload_path . '/' . $file_name;
$extract_path = $upload_path . '/' . pathinfo($file_name, PATHINFO_FILENAME);
if ($zip->open($zip_path) === true) {
$zip->extractTo($extract_path);
$zip->close();
File::delete($zip_path);
} else {
return response()->json(['error' => 'Failed to extract the SCORM file.'], 500);
}
$file = pathinfo($file_name, PATHINFO_FILENAME);
}
$data['attachment'] = $file;
$data['attachment_type'] = $request->scorm_provider;
} elseif ($request->lesson_type == 'image') {
if ($request->attachment == '') {
$file = '';
} else {
$item = $request->file('attachment');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/attachment');
if (!File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
} else {
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
}
$file = $file_name;
}
$data['attachment'] = $file;
$data['attachment_type'] = $item->getClientOriginalExtension();
} elseif ($request->lesson_type == 'vimeo-url') {
$data['video_type'] = $request->lesson_provider;
$data['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$data['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$data['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'iframe') {
$data['lesson_src'] = $request->iframe_source;
} elseif ($request->lesson_type == 'google_drive') {
$data['video_type'] = $request->lesson_provider;
$data['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$data['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$data['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'system-video') {
if ($request->system_video_file == '') {
$file = '';
} else {
$item = $request->file('system_video_file');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/videos');
if (! File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
}
$type = get_player_settings('watermark_type');
if ($type == 'ffmpeg') {
$watermark = get_player_settings('watermark_logo');
if (! $watermark) {
return redirect()->back()->with('error', get_phrase('Please configure watermark setting.'));
}
if (! file_exists(public_path($watermark))) {
return redirect()->back()->with('error', get_phrase('File doesn\'t exists.'));
}
$watermark_status = WatermarkController::encode($item, $file_name, $path);
if (! $watermark_status) {
return redirect()->back()->with('error', get_phrase('Something went wrong.'));
}
}
$file = FileUploader::upload($request->system_video_file, 'uploads/lesson_file/videos/' . $file_name);
}
$data['video_type'] = $request->lesson_provider;
$data['lesson_src'] = $file;
if (empty($request->duration)) {
$data['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$data['duration'] = $hour . ':' . $min . ':' . $sec;
}
}
Lesson::insert($data);
Session::flash('success', get_phrase('lesson added successfully'));
return redirect()->back();
}
public function lesson_sort(Request $request)
{
$lessons = json_decode($request->itemJSON);
foreach ($lessons as $key => $value) {
$updater = $key + 1;
Lesson::where('id', $value)->update(['sort' => $updater]);
}
Session::flash('success', get_phrase('Lessons sorted successfully'));
}
public function lesson_edit(Request $request)
{
$current_data = Lesson::find($request->id);
$lesson['title'] = $request->title;
$lesson['section_id'] = $request->section_id;
$lesson['summary'] = $request->summary;
if ($request->lesson_type == 'text') {
$lesson['attachment'] = $request->text_description;
} elseif ($request->lesson_type == 'video-url') {
$lesson['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'html5') {
$lesson['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'document_type') {
if ($request->attachment) {
$item = $request->file('attachment');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/attachment');
if (!File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
} else {
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
}
$lesson['attachment'] = $file_name;
$lesson['attachment_type'] = $request->attachment_type;
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
}
} elseif ($request->lesson_type == 'image') {
if ($request->attachment) {
$item = $request->file('attachment');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/attachment');
if (!File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
} else {
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
}
$lesson['attachment'] = $file_name;
$lesson['attachment_type'] = $item->getClientOriginalExtension();
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
}
} elseif ($request->lesson_type == 'vimeo-url') {
$lesson['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'iframe') {
$lesson['lesson_src'] = $request->iframe_source;
} elseif ($request->lesson_type == 'google_drive') {
$lesson['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'scorm') {
$existing_scorm_folder = $request->attachment;
if ($request->scorm_file == '') {
$file = '';
} else {
$item = $request->file('scorm_file');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$upload_path = public_path('uploads/lesson_file/scorm_content');
if (! File::isDirectory($upload_path)) {
File::makeDirectory($upload_path, 0777, true, true);
}
$this->deleteDir(public_path('uploads/lesson_file/scorm_content/' . $existing_scorm_folder));
FileUploader::upload($request->scorm_file, 'uploads/lesson_file/scorm_content/' . $file_name);
$zip = new \ZipArchive();
$zip_path = $upload_path . '/' . $file_name;
$extract_path = $upload_path . '/' . pathinfo($file_name, PATHINFO_FILENAME);
// Remove old SCORM directory if it exists
$existing_scorm_path = $upload_path . '/' . $request->scorm_file;
if (File::isDirectory($existing_scorm_path)) {
File::deleteDirectory($existing_scorm_path);
}
if ($zip->open($zip_path) === true) {
$zip->extractTo($extract_path);
$zip->close();
File::delete($zip_path);
} else {
return response()->json(['error' => 'Failed to extract the SCORM file.'], 500);
}
$file = pathinfo($file_name, PATHINFO_FILENAME);
}
$lesson['attachment'] = $file;
$lesson['attachment_type'] = $request->scorm_provider;
} elseif ($request->lesson_type == 'system-video') {
if ($request->system_video_file) {
$item = $request->file('system_video_file');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/videos');
if (! File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
}
$type = get_player_settings('watermark_type');
if ($type == 'ffmpeg') {
$watermark = get_player_settings('watermark_logo');
if (! $watermark) {
return redirect()->back()->with('error', get_phrase('Please configure watermark setting.'));
}
if (! file_exists(public_path($watermark))) {
return redirect()->back()->with('error', get_phrase('File doesn\'t exists.'));
}
$watermark_status = WatermarkController::encode($item, $file_name, $path);
if (! $watermark_status) {
return redirect()->back()->with('error', get_phrase('Something went wrong.'));
}
}
FileUploader::upload($request->system_video_file, 'uploads/lesson_file/videos/' . $file_name);
$file = str_replace(public_path('/'), '', $path).'/'. $file_name;
$lesson['lesson_src'] = $file;
remove_file($current_data->lesson_src);
}
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
}
Lesson::where('id', $request->id)->update($lesson);
Session::flash('success', get_phrase('lesson update successfully'));
return redirect()->back();
}
public function deleteDir($directoryPath)
{
if (File::exists($directoryPath)) {
// Delete all files and subdirectories within the directory
File::deleteDirectory($directoryPath);
// Finally, delete the root directory itself
File::delete($directoryPath);
}
}
public function lesson_delete($id)
{
// Find the lesson
$current_data = Lesson::find($id);
if (!$current_data) {
Session::flash('error', get_phrase('Lesson not found'));
return redirect()->back();
}
// Remove lesson files
remove_file($current_data->lesson_src);
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
// If the lesson is a quiz, delete related questions and submissions
if ($current_data->lesson_type == 'quiz') {
Question::where('quiz_id', $id)->each(function ($question) {
$question->delete();
});
QuizSubmission::where('quiz_id', $id)->each(function ($submission) {
$submission->delete();
});
}
// Delete the lesson
$current_data->delete();
// Flash success message
Session::flash('success', get_phrase('Deleted successfully'));
return redirect()->back();
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Controllers;
use App\Models\Payment_history;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
public function index()
{
$monthly_amount = array(0);
for ($i = 1; $i <= 12; $i++) {
$total_amount = date('t', strtotime(date("Y-$i-1 00:00:00")));
$amount = Payment_history::whereDate('created_at', '>=', date("Y-$i-1 00:00:00"))->whereDate('created_at', '<=', date("Y-$i-$total_amount 23:59:59"))->get();
if (count($amount) > 0) {
array_push($monthly_amount, array_sum($amount->pluck('admin_revenue')->toArray()));
} else {
array_push($monthly_amount, 0);
}
}
$page_data['monthly_amount'] = $monthly_amount;
return view('admin.dashboard.index', $page_data);
}
}

View File

@ -0,0 +1,187 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Lesson;
use Illuminate\Support\Facades\File;
class FileController extends Controller
{
public function get_file(Request $request)
{
// check this request from iframe, canvas, api or direct from browser url
// if (isset($_SERVER['HTTP_REFERER']) && isset($_SERVER['HTTP_SEC_FETCH_MODE'])) {
// } else {
// return false;
// }
$user_id = auth()->user()->id;
if (isset($request->course_id) && isset($request->lesson_id) && $user_id > 0) {
$course_id = $request->course_id;
$lesson_id = $request->lesson_id;
$lesson = Lesson::find($lesson_id);
$get_lesson_type = $lesson->lesson_type;
if(enroll_status($course_id, $user_id) || auth()->user()->role == 'admin' || is_course_instructor($course_id, $user_id)){
if ($get_lesson_type == 'image' || $get_lesson_type == 'document_type') {
$fileUrl = 'uploads/lesson_file/attachment/' . $lesson->attachment;
}
if ($get_lesson_type == 'system-video') {
$fileUrl = $lesson->lesson_src;
}
if (str_contains('https:', url('')) !== false && str_contains('http:', $fileUrl) !== false) {
$fileUrl = str_replace('http:', 'https:', $fileUrl);
}elseif(str_contains('http:', url('')) !== false && str_contains('https:', $fileUrl) !== false){
$fileUrl = str_replace('https:', 'http:', $fileUrl);
}
$fileUrl = str_replace(url(''), '', $fileUrl);
$basename = basename($fileUrl);
if (str_contains('http', $fileUrl) !== false) {
$header_data = get_headers($fileUrl, 1);
if (array_key_exists('Content-Type', $header_data)) {
$content_type = $header_data['Content-Type'];
}
if (array_key_exists('Content-type', $header_data)) {
$content_type = $header_data['Content-type'];
}
if (array_key_exists('content-type', $header_data)) {
$content_type = $header_data['content-type'];
}
//$this->get_remote_file_size($fileUrl);
if (array_key_exists('Content-Length', $header_data)) {
$file_size = $header_data['Content-Length'];
}
if (array_key_exists('Content-length', $header_data)) {
$file_size = $header_data['Content-length'];
}
if (array_key_exists('content-length', $header_data)) {
$file_size = $header_data['content-length'];
}
} else {
$content_type = mime_content_type(public_path($fileUrl));
$file_size = filesize(public_path($fileUrl));
}
if ($get_lesson_type == 'image' || $get_lesson_type == 'document_type') {
//for not streaming file as like: img, pdf, txt and more.
header('Content-Type: ' . $content_type);
header('Content-Length: ' . $file_size);
// header('Content-Disposition: inline; filename=' . basename($fileUrl));
readfile(public_path($fileUrl));
exit;
} elseif($get_lesson_type == 'system-video') {
if($file_size < 3000000){
$chunkSize = $file_size;
}else{
$chunkSize = 3000000;
}
$start = 0;
$end = $file_size - 1;
$range = isset($_SERVER['HTTP_RANGE']) ? $_SERVER['HTTP_RANGE'] : 'bytes=0-' . $chunkSize;
header('Accept-Ranges: bytes');
header('Content-Type: ' . $content_type);
header('Content-Disposition: inline; filename="' . $basename . '"');
if ($range) {
header('HTTP/1.1 206 Partial Content');
$range = explode('=', $range);
$start = intval($range[1]);
$end = min($start + $chunkSize - 1, $file_size - 1);
header('Content-Range: bytes ' . $start . '-' . $end . '/' . $file_size);
} else {
header('Content-Length: ' . $file_size);
}
// Set cache-control headers
header('Cache-Control: public, max-age=0');
header('Pragma: public');
// Remove unnecessary headers
header_remove('Expires');
$handle = fopen(public_path($fileUrl), 'rb');
fseek($handle, $start);
while (!feof($handle) && ($pos = ftell($handle)) <= $end) {
if ($pos + $chunkSize > $end) {
$chunkSize = $end - $pos + 1;
}
echo fread($handle, $chunkSize);
ob_flush();
flush();
}
fclose($handle);
exit;
}
}
}
}
public function get_video_file(Request $request)
{
$user_id = auth()->user()->id;
if (isset($request->course_id) && isset($request->lesson_id) && $user_id > 0) {
$course_id = $request->course_id;
$lesson_id = $request->lesson_id;
$lesson = Lesson::find($lesson_id);
$get_lesson_type = $lesson->lesson_type;
if(enroll_status($course_id, $user_id) || auth()->user()->role == 'admin' || is_course_instructor($course_id, $user_id)){
if ($get_lesson_type == 'system-video') {
$fileUrl = $lesson->lesson_src;
$filePath = public_path($fileUrl);
}
if (File::exists($filePath)) {
// Open the file as a stream and set headers
$stream = fopen($filePath, 'rb');
$mimeType = mime_content_type($filePath);
// Return the file as a stream (no direct download, just playback)
return response()->stream(function () use ($stream) {
fpassthru($stream);
}, 200, [
'Content-Type' => $mimeType,
'Content-Length' => filesize($filePath),
'Cache-Control' => 'no-cache',
'Content-Disposition' => 'inline; filename="' . basename($filePath) . '"',
]);
} else {
abort(404, 'Video not found');
}
}
}
}
public function pdf_canvas($course_id = "", $lesson_id = "")
{
$user_id = auth()->user()->id;
if(enroll_status($course_id, $user_id) || auth()->user()->role == 'admin' || is_course_instructor($course_id, $user_id)){
$page_data['course_id'] = $course_id;
$page_data['lesson_id'] = $lesson_id;
return view('course_player.pdf_canvas', $page_data);
} else {
echo get_phrase('Access denied');
}
}
}

View File

@ -0,0 +1,180 @@
<?php
namespace App\Http\Controllers;
use App\Models\Forum;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class ForumController extends Controller
{
public function index(Request $request)
{
$page_data['questions'] = Forum::join('users', 'forums.user_id', 'users.id')
->select('forums.*', 'users.name as user_name', 'users.photo as user_photo')
->latest('forums.id')
->where('forums.parent_id', 0)
->where('forums.course_id', $request->course_id)
->get();
return view('course_player.forum.question_body', $page_data);
}
public function create(Request $request)
{
$page_data['course_id'] = $request->course_id;
$page_data['parent_question_id'] = $request->parent_question_id;
return view('course_player.forum.create_question', $page_data);
}
public function store(Request $request)
{
$rules = [
'title' => 'required',
'description' => 'required',
];
$validate = Validator::make($request->all(), $rules);
if ($validate->fails()) {
return back()->withErrors($validate)->withInput();
}
$msg = 'Question added successfully.';
$data['description'] = $request->description;
if ($request->title == 'reply') {
$msg = 'Reply added successfully.';
$data['description'] = strip_tags($request->description);
}
$data['user_id'] = auth()->user()->id;
$data['course_id'] = $request->course_id;
$data['parent_id'] = $request->parent_id ?? 0;
$data['title'] = $request->title;
Forum::insert($data);
Session::flash('success', get_phrase($msg));
return redirect()->back();
}
public function edit(Request $request)
{
$page_data['course_id'] = $request->course_id;
$page_data['question'] = Forum::where('id', $request->question_id)->first();
return view('course_player.forum.edit_question', $page_data);
}
public function delete($id)
{
$query = Forum::where('user_id', auth()->user()->id)->where('id', $id);
if ($query->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
} else {
$query->delete();
Session::flash('success', get_phrase('Question deleted successfully.'));
}
return redirect()->back();
}
public function update(Request $request, $id)
{
$rules = [
'title' => 'required',
'description' => 'required',
];
$validate = Validator::make($request->all(), $rules);
if ($validate->fails()) {
return back()->withErrors($validate)->withInput();
}
$msg = 'Question updated successfully.';
$data['description'] = $request->description;
if ($request->title == 'reply') {
$msg = 'Reply updated successfully.';
$data['description'] = strip_tags($request->description);
}
$data['title'] = $request->title;
$data['description'] = $request->description;
Forum::where('id', $id)->update($data);
Session::flash('success', get_phrase($msg));
return redirect()->back();
}
public function likes($id)
{
$question = Forum::where('id', $id)->first();
$user_id = auth()->user()->id;
$likes = $question->likes ? json_decode($question->likes, true) : [];
if (in_array($user_id, $likes)) {
$likes = self::rmv_item($likes, $user_id);
Session::flash('success', get_phrase('Your like has been removed.'));
} else {
array_push($likes, $user_id);
Session::flash('success', get_phrase('Your like has been added.'));
}
$data['likes'] = count($likes) > 0 ? json_encode($likes) : null;
// remove dislike is there is any dislike
$dislikes = $question->dislikes ? json_decode($question->dislikes, true) : [];
if (in_array($user_id, $dislikes)) {
$dislikes = self::rmv_item($dislikes, $user_id);
$data['dislikes'] = count($dislikes) > 0 ? json_encode($dislikes) : null;
}
Forum::where('id', $id)->update($data);
return redirect()->back();
}
public function dislikes($id)
{
$question = Forum::where('id', $id)->first();
$user_id = auth()->user()->id;
$dislikes = $question->dislikes ? json_decode($question->dislikes, true) : [];
if (in_array($user_id, $dislikes)) {
$dislikes = self::rmv_item($dislikes, $user_id);
Session::flash('success', get_phrase('Your changes has been saved.'));
} else {
array_push($dislikes, $user_id);
Session::flash('success', get_phrase('Your changes has been saved.'));
}
$data['dislikes'] = count($dislikes) > 0 ? json_encode($dislikes) : null;
// remove like is there is any like
$likes = $question->likes ? json_decode($question->likes, true) : [];
if (in_array($user_id, $likes)) {
$likes = self::rmv_item($likes, $user_id);
$data['likes'] = count($likes) > 0 ? json_encode($likes) : null;
}
Forum::where('id', $id)->update($data);
return redirect()->back();
}
public static function rmv_item($arr = [], $user_id)
{
$pos = array_search($user_id, $arr);
array_splice($arr, $pos, 1);
return $arr;
}
public function tab_active(Request $request)
{
$tab = explode('#pills-', $request->tab)[1];
Session::put('forum_tab', $tab);
}
public function create_reply(Request $request)
{
$page_data['parent_question_id'] = $request->parent_question_id;
return view('course_player.forum.create_reply', $page_data);
}
public function edit_reply(Request $request)
{
$page_data['reply'] = Forum::where('id', $request->reply_id)->first();
return view('course_player.forum.edit_reply', $page_data);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class InvoiceController extends Controller
{
public function invoice()
{
return view('admin.invoice');
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class LanguageController extends Controller
{
//
}

View File

@ -0,0 +1,259 @@
<?php
namespace App\Http\Controllers;
use App\Models\Course;
use App\Models\Live_class;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Http\Request;
class LiveClassController extends Controller
{
public function live_class_start($id)
{
$live_class = Live_class::where('id', $id)->first();
if ($live_class->provider == 'zoom') {
if (get_settings('zoom_web_sdk') == 'active') {
return view('course_player.live_class.zoom_live_class', ['live_class' => $live_class]);
} else {
$meeting_info = json_decode($live_class->additional_info, true);
return redirect($meeting_info['start_url']);
}
} else {
return view('course_player.live_class.zoom_live_class', ['live_class' => $live_class]);
}
}
public function live_class_store(Request $request, $course_id)
{
$validated = $request->validate([
'class_topic' => 'required|max:255',
'class_date_and_time' => 'date|required',
'user_id' => 'required',
]);
$data['class_topic'] = $request->class_topic;
$data['course_id'] = $request->course_id;
$data['user_id'] = $request->user_id;
$data['provider'] = $request->provider;
$data['class_date_and_time'] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
$data['note'] = $request->note;
if ($request->provider == 'zoom') {
$meeting_info = $this->create_zoom_live_class($request->class_topic, $request->class_date_and_time);
$meeting_info_arr = json_decode($meeting_info, true);
if (array_key_exists('code', $meeting_info_arr) && $meeting_info_arr) {
return redirect(route('admin.course.edit', ['id' => $course_id, 'tab' => 'live-class']))->with('error', get_phrase($meeting_info_arr['message']));
}
$data['additional_info'] = $meeting_info;
}
Live_class::insert($data);
return redirect(route('admin.course.edit', ['id' => $course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class added successfully'));
}
public function live_class_update(Request $request, $id)
{
$previous_meeting_data = Live_class::where('id', $id)->first();
$request->validate([
'class_topic' => 'required|max:255',
'class_date_and_time' => 'date|required',
'user_id' => 'required',
]);
$data['class_topic'] = $request->class_topic;
$data['user_id'] = $request->user_id;
$data['class_date_and_time'] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
$data['note'] = $request->note;
if ($previous_meeting_data->provider == 'zoom') {
$previous_meeting_info = json_decode($previous_meeting_data->additional_info, true);
$this->update_zoom_live_class($request->class_topic, $request->class_date_and_time, $previous_meeting_info['id']);
$previous_meeting_info["start_time"] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
$previous_meeting_info["topic"] = $request->class_topic;
$data['additional_info'] = json_encode($previous_meeting_info);
}
Live_class::where('id', $id)->update($data);
return redirect(route('admin.course.edit', ['id' => $previous_meeting_data->course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class updated successfully'));
}
public function live_class_delete($id)
{
$previous_meeting_data = Live_class::where('id', $id)->first();
$course = Course::where('id', $previous_meeting_data->course_id)->first();
if ($course->instructors()->count() > 0) {
$previous_meeting_info = json_decode($previous_meeting_data->additional_info, true);
$this->delete_zoom_live_class($previous_meeting_info['id']);
Live_class::where('id', $id)->delete();
}
return redirect(route('admin.course.edit', ['id' => $previous_meeting_data->course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class deleted successfully'));
}
public function live_class_settings()
{
return view('admin.setting.live_class_settings');
}
public function update_live_class_settings(Request $request)
{
$validated = $request->validate([
'zoom_account_email' => 'required:email',
'zoom_web_sdk' => 'required|in:active,inactive',
'zoom_account_id' => 'required',
'zoom_client_id' => 'required',
'zoom_client_secret' => 'required',
]);
foreach ($request->all() as $name => $value) {
if (Setting::where('type', $name)->count() > 0) {
Setting::where('type', $name)->update(['description' => $value]);
} else {
Setting::insert(['type' => $name, 'description' => $value]);
}
}
return redirect(route('admin.live.class.settings'))->with('success', get_phrase('Zoom live class settings has been configured'));
}
public function create_zoom_live_class($topic, $date_and_time)
{
$zoom_account_email = get_settings('zoom_account_email');
$token = $this->create_zoom_token();
// API Endpoint for creating a meeting
$zoomEndpoint = 'https://api.zoom.us/v2/users/me/meetings';
// Meeting data
$meetingData = [
'topic' => $topic,
'schedule_for' => $zoom_account_email,
'type' => 2, // Scheduled meeting
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // Start time (in UTC)
'duration' => 60, // Duration in minutes
'timezone' => get_settings('timezone'), // Timezone
'settings' => [
'approval_type' => 2,
'join_before_host' => true,
'jbh_time' => 0,
],
];
// Prepare headers
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
// Make POST request to create meeting
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
// JSON response
return $response;
}
public function update_zoom_live_class($topic, $date_and_time, $meetingId)
{
$token = $this->create_zoom_token(); // Obtain the access token
// API Endpoint for updating a meeting
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
// Meeting data with updated start time
$meetingData = [
'topic' => $topic,
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // New start time (in UTC)
];
// Prepare headers
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
// Make PATCH request to update meeting
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
// JSON response
return $response;
}
public function delete_zoom_live_class($meetingId)
{
$token = $this->create_zoom_token(); // Obtain the access token
// API Endpoint for deleting a meeting
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
// Prepare headers
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
// Make DELETE request to delete meeting
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
// JSON response
return $response;
}
public function create_zoom_token()
{
// Access the environment variables
$clientId = get_settings('zoom_client_id');
$clientSecret = get_settings('zoom_client_secret');
$accountId = get_settings('zoom_account_id');
$oauthUrl = 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId; // Replace with your OAuth endpoint URL
$authHeader = 'Basic ' . base64_encode($clientId . ':' . $clientSecret);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/x-www-form-urlencoded',
'Authorization: ' . $authHeader,
'Cookie: __cf_bm=kn5ec2sntPlDgQWVWtSYdPeISb6bp6F7NHwuAFJQaGk-1736318967-1.0.1.1-SeM4z5pIb.nrMno35jg3y5BdXib.GPP13s2_yNnqz6LxbU9zsFTfZQc3a_Di94qx3DoyQjBT2Osz7idFMWWOrw; _zm_chtaid=816; _zm_ctaid=nbT15WlMTsCEAgCyUg3rYw.1736318967206.63747957ef3128f771210fb69e8d6831; _zm_mtk_guid=fa77ae1ac8e349bea690b72d942d6de6; _zm_page_auth=us04_c_uqPDVOshQQK6FRkhQPiPRA; _zm_ssid=us04_c_atJ4QboaQZG4Lw4U-Wpx6A; cred=A404810ADF33AFC21FF517216A4CB862'
),
));
$response = curl_exec($curl);
curl_close($curl);
$oauthResponse = json_decode($response, true) ?? ['access_token' => ''];
$accessToken = $oauthResponse['access_token'];
return $accessToken;
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ModalController extends Controller
{
public function common_view_function(Request $request, $view_path = "")
{
$page_data = array();
foreach ($request->all() as $key => $value) :
$page_data[$key] = $value;
endforeach;
return view($view_path, $page_data);
}
}

View File

@ -0,0 +1,135 @@
<?php
namespace App\Http\Controllers;
use App\Mail\Mailer;
use App\Models\Newsletter;
use App\Models\Newsletter_subscriber;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;
class NewsletterController extends Controller
{
public function index()
{
$page_data['newsletters'] = Newsletter::orderBy('id', 'desc')->paginate(10);
return view("admin.newsletter.index", $page_data);
}
public function store(Request $request)
{
$data["subject"] = $request->subject;
$data["description"] = $request->description;
Newsletter::insert($data);
Session::flash('success', get_phrase('Newsletter created successfully'));
return redirect()->back();
}
public function delete($id)
{
if (Newsletter::where('id', $id)->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
Newsletter::where('id', $id)->delete();
Session::flash('success', get_phrase('Newsletter deleted successfully.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
if (Newsletter::where('id', $id)->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$data["subject"] = $request->subject;
$data["description"] = $request->description;
Newsletter::where('id', $id)->update($data);
Session::flash('success', get_phrase('Newsletter updated successfully.'));
return redirect()->back();
}
public function subscribers(Request $request)
{
if ($request->search) {
$subscribers = Newsletter_subscriber::orderBy('id', 'desc')->where('email', 'like', "%$request->search%")->paginate(20);
} else {
$subscribers = Newsletter_subscriber::orderBy('id', 'desc')->paginate(20);
}
$page_data['subscribers'] = $subscribers;
return view("admin.newsletter.subscribers", $page_data);
}
public function subscribed_user_delete($id)
{
Newsletter_subscriber::where('id', $id)->delete();
Session::flash('success', get_phrase('subscriber delete successfully'));
return redirect()->back();
}
public function newsletters_form()
{
return view('admin.newsletter.send_newsletter');
}
public function get_user(Request $request)
{
$user = User::where('name', 'LIKE', '%' . $request->searchVal . '%')->get();
foreach ($user as $row) {
$response[] = ['id' => $row->id, 'text' => $row->name];
}
return json_encode($response);
}
public function send_newsletters(Request $request)
{
$members = [];
if ($request->send_to == 'all') {
$users = User::get();
$newsletter = Newsletter_subscriber::get();
$members = array_merge($users->all(), $newsletter->all());
} elseif ($request->send_to == 'student') {
$members = User::where('role', 'student')->get();
} elseif ($request->send_to == 'instructor') {
$members = User::where('role', 'instructor')->get();
} elseif ($request->send_to == 'all_subscriber') {
$members = Newsletter_subscriber::get();
} elseif ($request->send_to == 'registered_subscriber') {
$members = Newsletter_subscriber::join('users', 'newsletter_subscribers.email', '=', 'users.email')->get();
} elseif ($request->send_to == 'non_registered_subscriber') {
$members = Newsletter_subscriber::join('users', 'newsletter_subscribers.email', '!=', 'users.email')->get();
} elseif ($request->send_to == 'selected_user') {
Session::flash('error', get_phrase('Please select a user'));
return redirect()->route('admin.newsletter');
}
foreach ($members as $member) {
$data = self::send_mail($member->email, $request->subject, $request->description);
}
Session::flash('success', get_phrase('Email sent successfully'));
return redirect()->route('admin.newsletter');
}
public function send_mail($user_email, $subject, $description)
{
config([
'mail.mailers.smtp.transport' => get_settings('protocol'),
'mail.mailers.smtp.host' => get_settings('smtp_host'),
'mail.mailers.smtp.port' => get_settings('smtp_port'),
'mail.mailers.smtp.encryption' => get_settings('smtp_crypto'),
'mail.mailers.smtp.username' => get_settings('smtp_from_email'),
'mail.mailers.smtp.password' => get_settings('smtp_pass'),
'mail.from.address' => get_settings('smtp_from_email'),
'mail.from.name' => get_settings('smtp_user'),
]);
$mail_data['subject'] = $subject;
$mail_data['description'] = $description;
$send = Mail::to($user_email)->send(new Mailer($mail_data));
return $send;
}
}

View File

@ -0,0 +1,445 @@
<?php
namespace App\Http\Controllers;
use Anand\LaravelPaytmWallet\Facades\PaytmWallet;
use App\Models\FileUploader;
use App\Models\payment_gateway\Paystack;
use App\Models\payment_gateway\Ccavenue;
use App\Models\payment_gateway\Pagseguro;
use App\Models\payment_gateway\Xendit;
use App\Models\payment_gateway\Doku;
use App\Models\payment_gateway\Skrill;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use paytm\paytmchecksum\PaytmChecksum;
class PaymentController extends Controller
{
public function index()
{
$payment_details = session('payment_details');
if (!$payment_details || !is_array($payment_details) || count($payment_details) <= 0) {
Session::flash('error', get_phrase('Payment not configured yet'));
return redirect()->back();
}
if ($payment_details['payable_amount'] <= 0) {
Session::flash('error', get_phrase("Payable amount cannot be less than 1"));
return redirect()->to($payment_details['cancel_url']);
}
$page_data['payment_details'] = $payment_details;
$page_data['payment_gateways'] = DB::table('payment_gateways')->where('status', 1)->get();
return view('payment.index', $page_data);
}
public function show_payment_gateway_by_ajax($identifier)
{
$page_data['payment_details'] = session('payment_details');
$page_data['payment_gateway'] = DB::table('payment_gateways')->where('identifier', $identifier)->first();
return view('payment.' . $identifier . '.index', $page_data);
}
public function payment_success(Request $request, $identifier = "")
{
$payment_details = session('payment_details');
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
$model_name = $payment_gateway->model_name;
$model_full_path = str_replace(' ', '', 'App\Models\payment_gateway\ ' . $model_name);
$status = $model_full_path::payment_status($identifier, $request->all());
if ($status === true) {
$success_model = $payment_details['success_method']['model_name'];
$success_function = $payment_details['success_method']['function_name'];
$model_full_path = str_replace(' ', '', 'App\Models\ ' . $success_model);
return $model_full_path::$success_function($identifier);
} elseif ($status == "submitted") {
Session::flash('success', get_phrase('Your payment submitted. It will take some times to enrol.'));
return redirect(route('home'));
} else {
Session::flash('error', get_phrase('Payment failed! Please try again.'));
redirect()->to($payment_details['cancel_url']);
}
}
public function payment_create($identifier)
{
$payment_details = session('payment_details');
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
$model_name = $payment_gateway->model_name;
$model_full_path = str_replace(' ', '', 'App\Models\payment_gateway\ ' . $model_name);
$created_payment_link = $model_full_path::payment_create($identifier);
return redirect()->to($created_payment_link);
}
public function payment_notification(Request $request, $identifier)
{
if ($identifier == 'doku') {
Doku::payment_status($identifier, $request->all(), $request->headers->all());
}
}
public function payment_razorpay($identifier)
{
$payment_details = session('payment_details');
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
$model_name = $payment_gateway->model_name;
$model_full_path = str_replace(' ', '', 'App\Models\payment_gateway\ ' . $model_name);
$data = $model_full_path::payment_create($identifier);
return view('payment.razorpay.payment', compact('data'));
}
public function make_paytm_order(Request $request)
{
//start common code of all payment gateway
// $identifier = 'paytm';
// $payment_details = session('payment_details');
// $model = $payment_details['success_method']['model_name'];
// $payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
// $user = auth()->user();
// $paytm_merchant_key = $paytm_merchant_mid = $paytm_merchant_website = $industry_type_id = $channel_id = '';
// if ($model == 'InstructorPayment') {
// $instructor_payment_keys = DB::table('users')
// ->where('id', $payment_details['items'][0]['id'])
// ->value('paymentkeys');
// $keys = isset($instructor_payment_keys) ? json_decode($instructor_payment_keys) : null;
// if ($keys) {
// $paytm_merchant_key = $keys->paytm->paytm_merchant_key;
// $paytm_merchant_mid = $keys->paytm->paytm_merchant_mid;
// $paytm_merchant_website = $keys->paytm->paytm_merchant_website;
// $industry_type_id = $keys->paytm->industry_type_id;
// $channel_id = $keys->paytm->channel_id;
// }
// } else {
// $keys = json_decode($payment_gateway->keys);
// $paytm_merchant_key = $keys->paytm_merchant_key;
// $paytm_merchant_mid = $keys->paytm_merchant_mid;
// $paytm_merchant_website = $keys->paytm_merchant_website;
// $industry_type_id = $keys->industry_type_id;
// $channel_id = $keys->channel_id;
// }
// if ($payment_gateway->test_mode == 1) {
// $PAYTM_STATUS_QUERY_NEW_URL = 'https://securegw-stage.paytm.in/merchant-status/getTxnStatus';
// $PAYTM_TXN_URL = 'https://securegw-stage.paytm.in/theia/processTransaction';
// } else {
// define('PAYTM_ENVIRONMENT', 'PROD'); // PROD or TEST
// $PAYTM_STATUS_QUERY_NEW_URL = 'https://securegw.paytm.in/merchant-status/getTxnStatus';
// $PAYTM_TXN_URL = 'https://securegw.paytm.in/theia/processTransaction';
// }
// $paramList = [];
// $paramList['MID'] = $paytm_merchant_mid;
// $paramList['ORDER_ID'] = 'ORDS2123' . $user->id;
// $paramList['CUST_ID'] = 'CUST' . $user->id;
// $paramList['INDUSTRY_TYPE_ID'] = $industry_type_id;
// $paramList['CHANNEL_ID'] = $channel_id;
// $paramList['TXN_AMOUNT'] = $payment_details['payable_amount'];
// $paramList['WEBSITE'] = $paytm_merchant_website;
// $paramList['CALLBACK_URL'] = $payment_details['success_url'] . '/' . $identifier;
// $paytmParams = array();
// $paytmParams["body"] = array(
// "requestType" => "Payment",
// "mid" => $paytm_merchant_mid,
// "websiteName" => $paytm_merchant_website,
// "orderId" => 'ORDS2123' . $user->id,
// "callbackUrl" => $payment_details['success_url'] . '/' . $identifier,
// "txnAmount" => array(
// "value" => round($payment_details['payable_amount'], 2),
// "currency" => "INR",
// ),
// "userInfo" => array(
// "custId" => "CUST_".$user->id,
// ),
// );
// $checksum = PaytmChecksum::generateSignature(json_encode($paramList, JSON_UNESCAPED_SLASHES), $paytm_merchant_key);
// echo PaytmChecksum::verifySignature($paramList, $paytm_merchant_key, $checksum);
// // $checksum = str_replace('/', '', $checksum);
// // $checksum = str_replace('=', '', $checksum);
// $paytmParams["head"] = array(
// "signature" => $checksum,
// "channelId" => $channel_id
// );
// $post_data = json_encode($paytmParams, JSON_UNESCAPED_SLASHES);
// /* for Staging */
// $url = "https://securegw-stage.paytm.in/theia/api/v1/initiateTransaction?mid=$paytm_merchant_mid&orderId=ORDS2123" . $user->id;
// $ch = curl_init($url);
// curl_setopt($ch, CURLOPT_POST, 1);
// curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
// $response = curl_exec($ch);
// print_r($response);
return view('payment.paytm.paytm_merchant_checkout');
}
public function paytm_paymentCallback()
{
$transaction = PaytmWallet::with('receive');
$response = $transaction->response();
$order_id = $transaction->getOrderId(); // return a order id
$transaction->getTransactionId(); // return a transaction id
// update the db data as per result from api call
if ($transaction->isSuccessful()) {
Paytm::where('order_id', $order_id)->update(['status' => 1, 'transaction_id' => $transaction->getTransactionId()]);
return redirect(route('initiate.payment'))->with('message', "Your payment is successfull.");
} else if ($transaction->isFailed()) {
Paytm::where('order_id', $order_id)->update(['status' => 0, 'transaction_id' => $transaction->getTransactionId()]);
return redirect(route('initiate.payment'))->with('message', "Your payment is failed.");
} else if ($transaction->isOpen()) {
Paytm::where('order_id', $order_id)->update(['status' => 2, 'transaction_id' => $transaction->getTransactionId()]);
return redirect(route('initiate.payment'))->with('message', "Your payment is processing.");
}
$transaction->getResponseMessage(); //Get Response Message If Available
}
public function doku_checkout($identifier)
{
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
$keys = json_decode($payment_gateway->keys, true);
$test_mode = $payment_gateway->test_mode == 1 ? 1 : 0;
$client_id = $keys['client_id'];
if ($test_mode == 1) {
$key = $keys['public_test_key'];
$secret_key = $keys['secret_test_key'];
} else {
$key = $keys['public_live_key'];
$secret_key = $keys['secret_live_key'];
}
$user_id = auth()->user()->id;
$user = DB::table('users')->where('id', $user_id)->first();
$currency = $payment_gateway->currency;
$payment_details = session('payment_details');
$product_title = $payment_details['items'][0]['title'];
$amount = $payment_details['items'][0]['price'];
//Store temporary data
Doku::storeTempData();
$requestBody = array(
'order' => array(
'amount' => $amount,
'invoice_number' => 'INV-' . rand(1, 10000), // Change to your business logic
'currency' => $currency,
'callback_url' => $payment_details["success_url"] . "/$identifier",
'line_items' => array(
0 => array(
'name' => $product_title,
'price' => $amount,
'quantity' => 1,
),
),
),
'payment' => array(
'payment_due_date' => 60,
),
'customer' => array(
'id' => 'CUST-' . rand(1, 1000), // Change to your customer ID mapping
'name' => $user->name,
'email' => $user->email,
'phone' => $user->phone,
'address' => $user->address,
'country' => 'ID',
),
);
$requestId = rand(1, 100000); // Change to UUID or anything that can generate unique value
$dateTime = gmdate("Y-m-d H:i:s");
$isoDateTime = date(DATE_ISO8601, strtotime($dateTime));
$dateTimeFinal = substr($isoDateTime, 0, 19) . "Z";
$clientId = $client_id; // Change with your Client ID
$secretKey = $secret_key; // Change with your Secret Key
// $getUrl = 'https://api-sandbox.doku.com';
if ($test_mode == 1) {
$getUrl = 'https://api-sandbox.doku.com';
} else {
$getUrl = 'https://api.doku.com';
}
$targetPath = '/checkout/v1/payment';
$url = $getUrl . $targetPath;
// Generate digest
$digestValue = base64_encode(hash('sha256', json_encode($requestBody), true));
// Prepare signature component
$componentSignature = "Client-Id:" . $clientId . "\n" .
"Request-Id:" . $requestId . "\n" .
"Request-Timestamp:" . $dateTimeFinal . "\n" .
"Request-Target:" . $targetPath . "\n" .
"Digest:" . $digestValue;
// Generate signature
$signature = base64_encode(hash_hmac('sha256', $componentSignature, $secretKey, true));
// Execute request
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestBody));
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Client-Id:' . $clientId,
'Request-Id:' . $requestId,
'Request-Timestamp:' . $dateTimeFinal,
'Signature:' . "HMACSHA256=" . $signature,
));
// Set response json
$responseJson = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Echo the response
if (is_string($responseJson) && $httpCode == 200) {
return json_decode($responseJson, true);
} else {
return null;
}
}
public function webRedirectToPayFee(Request $request)
{
// Check if the 'auth' query parameter is present
if (!$request->has('auth')) {
return redirect()->route('login')->withErrors([
'email' => 'Authentication token is missing.',
]);
}
// Remove the 'Basic ' prefix
// $base64Credentials = $request->query('auth');
// Remove the 'Basic ' prefix
$base64Credentials = substr($request->query('auth'), 6);
// Decode the base64-encoded string
$credentials = base64_decode($base64Credentials);
// Split the decoded string into email, password, and timestamp
list($email, $password, $timestamp) = explode(':', $credentials);
// Get the current timestamp
$timestamp1 = strtotime(date('Y-m-d'));
// Calculate the difference
$difference = $timestamp1 - $timestamp;
if ($difference < 86400) {
if (auth()->attempt(['email' => $email, 'password' => $password])) {
// Authentication passed...
return redirect(route('cart'));
}
return redirect()->route('login')->withErrors([
'email' => 'Invalid email or password',
]);
} else {
return redirect()->route('login')->withErrors([
'email' => 'Token expired!',
]);
}
}
}

View File

@ -0,0 +1,143 @@
<?php
namespace App\Http\Controllers;
use App\Models\Certificate;
use App\Models\Course;
use App\Models\Enrollment;
use App\Models\Forum;
use App\Models\Lesson;
use App\Models\Watch_history;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class PlayerController extends Controller
{
public function course_player(Request $request, $slug, $id = '')
{
$course = Course::where('slug', $slug)->firstOrNew();
// check if course is paid
if ($course->is_paid && auth()->user()->role != 'admin') {
if (auth()->user()->role == 'student') { // for student check enrollment status
$enroll_status = enroll_status($course->id, auth()->user()->id);
if ($enroll_status == 'expired') {
Session::flash('error', get_phrase('Your course accessibility has expired. You need to buy it again'));
return redirect()->route('course.details', ['slug' => $slug]);
} elseif(! $enroll_status) {
Session::flash('error', get_phrase('Not registered for this course.'));
return redirect()->route('course.details', ['slug' => $slug]);
}
} elseif (auth()->user()->role == 'instructor') { // for instructor check who is course instructor
if ($course->user_id != auth()->user()->id) {
Session::flash('error', get_phrase('Not valid instructor.'));
return redirect()->route('my.courses');
}
}
}
$check_lesson_history = Watch_history::where('course_id', $course->id)
->where('student_id', auth()->user()->id)->first();
$first_lesson_of_course = Lesson::where('course_id', $course->id)->orderBy('sort', 'asc')->value('id');
if ($id == '') {
$id = $check_lesson_history->watching_lesson_id ?? $first_lesson_of_course;
}
// if user has any watched history or not
if (! $check_lesson_history && $id > 0) {
$data = [
'course_id' => $course->id,
'student_id' => auth()->user()->id,
'watching_lesson_id' => $id,
'completed_lesson' => json_encode([])
];
Watch_history::insert($data);
}
// when user plays a lesson, update that lesson id as watch history
if ($id > 0) {
Watch_history::where('course_id', $course->id)
->where('student_id', auth()->user()->id)
->update(['watching_lesson_id' => $id]);
}
$page_data['course_details'] = $course;
$page_data['lesson_details'] = Lesson::where('id', $id)->firstOrNew();
$page_data['history'] = Watch_history::where('course_id', $course->id)->where('student_id', auth()->user()->id)->first();
$forum_query = Forum::join('users', 'forums.user_id', 'users.id')
->select('forums.*', 'users.name as user_name', 'users.photo as user_photo')
->latest('forums.id')
->where('forums.parent_id', 0)
->where('forums.course_id', $course->id);
if (isset($_GET['search'])) {
$forum_query->where(function ($query) use ($request) {
$query->where('forums.title', 'like', '%' . $request->search . '%')->where('forums.description', 'like', '%' . $request->search . '%');
});
}
$page_data['questions'] = $forum_query->get();
return view('course_player.index', $page_data);
}
public function set_watch_history(Request $request)
{
$course = Course::where('id', $request->course_id)->first();
$enrollment = Enrollment::where('course_id', $course->id)->where('user_id', auth()->user()->id)->first();
if (! $enrollment && (auth()->user()->role != 'admin' || ! is_course_instructor($course->id))) {
Session::flash('error', get_phrase('Not registered for this course.'));
return redirect()->back();
}
$data['course_id'] = $request->course_id;
$data['student_id'] = auth()->user()->id;
$total_lesson = Lesson::where('course_id', $request->course_id)->pluck('id')->toArray();
$watch_history = Watch_history::where('course_id', $request->course_id)
->where('student_id', auth()->user()->id)->first();
if (isset($watch_history) && $watch_history->id) {
$lessons = (array) json_decode($watch_history->completed_lesson);
if (! in_array($request->lesson_id, $lessons)) {
array_push($lessons, $request->lesson_id);
} else {
while (($key = array_search($request->lesson_id, $lessons)) !== false) {
unset($lessons[$key]);
}
}
$data['completed_lesson'] = json_encode($lessons);
$data['watching_lesson_id'] = $request->lesson_id;
$data['completed_date'] = (count($total_lesson) == count($lessons)) ? time() : null;
Watch_history::where('course_id', $request->course_id)->where('student_id', auth()->user()->id)->update($data);
} else {
$lessons = [$request->lesson_id];
$data['completed_lesson'] = json_encode($lessons);
$data['watching_lesson_id'] = $request->lesson_id;
$data['completed_date'] = (count($total_lesson) == count($lessons)) ? time() : null;
Watch_history::insert($data);
}
if (progress_bar($request->course_id) >= 100) {
$certificate = Certificate::where('user_id', auth()->user()->id)->where('course_id', $request->course_id);
if ($certificate->count() == 0) {
$certificate_data['user_id'] = auth()->user()->id;
$certificate_data['course_id'] = $request->course_id;
$certificate_data['identifier'] = random(12);
$certificate_data['created_at'] = date('Y-m-d H:i:s');
Certificate::insert($certificate_data);
}
}
return redirect()->back();
}
public function prepend_watermark()
{
return view('course_player.watermark');
}
}

View File

@ -0,0 +1,125 @@
<?php
namespace App\Http\Controllers;
use App\Models\Payment_history;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
class ReportController extends Controller
{
public function admin_revenue(Request $request)
{
if ($request->eDateRange) {
$date = explode('-', $request->eDateRange);
$start_date = strtotime($date[0] . ' 00:00:00');
$end_date = strtotime($date[1] . ' 23:59:59');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['reports'] = Payment_history::where('admin_revenue', '!=', '')->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))
->latest('id')->paginate(10)->appends($request->query());
} else {
$start_date = strtotime('first day of this month');
$end_date = strtotime('last day of this month');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['reports'] = Payment_history::where('admin_revenue', '!=', '')->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))->latest('id')->paginate(10);
}
return view('admin.report.admin_revenue', $page_data);
}
public function admin_revenue_filter(Request $request)
{
if ($request->eDateRange) {
$date = explode('-', $request->eDateRange);
$start_date = strtotime($date[0] . ' 00:00:00');
$end_date = strtotime($date[1] . ' 23:59:59');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['reports'] = Payment_history::where('admin_revenue', '!=', '')->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))
->latest('id')->paginate(10)->appends($request->query());
} else {
$start_date = strtotime('first day of this month');
$end_date = strtotime('last day of this month');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['reports'] = Payment_history::where('admin_revenue', '!=', '')->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))
->latest('id')->paginate(10);
}
return view('admin.report.admin_revenue');
}
public function admin_revenue_delete($id)
{
Payment_history::where('id', $id)->delete();
Session::flash('success', get_phrase('Admin revenue delete successfully'));
return redirect()->back();
}
public function instructor_revenue(Request $request)
{
if ($request->eDateRange) {
$date = explode('-', $request->eDateRange);
$start_date = strtotime($date[0] . ' 00:00:00');
$end_date = strtotime($date[1] . ' 23:59:59');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['reports'] = Payment_history::where('instructor_revenue', '!=', '')->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))
->latest('id')->paginate(10)->appends($request->query());
} else {
$start_date = strtotime('first day of this month');
$end_date = strtotime('last day of this month');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['reports'] = Payment_history::where('instructor_revenue', '!=', '')->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))
->latest('id')->paginate(10);
}
return view('admin.report.instructor_revenue', $page_data);
}
public function instructor_revenue_delete($id)
{
Payment_history::where('id', $id)->delete();
Session::flash('success', get_phrase('Instructor revenue delete successfully'));
return redirect()->back();
}
public function purchase_history(Request $request)
{
if ($request->eDateRange) {
$date = explode('-', $request->eDateRange);
$start_date = strtotime($date[0] . ' 00:00:00');
$end_date = strtotime($date[1] . ' 23:59:59');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['reports'] = Payment_history::where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))
->latest('id')->paginate(10)->appends($request->all());
} else {
$start_date = strtotime('first day of this month');
$end_date = strtotime('last day of this month');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['reports'] = Payment_history::where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))
->latest('id')->paginate(10);
}
return view('admin.report.purchase_history', $page_data);
}
public function purchase_history_invoice($id = '')
{
$page_data['report'] = Payment_history::where('id', $id)->first();
return view('admin.report.report_invoice', $page_data);
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ReviewController extends Controller
{
//
}

View File

@ -0,0 +1,62 @@
<?php
namespace App\Http\Controllers;
use App\Models\FileUploader;
use App\Models\SeoField;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class SeoController extends Controller
{
public function seo_settings($active_tab = "")
{
$page_data = array();
$page_data['seo_meta_tags'] = SeoField::whereNull('course_id')
->whereNull('blog_id')
->whereNull('bootcamp_id')
->get();
$page_data['active_tab'] = !empty($active_tab) ? slugify($active_tab) : 'home';
return view("admin.setting.seo_setting", $page_data);
}
function seo_settings_update(Request $request, $route = "")
{
if (!empty($request->all())) {
$updateSeo = SeoField::where('route', $route)->first();
$updateSeo->meta_title = $request->meta_title;
$updateSeo->meta_keywords = $request->meta_keywords;
$updateSeo->meta_description = $request->meta_description;
$updateSeo->meta_robot = $request->meta_robot;
$updateSeo->canonical_url = $request->canonical_url;
$updateSeo->custom_url = $request->custom_url;
$updateSeo->og_title = $request->og_title;
$updateSeo->og_description = $request->og_description;
$updateSeo->json_ld = $request->json_ld;
if (isset($request->og_image)) {
$originalFileName = $updateSeo->id . '-' . $request->og_image->getClientOriginalName();
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
// Move the file to the destination path
FileUploader::upload($request->og_image, $destinationPath, 600);
remove_file($updateSeo->og_image);
$updateSeo->og_image = $destinationPath;
}
$updateSeo->save();
$page_data = array();
$page_data['seo_meta_tags'] = SeoField::all();
$page_data['active_tab'] = $route;
return redirect('/admin/seo_settings/' . $route)->with('success', 'SEO updated Successfully');
}
return redirect()->back()->with('error', 'Seo update failed');
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,193 @@
<?php
namespace App\Http\Controllers;
use App\Models\FileUploader;
use Artisan;
//database migration
use DB;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use ZipArchive;
class Updater extends Controller
{
public function update(Request $request)
{
$addons_parent_id = null;
$rules = array('file' => 'required|file|mimes:zip');
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->with('error', get_phrase('Select a valid zip file'));
}
//Create update directory
$dir = 'upload';
if (!is_dir($dir) && !file_exists($dir)) {
mkdir($dir, 0777, true);
}
//Uploaded file name
$file_name = $request->file->getClientOriginalName();
$path = $dir . '/' . $file_name;
if (class_exists('ZipArchive')) {
//File uploading..
FileUploader::upload($request->file, '../'.$path);
// Unzip uploaded update file and remove zip file.
$zip = new ZipArchive;
$res = $zip->open(base_path($path));
$zip->extractTo(base_path($dir));
$zip->close();
unlink(base_path($path));
} else {
return redirect()->back()->with('error', get_phrase('Your server is unable to extract the zip file') . '. ' . get_phrase('Please enable the zip extension to the server, then try again'));
}
$uploaded_folder_name = substr($file_name, 0, -4);
$version_ = substr($file_name, 0, -4);
// Exicute php or laravel's code
$step1Exicution = file_get_contents(base_path($dir . '/' . $uploaded_folder_name . '/step1_pre_checker.php'));
if ($step1Exicution) {
eval($step1Exicution);
}
//check required version
$product_current_version = DB::table('settings')->where('type', 'version')->value('description');
$config = file_get_contents(base_path($dir . '/' . $uploaded_folder_name . '/step2_config.json'));
if ($config) {
$config = json_decode($config, true);
}
//check ias addon or main product update
if (array_key_exists('is_addon', $config) && strval($config['is_addon']) == "1") {
//check required main product version to install this addon
if ($config['product_version']['minimum_required_version'] > $product_current_version) {
return redirect()->back()->with('error', get_phrase("You have to update your main application's version.") . '(' . $config['product_version']['minimum_required_version'] . ') ' . get_phrase(' to install the addon'));
}
$addons_current_version = DB::table('addons')->where('unique_identifier', $config['addons'][0]['unique_identifier']);
if ($addons_current_version->get()->count() > 0) {
$addons_current_version = $addons_current_version->value('version');
} else {
$addons_current_version = "0";
}
//check required addon version to update this addon
if (strval($config['addon_version']['minimum_required_version']) != strval($addons_current_version)) {
return redirect()->back()->with('error', get_phrase('It looks like you are skipping a version') . '. ' . get_phrase('Please update version') . ' ' . $config['addon_version']['minimum_required_version'] . ' ' . get_phrase('first'));
}
foreach ($config['addons'] as $addon) {
$data['unique_identifier'] = $addon['unique_identifier'];
$data['title'] = $addon['title'];
$data['version'] = $config['addon_version']['update_version'];
$data['features'] = $addon['features'];
$data['status'] = 1;
$data['parent_id'] = $addons_parent_id;
$parent_id = DB::table('addons')->insertGetId($data);
if ($addons_parent_id == null) {
$addons_parent_id = $parent_id;
}
}
} else {
//check required main product version
if (strval($config['product_version']['minimum_required_version']) != strval($product_current_version)) {
return redirect()->back()->with('error', get_phrase('It looks like you are skipping a version') . '. ' . get_phrase('Please update version') . ' ' . $config['product_version']['minimum_required_version'] . ' ' . get_phrase('first'));
}
}
//Update files, folders and libraries
$this->fileAndFolderDistributor($uploaded_folder_name);
//run SQL file
$sql = file_get_contents(base_path($dir . '/' . $uploaded_folder_name . '/step3_database.sql'));
if ($sql) {
DB::unprepared($sql);
}
// Exicute php or laravel's code
$step4Exicution = file_get_contents(base_path($dir . '/' . $uploaded_folder_name . '/step4_update_data.php'));
if ($step4Exicution) {
eval($step4Exicution);
}
if (array_key_exists('is_addon', $config) && strval($config['is_addon']) == "1") {
if ($config['addon_version']['minimum_required_version'] == "0") {
return redirect()->back()->with('success', get_phrase('Addon installed successfully'));
} else {
return redirect()->back()->with('success', get_phrase('Addon updated successfully'));
}
} else {
DB::table('settings')->where('type', 'version')->update(['description' => $config['product_version']['update_version']]);
return redirect()->back()->with('success', get_phrase('Version updated successfully'));
}
}
public function fileAndFolderDistributor($param1, $param2 = "")
{
if ($param2 == "") {
$param2 = $param1;
$uploaded_dir_path = base_path('upload/' . $param1 . '/sources');
} else {
$uploaded_dir_path = $param1;
}
$uploaded_dir_paths = glob($uploaded_dir_path . '/*');
foreach ($uploaded_dir_paths as $uploaded_sub_dir_path) {
if (is_dir($uploaded_sub_dir_path)) {
$all_available_sub_paths = count(glob($uploaded_sub_dir_path . '/*'));
if ($all_available_sub_paths == 0) {
//Create directory
$application_dir_path = str_replace('upload/' . $param2 . '/sources/', "", $uploaded_sub_dir_path);
if (!is_dir($application_dir_path) && !file_exists($application_dir_path)) {
mkdir($application_dir_path, 0777, true);
}
} else {
$this->fileAndFolderDistributor($uploaded_sub_dir_path, $param2);
}
} else {
$application_file_path = str_replace('upload/' . $param2 . '/sources/', "", $uploaded_sub_dir_path);
//Check dir. If not exist then created
$file_path_arr = explode("/", $application_file_path);
$file_name = $file_path_arr[count($file_path_arr) - 1];
$application_dir_path = str_replace('/' . $file_name, "", $application_file_path);
if (!is_dir($application_dir_path) && !file_exists($application_dir_path)) {
mkdir($application_dir_path, 0777, true);
}
//Copy file to application path
copy($uploaded_sub_dir_path, $application_file_path);
//Zip file extract for any big size libraries
if (pathinfo($file_name, PATHINFO_EXTENSION) == 'zip') {
// PATH OF EXTRACTING LIBRARY FILE
array_pop($file_path_arr);
$extract_to = implode('/', $file_path_arr);
$library_zip = new ZipArchive;
$library_result = $library_zip->open($application_file_path);
$library_zip->extractTo($extract_to);
$library_zip->close();
unlink($application_file_path);
}
}
}
}
}

View File

@ -0,0 +1,692 @@
<?php
namespace App\Http\Controllers;
use App\Models\Application;
use App\Models\Course;
use App\Models\Enrollment;
use App\Models\FileUploader;
use App\Models\Payout;
use App\Models\Permission;
use App\Models\Setting;
use App\Models\Message;
use App\Models\MessageThread;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Str;
class UsersController extends Controller
{
public function admin_index(Request $request)
{
$query = User::where('role', 'admin');
if (isset($_GET['search']) && $_GET['search'] != '') {
$query = $query->where('name', 'LIKE', '%' . $_GET['search'] . '%')
->orWhere('email', 'LIKE', '%' . $_GET['search'] . '%');
}
$page_data['admins'] = $query->paginate(10);
return view('admin.admin.index', $page_data);
}
public function admin_create()
{
return view('admin.admin.create_admin');
}
public function admin_store(Request $request)
{
$validated = $request->validate([
'name' => "required",
'email' => 'required|email|unique:users',
'password' => "required|min:8",
]);
$data['name'] = $request->name;
$data['about'] = $request->about;
$data['phone'] = $request->phone;
$data['address'] = $request->address;
$data['email'] = $request->email;
$data['password'] = Hash::make($request->password);
$data['facebook'] = $request->facebook;
$data['twitter'] = $request->twitter;
$data['website'] = $request->website;
$data['linkedin'] = $request->linkedin;
$data['role'] = 'admin';
$data['status'] = '1';
if (isset($request->photo) && $request->hasFile('photo')) {
$path = "uploads/users/instructor/" . nice_file_name($request->name, $request->photo->extension());
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
$data['photo'] = $path;
}
$done = User::insert($data);
if ($done) {
$admin_id = User::latest('id')->first();
Permission::insert(['admin_id' => $admin_id->id]);
}
Session::flash('success', get_phrase('Admin add successfully'));
return redirect()->route('admin.admins.index');
}
public function admin_edit($id)
{
$page_data['admin'] = User::where('id', $id)->first();
return view('admin.admin.edit_admin', $page_data);
}
public function admin_update(Request $request, $id)
{
$validated = $request->validate([
'name' => 'required|max:255',
'email' => "required|email|unique:users,email,$id",
]);
$data['name'] = $request->name;
$data['about'] = $request->about;
$data['phone'] = $request->phone;
$data['address'] = $request->address;
$data['email'] = $request->email;
$data['facebook'] = $request->facebook;
$data['twitter'] = $request->twitter;
$data['website'] = $request->website;
$data['linkedin'] = $request->linkedin;
if (isset($request->photo) && $request->hasFile('photo')) {
remove_file(User::where('id', $id)->first()->photo);
$path = "uploads/users/instructor/" . nice_file_name($request->name, $request->photo->extension());
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
$data['photo'] = $path;
}
User::where('id', $request->id)->update($data);
Session::flash('success', get_phrase('Admin update successfully'));
return redirect()->route('admin.admins.index');
}
public function admin_delete($id)
{
$threads = MessageThread::where('contact_one', $id)
->orWhere('contact_two', $id)
->pluck('id');
if ($threads->isNotEmpty()) {
Message::whereIn('thread_id', $threads)->delete();
MessageThread::whereIn('id', $threads)->delete();
}
$done = User::where('id', $id)->delete();
if ($done) {
Permission::where('admin_id', $id)->delete();
}
Session::flash('success', get_phrase('Admin delete successfully'));
return redirect()->back();
}
public function admin_permission($user_id)
{
$page_data['admin'] = User::where('id', $user_id)->firstOrNew();
return view('admin.admin.permission', $page_data);
}
public function admin_permission_store(Request $request)
{
$user_id = $request->user_id;
$permission = Permission::where('admin_id', $user_id)->first();
if ($permission) {
$set_permission = json_decode($permission->permissions, true) ?? [];
if (in_array($request->permission, $set_permission)) {
$pos = array_search($request->permission, $set_permission);
array_splice($set_permission, $pos, 1);
} else {
array_push($set_permission, $request->permission);
}
Permission::where('admin_id', $user_id)->update(['permissions' => $set_permission]);
return true;
} else {
$set_per = json_encode([$request->permission]);
Permission::insert(['admin_id' => $user_id, 'permissions' => $set_per]);
return true;
}
}
public function instructor_index()
{
$query = User::where('role', 'instructor');
if (isset($_GET['search']) && $_GET['search'] != '') {
$query = $query->where('name', 'LIKE', '%' . $_GET['search'] . '%')
->orWhere('email', 'LIKE', '%' . $_GET['search'] . '%');
}
$page_data['instructors'] = $query->paginate(10);
return view('admin.instructor.index', $page_data);
}
public function instructor_create()
{
return view('admin.instructor.create_instructor');
}
public function instructor_edit($id = '')
{
$page_data['instructor'] = User::where('id', $id)->first();
return view('admin.instructor.edit_instructor', $page_data);
}
public function instructor_store(Request $request, $id = '')
{
$validated = $request->validate([
'name' => "required|max:255",
'email' => 'required|email|unique:users',
'password' => "required|min:8",
]);
if(get_settings('student_email_verification') != 1){
$data['email_verified_at'] = date('Y-m-d H:i:s');
}
$data['name'] = $request->name;
$data['about'] = $request->about;
$data['phone'] = $request->phone;
$data['address'] = $request->address;
$data['email'] = $request->email;
$data['facebook'] = $request->facebook;
$data['twitter'] = $request->twitter;
$data['website'] = $request->website;
$data['linkedin'] = $request->linkedin;
$data['paymentkeys'] = json_encode($request->paymentkeys);
$data['status'] = '1';
$data['password'] = Hash::make($request->password);
$data['role'] = 'instructor';
$data['email_verified_at'] = $request->email_verified == 1 ? now() : null;
if (isset($request->photo) && $request->hasFile('photo')) {
$path = "uploads/users/instructor/" . nice_file_name($request->name, $request->photo->extension());
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
$data['photo'] = $path;
}
$user = User::create($data);
if(get_settings('student_email_verification') == 1) {
$user->sendEmailVerificationNotification();
}
Session::flash('success', get_phrase('Instructor add successfully'));
return redirect()->route('admin.instructor.index');
}
public function instructor_update(Request $request, $id = '')
{
$validated = $request->validate([
'name' => 'required|max:255',
'email' => "required|email|unique:users,email,$id",
]);
$data['name'] = $request->name;
$data['about'] = $request->about;
$data['phone'] = $request->phone;
$data['address'] = $request->address;
$data['email'] = $request->email;
$data['facebook'] = $request->facebook;
$data['twitter'] = $request->twitter;
$data['website'] = $request->website;
$data['linkedin'] = $request->linkedin;
$data['paymentkeys'] = json_encode($request->paymentkeys);
if (isset($request->photo) && $request->hasFile('photo')) {
remove_file(User::where('id', $id)->first()->photo);
$path = "uploads/users/instructor/" . nice_file_name($request->name, $request->photo->extension());
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
$data['photo'] = $path;
}
User::where('id', $id)->update($data);
Session::flash('success', get_phrase('Instructor update successfully'));
return redirect()->route('admin.instructor.index');
}
public function instructor_delete($id)
{
$threads = MessageThread::where('contact_one', $id)
->orWhere('contact_two', $id)
->pluck('id');
if ($threads->isNotEmpty()) {
Message::whereIn('thread_id', $threads)->delete();
MessageThread::whereIn('id', $threads)->delete();
}
User::where('id', $id)->delete();
Session::flash('success', get_phrase('Instructor delete successfully'));
return redirect()->back();
}
public function instructor_view_course(Request $request)
{
$course = Course::where('user_id', $request->id)->get();
}
public function instructor_payout(Request $request)
{
$start_date = strtotime('first day of this month');
$end_date = strtotime('last day of this month');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['instructor_payout_complete'] = Payout::where('status', 1)->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))->paginate(10);
$page_data['instructor_payout_incomplete'] = Payout::where('status', 0)->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))->paginate(10);
return view('admin.instructor.payout', $page_data);
}
public function instructor_payout_filter(Request $request)
{
$date = explode('-', $request->eDateRange);
$start_date = strtotime($date[0] . ' 00:00:00');
$end_date = strtotime($date[1] . ' 23:59:59');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['instructor_payout_complete'] = Payout::where('status', 1)->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))->paginate(10);
$page_data['instructor_payout_incomplete'] = Payout::where('status', 0)->paginate(10);
return view('admin.instructor.payout', $page_data);
}
public function instructor_payout_invoice($id = '')
{
if ($id != '') {
$page_data['invoice_info'] = Payout::where('status', 1)->first();
$page_data['invoice_data'] = Payout::where('status', 1)->get();
$page_data['invoice_id'] = $id;
return view('admin.instructor.instructor_invoice', $page_data);
}
}
public function instructor_payment(Request $request)
{
$id = $request->user_id;
$payable_amount = $request->amount;
$start_timestamp = time();
$end_timestamp = time();
$payment_details = [
'items' => [
[
'id' => $id,
'title' => get_phrase('Pay for instructor payout'),
'subtitle' => get_phrase(''),
'price' => $payable_amount,
'discount_price' => $payable_amount,
'discount_percentage' => 0,
],
],
'custom_field' => [
'start_date' => date('Y-m-d H:i:s', $start_timestamp),
'end_date' => date('Y-m-d H:i:s', $end_timestamp),
'user_id' => auth()->user()->id,
'payout_id' => $request->payout_id,
],
'success_method' => [
'model_name' => 'InstructorPayment',
'function_name' => 'instructor_payment',
],
'tax' => 0,
'coupon' => null,
'payable_amount' => $payable_amount,
'cancel_url' => route('admin.instructor.payout'),
'success_url' => route('payment.success'),
];
session(['payment_details' => $payment_details]);
return redirect()->route('payment');
}
public function instructor_setting()
{
$page_data['allow_instructor'] = Setting::where('type', 'allow_instructor')->first();
$page_data['application_note'] = Setting::where('type', 'instructor_application_note')->first();
$page_data['instructor_revenue'] = Setting::where('type', 'instructor_revenue')->first();
return view('admin.instructor.instructor_setting', $page_data);
}
public function instructor_setting_store(Request $request)
{
if ($request->first == 'item_1') {
$key_found = Setting::where('type', 'instructor_application_note')->exists();
if ($key_found) {
$data['description'] = $request->instructor_application_note;
Setting::where('type', 'instructor_application_note')->update($data);
} else {
$data['type'] = 'instructor_application_note';
$data['description'] = $request->instructor_application_note;
Setting::insert($data);
}
$key_founds = Setting::where('type', 'allow_instructor')->exists();
if ($key_founds) {
$data['description'] = $request->allow_instructor;
Setting::where('type', 'allow_instructor')->update($data);
} else {
$data['type'] = 'allow_instructor';
$data['description'] = $request->allow_instructor;
Setting::insert($data);
}
}
if ($request->second == 'item_2') {
$key_found = Setting::where('type', 'instructor_revenue')->exists();
if ($key_found) {
$data['description'] = $request->instructor_revenue;
Setting::where('type', 'instructor_revenue')->update($data);
} else {
$data['type'] = 'instructor_revenue';
$data['description'] = $request->instructor_revenue;
Setting::insert($data);
}
}
Session::flash('success', get_phrase('Instructor setting updated'));
return redirect()->back();
}
public function instructor_application()
{
return view('admin.instructor.application');
}
public function instructor_application_approve($id)
{
$query = Application::where('id', $id);
$update_status = $query->update(['status' => 1]);
if ($update_status) {
$user_id = $query->first();
User::where('id', $user_id->user_id)->update(['role' => 'instructor']);
Session::flash('success', get_phrase('Application approve successfully'));
}
return redirect()->back();
}
public function instructor_application_delete($id)
{
Application::where('id', $id)->delete();
Session::flash('success', get_phrase('Application delete successfully'));
return redirect()->back();
}
public function instructor_application_download($id)
{
$path = Application::where('id', $id)->first();
if (file_exists(public_path($path->document))) {
return response()->download(public_path($path->document));
} else {
Session::flash('error', get_phrase('File does not exists'));
return redirect()->back();
}
}
public function revokeAccess($id)
{
$user = User::findOrFail($id);
if ($user->role === 'instructor') {
$user->role = 'student';
$user->save();
Session::flash('success', get_phrase('Instructor has been switched to Student successfully.'));
} else {
Session::flash('error', get_phrase('This user is not an instructor.'));
}
return redirect()->back();
}
public function student_index()
{
$query = User::where('role', 'student');
if (isset($_GET['search']) && $_GET['search'] != '') {
$query = $query->where('name', 'LIKE', '%' . $_GET['search'] . '%')
->orWhere('email', 'LIKE', '%' . $_GET['search'] . '%');
}
$page_data['students'] = $query->paginate(10);
return view('admin.student.index', $page_data);
}
public function student_create()
{
return view('admin.student.create_student');
}
public function student_edit($id = '')
{
$page_data['student'] = User::where('id', $id)->first();
return view('admin.student.edit_student', $page_data);
}
public function student_store(Request $request, $id = '')
{
$validated = $request->validate([
'name' => 'required|max:255',
'email' => 'required|email|unique:users',
'password' => 'required',
]);
if(get_settings('student_email_verification') != 1){
$data['email_verified_at'] = date('Y-m-d H:i:s');
}
$data['name'] = $request->name;
$data['about'] = $request->about;
$data['phone'] = $request->phone;
$data['address'] = $request->address;
$data['email'] = $request->email;
$data['facebook'] = $request->facebook;
$data['twitter'] = $request->twitter;
$data['website'] = $request->website;
$data['linkedin'] = $request->linkedin;
$data['paymentkeys'] = json_encode($request->paymentkeys);
$data['status'] = '1';
$data['password'] = Hash::make($request->password);
$data['role'] = 'student';
$data['email_verified_at'] = $request->email_verified == 1 ? now() : null;
if (isset($request->photo) && $request->hasFile('photo')) {
$path = "uploads/users/student/" . nice_file_name($request->name, $request->photo->extension());
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
$data['photo'] = $path;
}
$user = User::create($data);
if(get_settings('student_email_verification') == 1) {
$user->sendEmailVerificationNotification();
}
Session::flash('success', get_phrase('Student add successfully'));
return redirect()->route('admin.student.index');
}
public function student_update(Request $request, $id = '')
{
$validated = $request->validate([
'name' => 'required|max:255',
'email' => "required|email|unique:users,email,$id",
]);
$data['name'] = $request->name;
$data['about'] = $request->about;
$data['phone'] = $request->phone;
$data['address'] = $request->address;
$data['email'] = $request->email;
$data['facebook'] = $request->facebook;
$data['twitter'] = $request->twitter;
$data['website'] = $request->website;
$data['linkedin'] = $request->linkedin;
$data['paymentkeys'] = json_encode($request->paymentkeys);
if (isset($request->photo) && $request->hasFile('photo')) {
remove_file(User::where('id', $id)->first()->photo);
$path = "uploads/users/student/" . nice_file_name($request->name, $request->photo->extension());
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
$data['photo'] = $path;
}
User::where('id', $id)->update($data);
Session::flash('success', get_phrase('Student update successfully'));
return redirect()->route('admin.student.index');
}
public function student_delete($id)
{
$threads = MessageThread::where('contact_one', $id)
->orWhere('contact_two', $id)
->pluck('id');
if ($threads->isNotEmpty()) {
Message::whereIn('thread_id', $threads)->delete();
MessageThread::whereIn('id', $threads)->delete();
}
$query = User::where('id', $id);
remove_file($query->first()->photo);
$query->delete();
return redirect(route('admin.student.index'))->with('success', get_phrase('User deleted successfully'));
}
public function student_enrol()
{
return view('admin.enroll.course_enrollment');
}
public function student_get(Request $request)
{
$user = User::where('role', 'student')->where('name', 'LIKE', '%' . $request->searchVal . '%')->get();
foreach ($user as $row) {
$response[] = ['id' => $row->id, 'text' => $row->name];
}
return json_encode($response);
}
public function student_post(Request $request)
{
for ($i = 0; $i < count($request->user_id); $i++) {
for ($j = 0; $j < count($request->course_id); $j++) {
$data['user_id'] = $request->user_id[$i];
$data['course_id'] = $request->course_id[$j];
$data['entry_date'] = time();
$course_details = $course_details = get_course_info($request->course_id[$j]);
if ($course_details->expiry_period > 0) {
$days = $course_details->expiry_period * 30;
$data['expiry_date'] = strtotime("+" . $days . " days");
} else {
$data['expiry_date'] = null;
}
$user = Enrollment::where('user_id', $request->user_id[$i])->where('course_id', $request->course_id[$j])->exists();
if (!$user) {
Enrollment::insert($data);
}
}
}
Session::flash('success', get_phrase('Student add successfully'));
return redirect()->route('admin.enroll.history');
}
public function enroll_history(Request $request)
{
if ($request->eDateRange) {
$date = explode('-', $request->eDateRange);
$start_date = strtotime($date[0] . ' 00:00:00');
$end_date = strtotime($date[1] . ' 23:59:59');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['enroll_history'] = Enrollment::where('entry_date', '>=', $start_date)
->where('entry_date', '<=', $end_date)
->paginate(10)->appends($request->query());
} else {
$start_date = strtotime('first day of this month ');
$end_date = strtotime('last day of this month');
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['enroll_history'] = Enrollment::where('entry_date', '>=', $start_date)
->where('entry_date', '<=', $end_date)->paginate(10);
}
return view('admin.enroll.enroll_history', $page_data);
}
public function enroll_history_delete($id)
{
Enrollment::where('id', $id)->delete();
Session::flash('success', get_phrase('Enroll delete successfully'));
return redirect()->back();
}
public function manage_profile()
{
return view('admin.profile.index');
}
public function manage_profile_update(Request $request)
{
if ($request->type == 'general') {
$profile['name'] = $request->name;
$profile['email'] = $request->email;
$profile['facebook'] = $request->facebook;
$profile['linkedin'] = $request->linkedin;
$profile['twitter'] = $request->twitter;
$profile['about'] = $request->about;
$profile['skills'] = $request->skills;
$profile['biography'] = $request->biography;
if ($request->photo) {
if (isset($request->photo) && $request->photo != '') {
$profile['photo'] = "uploads/users/admin/" . nice_file_name($request->title, $request->photo->extension());
FileUploader::upload($request->photo, $profile['photo'], 400, null, 200, 200);
}
}
User::where('id', auth()->user()->id)->update($profile);
} else {
$old_pass_check = Auth::attempt(['email' => auth()->user()->email, 'password' => $request->current_password]);
if (!$old_pass_check) {
Session::flash('error', get_phrase('Current password wrong.'));
return redirect()->back();
}
if ($request->new_password != $request->confirm_password) {
Session::flash('error', get_phrase('Confirm password not same'));
return redirect()->back();
}
$password = Hash::make($request->new_password);
User::where('id', auth()->user()->id)->update(['password' => $password]);
}
Session::flash('success', get_phrase('Your changes has been saved.'));
return redirect()->back();
}
}

View File

@ -0,0 +1,127 @@
<?php
namespace App\Http\Controllers;
use FFMpeg\Coordinate\Point;
use FFMpeg\Coordinate\TimeCode;
use FFMpeg\Format\Video\X264;
use Illuminate\Support\Facades\File;
use Intervention\Image\Facades\Image;
use ProtoneMedia\LaravelFFMpeg\Filters\WatermarkFactory;
use ProtoneMedia\LaravelFFMpeg\Support\FFMpeg;
class WatermarkController extends Controller
{
public static function encode($video, $file_name, $path)
{
$full_output_path = "{$path}/watermark/{$file_name}";
$output = str_replace(public_path(''), '', $full_output_path);
$watermark_data = self::getWatermarkData();
FFMpeg::fromDisk('public')
->open($video)
->addWatermark(function (WatermarkFactory $watermark) use ($watermark_data) {
$watermark->fromDisk('public')
->open($watermark_data['logo'])
->top($watermark_data['top'])
->left($watermark_data['left']);
})
->export()
->inFormat(new X264())
->toDisk('public')
->save($output);
self::deleteTempWatermark(public_path($watermark_data['logo']));
return true;
}
public static function getWatermarkData()
{
$watermark = [
'top' => get_player_settings('watermark_top') ?? 0,
'left' => get_player_settings('watermark_left') ?? 0,
'opacity' => get_player_settings('watermark_opacity'),
'logo' => self::makeTempWatermark(get_player_settings('watermark_logo')),
];
return $watermark;
}
public static function makeTempWatermark($logo)
{
$temp_img_name = File::name($logo) . '.png';
$path = 'uploads/watermark/temp';
$temp_path = public_path($path);
$watermark = "{$path}/{$temp_img_name}";
$width = get_player_settings('watermark_width') ?? 200;
$height = get_player_settings('watermark_height') ?? 120;
$opacity = get_player_settings('watermark_opacity') ?? 10;
if (! File::exists($temp_path)) {
File::makeDirectory($temp_path, 0755, true);
}
Image::make(public_path($logo))
->encode('png', 90)
->opacity($opacity)
->orientate()
->resize($width, $height, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})
->save(public_path($watermark));
return $watermark;
}
public static function deleteTempWatermark($path)
{
if (is_file($path) && file_exists($path)) {
remove_file($path);
}
}
// randomly changes position (not finished)
public static function randomPositionWatermark($file, $file_name, $path)
{
$full_output_path = "{$path}/{$file_name}";
$output = str_replace(public_path(''), '', $full_output_path);
$watermark_data = self::getWatermarkData();
$inputPath = $file;
$outputPath = $output;
$watermarkImagePath = public_path($watermark_data['logo']);
$watermarkImagePath = $watermark_data['logo'];
$ffmpeg = FFMpeg::fromDisk('public')
->open($inputPath);
$duration = $ffmpeg->getDurationInSeconds();
$videoDimensions = $ffmpeg->getVideoStream()->getDimensions();
$width = $videoDimensions->getWidth();
$height = $videoDimensions->getHeight();
$ffmpeg->addFilter(function ($filters) use ($width, $height, $watermarkImagePath, $duration) {
for ($time = 0; $time < $duration; $time++) {
$x = rand(0, $width - 100);
$y = rand(0, $height - 100);
$filters->watermark($watermarkImagePath, [
'position' => new Point($x, $y),
'start_time' => TimeCode::fromSeconds($time),
'duration' => 3,
]);
}
});
$ffmpeg->export()
->toDisk('public')
->inFormat(new X264)
->save($outputPath);
self::deleteTempWatermark(public_path($watermark_data['logo']));
return true;
}
}

View File

@ -0,0 +1,158 @@
<?php
namespace App\Http\Controllers;
use Exception;
use Illuminate\Http\Request;
class ZoomMeetingController extends Controller
{
public static function createToken()
{
$clientId = get_settings('zoom_client_id');
$clientSecret = get_settings('zoom_client_secret');
$accountId = get_settings('zoom_account_id');
$oauthUrl = 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId;
try {
// Create the Basic Authentication header
$authHeader = 'Basic ' . base64_encode($clientId . ':' . $clientSecret);
$ch = curl_init($oauthUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $authHeader));
// Execute cURL session and get the response
$response = curl_exec($ch);
// Check if the request was successful (status code 200)
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
$oauthResponse = json_decode($response, true);
$accessToken = $oauthResponse['access_token'];
http_response_code(200);
header('Content-Type: application/json');
return $accessToken;
} else {
echo 'OAuth Request Failed with Status Code: ' . $httpCode . PHP_EOL;
echo $response . PHP_EOL;
return null;
}
} catch (Exception $e) {
echo 'An error occurred: ' . $e->getMessage() . PHP_EOL;
return null;
}
}
public static function createMeeting($topic, $time, $duration)
{
$zoom_account_email = get_settings('zoom_account_email');
$token = self::createToken();
// API Endpoint for creating a meeting
$zoomEndpoint = 'https://api.zoom.us/v2/users/me/meetings';
// Meeting data
$meetingData = [
'topic' => $topic,
'schedule_for' => $zoom_account_email,
'type' => 2,
'start_time' => date('Y-m-d\TH:i:s', strtotime($time)),
'duration' => $duration,
'timezone' => get_settings('timezone'),
'settings' => [
'approval_type' => 2,
'join_before_host' => true,
'jbh_time' => 0,
],
];
// Prepare headers
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
// Make POST request to create meeting
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
// JSON response
return $response;
}
public static function updateMeeting($topic, $time, $meetingId)
{
$token = self::createToken();
// API Endpoint for updating a meeting
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
// Meeting data with updated start time
$meetingData = [
'topic' => $topic,
'start_time' => date('Y-m-d\TH:i:s', strtotime($time)),
];
// Prepare headers
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
// Make PATCH request to update meeting
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
// JSON response
return $response;
}
public static function deleteMeeting($meetingId)
{
$token = self::createToken();
// API Endpoint for deleting a meeting
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
// Prepare headers
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
// Make DELETE request to delete meeting
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
// JSON response
return $response;
}
public static function config()
{
$data['clientId'] = get_settings('zoom_client_id');
$data['clientSecret'] = get_settings('zoom_client_secret');
$data['accountId'] = get_settings('zoom_account_id');
$data['email'] = get_settings('zoom_account_email');
return $data;
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
class AboutController extends Controller
{
public function index()
{
$page_data['instructors'] = User::where('role', 'instructor')->inRandomOrder()->take(8)->get();
$view_path = 'frontend.' . get_frontend_settings('theme') . '.about_us.index';
return view($view_path, $page_data);
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Blog;
use App\Models\BlogCategory;
use App\Models\BlogComment;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class BlogController extends Controller
{
public function index(Request $request, $category = '')
{
$category_row = BlogCategory::where('slug', $category)->first();
$query = Blog::query();
// search result
if (request()->has('search')) {
$search = request()->input('search');
$query->where(function ($query) use ($search) {
$query->where('title', 'LIKE', '%' . $search . '%');
$query->orWhere('description', 'LIKE', '%' . $search . '%');
});
}
// if blog has category
if ($category != '') {
$query->where('category_id', $category_row->id);
}
$page_data['blogs'] = $query->latest('id')->paginate(6)->appends($request->query());
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.blog.index';
return view($view_path, $page_data);
}
public function blog_details($slug)
{
$query = Blog::join('users', 'blogs.user_id', 'users.id')
->select(
'blogs.*',
'users.name as author_name',
'users.email as author_email',
'users.photo as author_photo',
'users.skills as author_skills',
'users.biography as author_biography',
'users.facebook as author_facebook',
'users.linkedin as author_linkedin',
'users.twitter as author_twitter',
)
->where('blogs.slug', $slug);
// if selected blog doesn't exists return back page
if ($query->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$blog_details = $query->first();
$page_data['blog_details'] = $blog_details;
$page_data['blog_comments'] = BlogComment::join('users', 'blog_comments.user_id', '=', 'users.id')
->select('blog_comments.*', 'users.name as commentator_name', 'users.photo as commentator_photo')
->where('blog_comments.blog_id', $blog_details->id)
->where('blog_comments.parent_id', null)
->latest('id')->get();
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.blog.details';
return view($view_path, $page_data);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Bootcamp;
use App\Models\BootcampCategory;
use App\Models\BootcampModule;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Str;
class BootcampController extends Controller
{
public function index($category = '')
{
$query = Bootcamp::join('users', 'bootcamps.user_id', 'users.id')
->join('bootcamp_categories', 'bootcamps.category_id', 'bootcamp_categories.id')
->select('bootcamps.*', 'bootcamp_categories.slug as category_slug', 'users.name as instructor_name', 'users.email as instructor_email', 'users.photo as instructor_image')
->where('bootcamps.status', 1);
if (request()->has('search')) {
$query = $query->where('bootcamps.title', 'LIKE', '%' . request()->query('search') . '%');
}
if ($category) {
$query->where('bootcamp_categories.slug', $category);
}
$page_data['bootcamps'] = $query->paginate(9)->appends(request()->query());
return view(theme_path() . 'bootcamp.index', $page_data);
}
public function show($slug)
{
// bootcamp details
$bootcamp = Bootcamp::where(['status' => 1, 'slug' => $slug]);
if ($bootcamp->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$bootcamp_details = $bootcamp->first();
$page_data['bootcamp_details'] = $bootcamp_details;
$page_data['modules'] = BootcampModule::where('bootcamp_id', $bootcamp_details->id)->get();
return view(theme_path() . 'bootcamp.details', $page_data);
}
}

View File

@ -0,0 +1,102 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\MessageThread;
use App\Models\Message;
use App\Models\User;
use Illuminate\Http\Request;
class Chatcontroller extends Controller
{
public function studentQuery(Request $request)
{
$data = $request->all();
$message = $data['message'];
$receiver = $data['receiver_id'];
$sender = auth()->user()->id;
//check if the thread between those 2 users exists, if not create new thread
$check = MessageThread::where('sender', $sender)->where('receiver', $receiver)->count();
if ($check == 0) {
$data_message_thread = new MessageThread();
$message_thread_code = substr(md5(rand(100000000, 20000000000)), 0, 15);
$data_message_thread['message_thread_code'] = $message_thread_code;
$data_message_thread['sender'] = $sender;
$data_message_thread['receiver'] = $receiver;
$data_message_thread->save();
} elseif ($check > 0) {
$message_thread_code = MessageThread::where('sender', $sender)->where('receiver', $receiver)->value('message_thread_code');
}
$data_message = new Message();
$data_message['message_thread_code'] = $message_thread_code;
$data_message['message'] = $message;
$data_message['sender'] = $sender;
$data_message['read_status'] = 0;
$data_message->save();
return redirect()->back();
}
function mark_thread_messages_read($message_thread_code)
{
// mark read only the oponnent messages of this thread, not currently logged in user's sent messages
Message::where('sender', '!=', auth()->user()->id)
->where('message_thread_code', $message_thread_code)
->update([
'read_status' => 1,
]);
}
public function agentMessage($param1 = '', $param2 = '')
{
if (empty($param1)) {
$param1 = 'message_home';
}
if ($param1 == 'message_read') {
$page_data['current_message_thread_code'] = $param2;
$this->mark_thread_messages_read($param2);
$message_thread_details = MessageThread::where('message_thread_code', $param2)->first();
$page_data['first_sender'] = $message_thread_details->sender;
$page_data['sender'] = $message_thread_details->message_to_sender->name;
$page_data['receiver'] = $message_thread_details->message_to_receiver->name;
$page_data['messages'] = Message::where('message_thread_code', $param2)->get();
} else {
$page_data['current_message_thread_code'] = '';
}
$message_threads = MessageThread::where('sender', auth()->user()->id)
->get();
$page_data['message_threads'] = $message_threads;
$page_data['message_inner_page_name'] = $param1;
$page_data['agent_messages'] = 'active';
$page_data['navigation_name'] = 'Messaging with Agents';
return view('frontend.my-courses.message', $page_data);
}
public function agentReplyMessage(Request $request, $param1 = '')
{
$data = $request->all();
$message = $data['message'];
$sender = auth()->user()->id;
$data_message['message_thread_code'] = $param1;
$data_message['message'] = $message;
$data_message['sender'] = $sender;
$data_message['read_status'] = 0;
Message::create($data_message);
return redirect()->route('agentMessage', ['param1' => 'message_read', 'param2' => $param1]);
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Contact;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class ContactController extends Controller
{
public function index()
{
$view_path = 'frontend.' . get_frontend_settings('theme') . '.contact_us.index';
return view($view_path);
}
public function store(Request $request)
{
$input = $request->all();
if (get_frontend_settings('recaptcha_status') == true && check_recaptcha($input['g-recaptcha-response']) == false) {
Session::flash('error', get_phrase('Recaptcha verification failed'));
return redirect(route('contact.us'));
}
// check duplicate
if (Contact::where('email', $request->email)->exists()) {
Session::flash('error', get_phrase('This email has been taken.'));
return redirect()->back();
}
// validate user data
$rules = [
'name' => 'required',
'email' => 'required',
'phone' => 'required',
'address' => 'required',
'message' => 'required',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
// process data
$contact['name'] = $request->name;
$contact['email'] = $request->email;
$contact['phone'] = $request->phone;
$contact['address'] = $request->address;
$contact['message'] = $request->message;
// insert data
Contact::insert($contact);
// redirect back
Session::flash('success', get_phrase('Your record has been saved.'));
return redirect()->back();
}
}

View File

@ -0,0 +1,179 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Course;
use App\Models\Enrollment;
use App\Models\Lesson;
use App\Models\Section;
use App\Models\User;
use App\Models\Wishlist;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class CourseController extends Controller
{
public function index(Request $request, $category = '')
{
$layout = Session::has('view') ? session('view') : 'grid';
$page_data['layout'] = $layout;
$query = Course::join('users', 'courses.user_id', '=', 'users.id')
->select('courses.*', 'users.name as instructor_name', 'users.email as instructor_email', 'users.photo as instructor_image')
->where('courses.status', 'active');
// filter by category
if ($category != '') {
$category_details = Category::where('slug', $request->category)->first();
if ($category_details->parent_id > 0) {
$page_data['child_cat'] = $request->category;
$query = $query->where('category_id', $category_details->id);
} else {
$sub_cat_id = Category::where('parent_id', $category_details->id)->pluck('id')->toArray();
$sub_cat_id[] = $category_details->id;
$query = $query->whereIn('category_id', $sub_cat_id);
$page_data['parent_cat'] = $request->category;
}
}
// searched courses
if (request()->has('search')) {
$query->where(function ($query) {
$query->where('courses.title', 'LIKE', '%' . request()->input('search') . '%');
$query->orWhere('courses.short_description', 'LIKE', '%' . request()->input('search') . '%');
$query->orWhere('courses.level', 'LIKE', '%' . request()->input('search') . '%');
$query->orWhere('courses.meta_keywords', 'LIKE', '%' . request()->input('search') . '%');
$query->orWhere('courses.meta_description', 'LIKE', '%' . request()->input('search') . '%');
$query->orWhere('courses.description', 'LIKE', '%' . request()->input('search') . '%');
});
}
// filter by price
if (request()->has('price')) {
$price = request()->query('price');
if ($price == 'paid') {
$query = $query->where('is_paid', 1);
} elseif ($price == 'discount') {
$query = $query->where('discount_flag', 1);
} elseif ($price == 'free') {
$query = $query->where('is_paid', 0);
}
}
// filter by level
if (request()->has('level')) {
$level = request()->query('level');
$query = $query->where('level', $level);
}
// filter by language
if (request()->has('language')) {
$language = request()->query('language');
$query = $query->where('language', $language);
}
// filter by rating
if (request()->has('rating')) {
$rating = request()->query('rating');
$query = $query->where('average_rating', $rating);
}
$wishlist = [];
if (isset(auth()->user()->id)) {
$wishlist = Wishlist::where('user_id', auth()->user()->id)->pluck('course_id')->toArray();
}
$page_data['courses'] = $query->latest('id')->paginate($layout == 'grid' ? 9 : 5)->appends($request->query());
$page_data['wishlist'] = $wishlist;
$page_data['category_details'] = Category::where('slug', $category)->first();
return view('frontend' . '.' . get_frontend_settings('theme') . '.course.index', $page_data);
}
public function course_details(Request $request, $slug)
{
// validate slug
if (empty($slug)) {
return redirect()->back();
}
// course details
$course = Course::where('slug', $slug)->where('status', 'active');
if ($course->exists()) {
$course_details = $course->first();
$page_data['course_details'] = $course_details;
$page_data['sections'] = Section::where('course_id', $course_details->id)->orderBy('sort')->get();
$page_data['total_lesson'] = Lesson::where('course_id', $course_details->id)->count();
$page_data['enroll'] = Enrollment::where('course_id', $course_details->id)->count('user_id');
$view_path = 'frontend.' . get_frontend_settings('theme') . '.course.course_details';
return view($view_path, $page_data);
} else {
return redirect()->back();
}
}
public function change_layout(Request $request)
{
$layout = Session::has('view');
if ($layout) {
Session::forget('view');
}
session(['view' => $request->view]);
return response()->json(['reload' => true]);
}
// ------------------------------------------------------------------------------------------------------
public function compare(Request $request)
{
$course_1 = $request->course_1;
$course_2 = $request->course_2;
$course_3 = $request->course_3;
if (isset($course_1) && $course_1 != '') {
$course_details_1 = Course::where('status', 'active')->where('slug', $course_1)->first();
$page_data['course_details_1'] = $course_details_1;
}
if (isset($course_2) && $course_2 != '') {
$course_details_2 = Course::where('status', 'active')->where('slug', $course_2)->first();
$page_data['course_details_2'] = $course_details_2;
}
if (isset($course_3) && $course_3 != '') {
$course_details_3 = Course::where('status', 'active')->where('slug', $course_3)->first();
$page_data['course_details_3'] = $course_details_3;
}
if ($course_1 == '' && $course_2 == '' && $course_3 == '') {
$page_data['course_details'] = '';
}
return view('frontend.course.compare', $page_data);
}
public function comparewith($course_1 = '', $course_2 = '', $course_3 = '')
{
$response = array();
$result = Course::join('users', 'courses.user_id', 'users.id')
->select('course.id as id', 'course.title as title', 'users.first_name as first_name', 'users.last_name as last_name')
->where('course.id', '!=', $course_1)
->where('course.id', '!=', $course_2)
->where('course.id', '!=', $course_3)
->where('course.status', 'active')
->like('course.title', $_GET['searchVal'])
->or_like('short_description', $_GET['searchVal'])
->or_like('first_name', $_GET['searchVal'])
->or_like('last_name', $_GET['searchVal'])
->take(100)
->get();
foreach ($result as $key => $row) {
$response[] = ['id' => $row->id, 'text' => $row->title . ' (' . get_phrase('Creator') . ': ' . $row->first_name];
}
echo json_encode($response);
}
}

View File

@ -0,0 +1,208 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Blog;
use App\Models\Builder_page;
use App\Models\Category;
use App\Models\Certificate;
use App\Models\Course;
use App\Models\Message;
use App\Models\Message_code;
use App\Models\Review;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
use DB;
use App\Http\Controllers\NewsletterController;
class HomeController extends Controller
{
function homepage_switcher($id){
session(['home' => $id]);
return redirect(route('home'));
}
public function index()
{
if(session('home')){
$page_builder = Builder_page::where('id', session('home'))->first();
}else{
$page_builder = Builder_page::where('status', 1)->first();
}
if ($page_builder && $page_builder->is_permanent == 1) {
$page_data['blogs'] = Blog::where('status', 1)->orderBy('is_popular', 'desc')->orderBy('id', 'desc')->take(3)->get();
$page_data['reviews'] = Review::all();
return view('components.home_permanent_templates.' . $page_builder->identifier, $page_data);
} else {
$page_data['instructor'] = User::join('courses', 'users.id', 'courses.user_id')
->select('users.*', 'courses.title as course_title')
->get()->unique()->take(4);
$page_data['blogs'] = Blog::where('status', 1)->orderBy('is_popular', 'desc')->orderBy('id', 'desc')->take(3)->get();
$page_data['category'] = Category::take(8)->get();
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.home.index';
return view($view_path, $page_data);
}
}
public function download_certificate($identifier)
{
$certificate = Certificate::where('identifier', $identifier);
if ($certificate->count() > 0) {
$qr_code_content_value = route('certificate', ['identifier' => $identifier]);
$qrcode = QrCode::size(300)->generate($qr_code_content_value);
$page_data['certificate'] = $certificate->first();
$page_data['qrcode'] = $qrcode;
return view('curriculum.certificate.download', $page_data);
} else {
return redirect(route('home'))->with('error', get_phrase('Certificate not found at this url'));
}
}
public function update_watch_history_with_duration(Request $request)
{
$userId = auth()->user()->id; // Get the logged-in user's ID
$courseProgress = 0;
$isCompleted = 0;
// Retrieve and sanitize input data
$courseId = htmlspecialchars($request->input('course_id'));
$lessonId = htmlspecialchars($request->input('lesson_id'));
$currentDuration = htmlspecialchars($request->input('current_duration'));
// Fetch current watch history record
$currentHistory = DB::table('watch_durations')
->where([
'watched_course_id' => $courseId,
'watched_lesson_id' => $lessonId,
'watched_student_id' => $userId,
])
->first();
// Fetch course details
$courseDetails = DB::table('courses')->where('id', $courseId)->first();
$dripContentSettings = json_decode($courseDetails->drip_content_settings, true);
if ($currentHistory) {
$watchedDurationArr = json_decode($currentHistory->watched_counter, true);
if (!is_array($watchedDurationArr)) $watchedDurationArr = [];
if (!in_array($currentDuration, $watchedDurationArr)) {
array_push($watchedDurationArr, $currentDuration);
}
$watchedDurationJson = json_encode($watchedDurationArr);
DB::table('watch_durations')
->where([
'watched_course_id' => $courseId,
'watched_lesson_id' => $lessonId,
'watched_student_id' => $userId,
])
->update([
'watched_counter' => $watchedDurationJson,
'current_duration' => $currentDuration,
]);
} else {
$watchedDurationArr = [$currentDuration];
DB::table('watch_durations')->insert([
'watched_course_id' => $courseId,
'watched_lesson_id' => $lessonId,
'watched_student_id' => $userId,
'current_duration' => $currentDuration,
'watched_counter' => json_encode($watchedDurationArr),
]);
}
if ($courseDetails->enable_drip_content != 1) {
return response()->json([
'lesson_id' => $lessonId,
'course_progress' => null,
'is_completed' => null
]);
}
// Fetch lesson details for duration calculations
$lessonTotalDuration = DB::table('lessons')->where('id', $lessonId)->value('duration');
$lessonTotalDurationArr = explode(':', $lessonTotalDuration);
$lessonTotalSeconds = ($lessonTotalDurationArr[0] * 3600) + ($lessonTotalDurationArr[1] * 60) + $lessonTotalDurationArr[2];
$currentTotalSeconds = count($watchedDurationArr) * 5; // Assuming each increment represents 5 seconds
// Drip content completion logic
if ($dripContentSettings['lesson_completion_role'] == 'duration') {
if ($currentTotalSeconds >= $dripContentSettings['minimum_duration']) {
$isCompleted = 1;
} elseif (($currentTotalSeconds + 4) >= $lessonTotalSeconds) {
$isCompleted = 1;
}
} else {
$requiredDuration = ($lessonTotalSeconds / 100) * $dripContentSettings['minimum_percentage'];
if ($currentTotalSeconds >= $requiredDuration) {
$isCompleted = 1;
} elseif (($currentTotalSeconds + 4) >= $lessonTotalSeconds) {
$isCompleted = 1;
}
}
// Update course progress if the lesson is completed
if ($isCompleted == 1) {
$watchHistory = DB::table('watch_histories')
->where([
'course_id' => $courseId,
'student_id' => $userId,
])
->first();
if ($watchHistory) {
$lessonIds = json_decode($watchHistory->completed_lesson, true);
$courseProgress = $watchHistory->course_progress;
if (!is_array($lessonIds)) $lessonIds = [];
if (!in_array($lessonId, $lessonIds)) {
array_push($lessonIds, $lessonId);
$totalLesson = DB::table('lessons')->where('course_id', $courseId)->count();
$courseProgress = (100 / $totalLesson) * count($lessonIds);
$completedDate = ($courseProgress >= 100 && !$watchHistory->completed_date)
? time()
: $watchHistory->completed_date;
DB::table('watch_histories')
->where('id', $watchHistory->id)
->update([
'course_progress' => $courseProgress,
'completed_lesson' => json_encode($lessonIds),
'completed_date' => $completedDate,
]);
}
}
}
// Return the response
return response()->json([
'lesson_id' => $lessonId,
'course_progress' => round($courseProgress),
'is_completed' => $isCompleted,
]);
}
public function sendEmailToAssignedAddresses()
{
// Accessing the method from NewsletterController
$newsletterController = new NewsletterController();
$response = $newsletterController->sendEmailToAssignedAddresses();
if ($response) {
return response($response);
}
return response('No response', 404); // Default response if no data
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Course;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class InstructorController extends Controller
{
public function index()
{
$page_data['instructors'] = User::where('role', 'instructor')->latest('id')->paginate(8);
$view_path = 'frontend.' . get_frontend_settings('theme') . '.instructor.index';
return view($view_path, $page_data);
}
public function show($name, $id)
{
$instructor = User::where('id', $id)->first();
// if instructor doesn't exists go back
if (!$instructor && $instructor->name != $name) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$instructor_courses = Course::join('users', 'courses.user_id', '=', 'users.id')
->select('courses.*', 'users.name as instructor_name', 'users.email as instructor_email', 'users.photo as instructor_image')
->where('courses.status', 'active')
->where('courses.user_id', $instructor->id)
->latest('id')->paginate(6);
$page_data['instructor_details'] = $instructor;
$page_data['instructor_courses'] = $instructor_courses;
$view_path = 'frontend.' . get_frontend_settings('theme') . '.instructor.details';
return view($view_path, $page_data);
}
}

View File

@ -0,0 +1,85 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Models\Knowledge_base_topick;
use App\Models\Knowledge_base;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class KnowledgeBaseTopicController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$articles = Knowledge_base::orderBy('updated_at', 'desc')->paginate(10);
return view('frontend.default.knowledge_base_topics.index', ['articles'=> $articles]);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
$query = Knowledge_base_topick::where('id', $id)->first();
if($query){
$title =Knowledge_base::where('id',$query->knowledge_base_id)->first();
}
if (!$query) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->route('knowledge.base.topicks');
}
return view('frontend.default.knowledge_base_topics.article_single', ['title'=> $title,'article'=> $query]);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class LanguageController extends Controller
{
public function select_lng(Request $request)
{
session(['language' => strtolower($request->language)]);
return redirect()->back();
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Course;
use App\Models\Enrollment;
use App\Models\MessageThread;
use App\Models\Payment_history;
use App\Models\User;
use App\Models\Wishlist;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class MycourseController extends Controller
{
public function mycourses(Request $request)
{
$page_data['courses'] = Enrollment::where('user_id', auth()->user()->id)->get();
// searched courses
if (isset($_GET['search']) && $_GET['search'] != '') {
$query = Enrollment::join('courses', 'enrollments.course_id', 'courses.id')
->where('enrollments.user_id', auth()->user()->id)
->where('courses.title', 'LIKE', '%' . $_GET['search'] . '%')
->get();
$page_data['courses'] = $query;
}
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.my_courses.my_courses';
return view($view_path, $page_data);
}
public function profile()
{
return view('frontend.my-courses.profile');
}
public function profile_edit(Request $request)
{
$data['name'] = $request->name;
$data['email'] = $request->email;
$data['about'] = $request->about;
$data['phone'] = $request->phone;
$data['website'] = $request->website;
User::where('id', $request->user_id)->update($data);
Session::flash('success', get_phrase('Update successfully'));
return redirect()->back();
}
public function wishlist()
{
$quary = Wishlist::join('courses', 'wishlists.course_id', 'courses.id')
->where('wishlists.user_id', auth()->user()->id)
->get();
$page_data['courses'] = $quary;
return view('frontend.my-courses.wishlist', $page_data);
}
public function message()
{
$page_data['message_threads'] = MessageThread::get();
return view('frontend.my-courses.message', $page_data);
}
public function purchase_history()
{
$payment_history = Payment_history::where('user_id', auth()->user()->id)->get();
$page_data['courses'] = $payment_history;
return view('frontend.my-courses.purchase-history', $page_data);
}
public function invoice($id)
{
$invoice = Payment_history::where('id', $id)->first();
$user = User::where('id', $invoice->user_id)->first();
$course = Course::where('id', $invoice->course_id)->first();
$page_data['invoices'] = $invoice;
$page_data['courses'] = $course;
$page_data['users'] = $user;
return view('frontend.my-courses.invoice', $page_data);
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\NewsletterSubscriber;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class NewsletterController extends Controller
{
public function store(Request $request)
{
$input = $request->all();
if (get_frontend_settings('recaptcha_status') == true && check_recaptcha($input['g-recaptcha-response']) == false) {
Session::flash('error', get_phrase('Recaptcha verification failed'));
return redirect()->back();
}
// validate email
$validated = $request->validate([
'email' => 'required|email|unique:newsletter_subscribers',
]);
// check user exists or not
if (NewsletterSubscriber::where('email', $request->email)->exists()) {
Session::flash('error', get_phrase('You have already subscribed.'));
return redirect()->back();
}
// store data
$data['email'] = $request->email;
NewsletterSubscriber::insert($data);
// redirect back
Session::flash('success', get_phrase('You have successfully subscribed.'));
return redirect()->back();
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Course;
use App\Models\Instructor_review;
use App\Models\Review;
use App\Models\User;
use Illuminate\Http\Request;
class ReviewController extends Controller
{
public function instructor_review_store(Request $request)
{
$data['instructor_id'] = $request->instructor_id;
$data['user_id'] = Auth()->user()->id;
$data['review'] = $request->comment;
$data['rating'] = $request->rating;
Instructor_review::insert($data);
return redirect()->back();
}
public function instructor_details($id)
{
$page_data['instructor'] = User::where('id', $id)->first();
return view('frontend.instructor.instructor_details', $page_data);
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Contact;
use App\Models\Newsletter_subscriber;
use Illuminate\Http\Request;
class SubscribedController extends Controller
{
public function contact_us()
{
return view('frontend.contact');
}
public function contact_us_store(Request $request)
{
if ($request->check == '1') {
$data['first_name'] = $request->first_name;
$data['last_name'] = $request->last_name;
$data['email'] = $request->email;
$data['phone'] = $request->phone;
$data['address'] = $request->address;
$data['message'] = $request->comment;
Contact::insert($data);
}
return redirect()->back();
}
public function about_us()
{
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.home.index';
return view($view_path);
}
public function privacy_policy()
{
return view('frontend.privacy_policy.index');
}
public function refund_policy()
{
return view('frontend.refund_policy.index');
}
public function terms_and_condition()
{
return view('frontend.terms_and_condition.index');
}
public function faq()
{
return view('frontend.faq.index');
}
}

View File

@ -0,0 +1,69 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Course;
use App\Models\TeamTrainingPackage;
use Illuminate\Http\Request;
class TeamTrainingController extends Controller
{
public function index($course_category = '')
{
$query = TeamTrainingPackage::join('courses', 'team_training_packages.course_id', 'courses.id')
->join('users', 'team_training_packages.user_id', 'users.id')
->where('team_training_packages.status', 1)
->select(
'team_training_packages.*',
'courses.title as course_title',
'courses.slug as course_slug',
'courses.price as course_price',
'users.name as creator_name',
'users.email as creator_email',
'users.photo as creator_photo',
);
if (request()->has('search')) {
$query = $query->where('team_training_packages.title', 'LIKE', "%" . request()->query('search') . "%");
}
if ($course_category) {
$category_details = Category::where('slug', $course_category)->first();
if ($category_details->parent_id == 0) {
$sub_cat_id = Category::where('parent_id', $category_details->id)->pluck('id');
$courses = Course::whereIn('category_id', $sub_cat_id)->pluck('id')->toArray();
} else {
$courses = Course::where('category_id', $category_details->id)->pluck('id')->toArray();
}
$query = $query->where('course_id', $courses);
}
$page_data['packages'] = $query->latest('id')->paginate(5)->appends(request()->query());
return view('frontend.default.team_training.index', $page_data);
}
public function show($slug)
{
$page_data['package'] = TeamTrainingPackage::join('courses', 'team_training_packages.course_id', 'courses.id')
->join('users', 'team_training_packages.user_id', 'users.id')
->select(
'team_training_packages.*',
'courses.title as course_title',
'courses.slug as course_slug',
'courses.price as course_price',
'users.name as creator_name',
'users.email as creator_email',
'users.photo as creator_photo',
)
->where('team_training_packages.slug', $slug)
->first();
if (! $page_data['package']) {
return redirect()->back()->with('error', get_phrase('Data not found.'));
}
return view('frontend.default.team_training.details', $page_data);
}
}

View File

@ -0,0 +1,310 @@
<?php
namespace App\Http\Controllers\frontend;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\TutorSchedule;
use App\Models\TutorCategory;
use App\Models\TutorSubject;
use App\Models\TutorReview;
use App\Models\TutorCanTeach;
use Illuminate\Http\Request;
class TutorBookingController extends Controller
{
public function index(Request $request)
{
// Retrieve distinct tutor_ids from TutorSchedule
$tutorIds = TutorSchedule::select('tutor_id')->distinct()->pluck('tutor_id');
// Convert to an array if needed
$tutorIdsArray = $tutorIds->toArray();
// Initialize the query to get users based on tutor_ids
$query = User::whereIn('id', $tutorIdsArray);
if ($request->has('search')) {
$query->where('name', 'LIKE', '%' . request()->input('search') . '%');
}
// Check if a category & subject are present in the request
if ($request->has('category') && $request->has('subject')) {
$categorySlug = $request->input('category');
$subjectSlug = $request->input('subject');
// Get category_id based on category
$categoryId = TutorCategory::where('slug', $categorySlug)->value('id');
// Get subject_id based on subject
$subjectId = TutorSubject::where('slug', $subjectSlug)->value('id');
// Filter TutorSchedule by both category_id and subject_id
$tutorIdsByCategoryAndSubject = TutorSchedule::where('category_id', $categoryId)
->where('subject_id', $subjectId)
->pluck('tutor_id');
// Intersect the filtered tutor IDs with the existing filtered IDs
$filteredTutorIds = array_intersect($tutorIdsArray, $tutorIdsByCategoryAndSubject->toArray());
} else {
$filteredTutorIds = $tutorIdsArray; // Initialize filteredTutorIds with all tutor IDs
// Check if a category is present in the request
if ($request->has('category')) {
$categorySlug = $request->input('category');
// Get category_id based on category
$categoryId = TutorCategory::where('slug', $categorySlug)->value('id');
// Filter TutorSchedule by category_id
$tutorIdsByCategory = TutorSchedule::where('category_id', $categoryId)
->pluck('tutor_id');
// Intersect the filtered tutor IDs with the existing filtered IDs
$filteredTutorIds = array_intersect($filteredTutorIds, $tutorIdsByCategory->toArray());
}
// Check if a subject is present in the request
if ($request->has('subject')) {
$subjectSlug = $request->input('subject');
// Get subject_id based on subject
$subjectId = TutorSubject::where('slug', $subjectSlug)->value('id');
// Filter TutorSchedule by subject_id
$tutorIdsBySubject = TutorSchedule::where('subject_id', $subjectId)
->pluck('tutor_id');
// Intersect the filtered tutor IDs with the existing filtered IDs
$filteredTutorIds = array_intersect($filteredTutorIds, $tutorIdsBySubject->toArray());
}
}
if ($request->has('min_fee') && $request->has('max_fee')) {
$minFee = $request->input('min_fee');
$maxFee = $request->input('max_fee');
$tutorIdsByPrice = TutorCanTeach::where('price', '>=', $minFee)
->where('price', '<=', $maxFee)
->pluck('instructor_id');
// If no tutor IDs found by rating, clear the existing tutor IDs array
if ($tutorIdsByPrice->isEmpty()) {
$filteredTutorIds = []; // Clear the array to ensure no tutors are returned
} else {
// Merge the filtered tutor IDs with the original tutor IDs
$filteredTutorIds = array_intersect($filteredTutorIds, $tutorIdsByPrice->toArray());
}
}
// Check if a rating is present in the request
if ($request->has('rating')) {
$rating = $request->input('rating');
// Get tutor_ids with average ratings matching the requested rating
$tutorIdsByRating = TutorReview::select('tutor_id')
->groupBy('tutor_id')
->havingRaw('AVG(rating) = ?', [$rating])
->pluck('tutor_id');
// If no tutor IDs found by rating, clear the existing tutor IDs array
if ($tutorIdsByRating->isEmpty()) {
$filteredTutorIds = []; // Clear the array to ensure no tutors are returned
} else {
// Merge the filtered tutor IDs with the original tutor IDs
$filteredTutorIds = array_intersect($filteredTutorIds, $tutorIdsByRating->toArray());
}
}
// Retrieve the filtered users
$page_data['tutors'] = $query->whereIn('id', $filteredTutorIds)->paginate(10)->appends(request()->query());
$page_data['categories'] = TutorCategory::where('status', 1)->get();
$page_data['subjects'] = TutorSubject::where('status', 1)->get();
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.tutor_booking.index';
return view($view_path, $page_data);
}
public function index2(Request $request)
{
$query = TutorSchedule::query();
// Filter by category if specified
if (request()->has('category')) {
$category_details = TutorCategory::where('slug', $request->category)->first();
if ($category_details) {
$query = $query->where('category_id', $category_details->id);
}
}
// filter by subject
if (request()->has('subject')) {
$subject = request()->query('subject');
$subject_details = TutorSubject::where('slug', $subject)->first();
if ($subject_details) {
$query = $query->where('subject_id', $subject_details->id);
}
}
// filter by rating
if (request()->has('rating')) {
$rating = request()->query('rating');
// Calculate average ratings for tutors and get IDs of those with matching average
$tutor_ids = TutorReview::select('tutor_id')
->groupBy('tutor_id')
->havingRaw('AVG(rating) = ?', [$rating])
->pluck('tutor_id');
// if ($tutor_ids->isNotEmpty()) {
// $query = $query->whereIn('tutor_id', $tutor_ids);
// }
$query = $query->whereIn('tutor_id', $tutor_ids);
}
// Get unique tutor IDs first, then paginate
$uniqueTutorSchedules = $query->select('tutor_id')
->distinct()
->paginate(20)
->appends(request()->query());
// Load the categories and subjects
$page_data['tutors'] = $uniqueTutorSchedules;
$page_data['categories'] = TutorCategory::where('status', 1)->get();
$page_data['subjects'] = TutorSubject::where('status', 1)->get();
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.tutor_booking.index';
return view($view_path, $page_data);
}
public function tutor_schedule2(Request $request, $user)
{
$page_data['tutor_details'] = User::find($request->tutor_id);
// Get the current timestamp for today at midnight
$todayStart = strtotime('today'); // This gives you the timestamp for today at 00:00:00
// Retrieve tutors with schedules starting from today onwards
$page_data['schedules'] = TutorSchedule::where('start_time', '>=', $todayStart)->get();
$page_data['reviews'] = TutorReview::where('tutor_id', $request->tutor_id)->get();
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.tutor_booking.tutor_schedule';
return view($view_path, $page_data);
}
public function tutor_schedule(Request $request, $id, $user)
{
// Find the tutor details based on the given ID
$page_data['tutor_details'] = User::find($id);
// Get the current timestamp for today at midnight
$todayStart = strtotime('today');
$todayEnd = strtotime('tomorrow') - 1;
// Retrieve tutors with schedules starting and ending within today
$page_data['schedules'] = TutorSchedule::where('tutor_id', $id)
->where('start_time', '>=', $todayStart)
->where('end_time', '<=', $todayEnd)
->get();
// Generate date data for the Swiper calendar
$page_data['dateSwiperData'] = [];
$today = new \DateTime();
$twoYearsFromNow = (clone $today)->modify('+2 years');
while ($today <= $twoYearsFromNow) {
$day = $today->format('d');
$month = $today->format('M');
$year = $today->format('Y');
$dayName = $today->format('D');
// Check if the date is today
$isToday = $today->format('Y-m-d') === (new \DateTime())->format('Y-m-d');
$page_data['dateSwiperData'][] = [
'day' => $day,
'month' => $month,
'year' => $year,
'dayName' => $dayName,
'isToday' => $isToday
];
// Move to the next day
$today->modify('+1 day');
}
// Get reviews for the specified tutor
$page_data['reviews'] = TutorReview::where('tutor_id', $id)->get();
// Define the view path based on frontend settings
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.tutor_booking.tutor_schedule';
// Return the view with the prepared data
return view($view_path, $page_data);
}
public function getSchedulesForDate($date, $tutor_id)
{
// Convert the date to a timestamp for the beginning and end of the day
$startOfDay = strtotime($date);
$endOfDay = strtotime('+1 day', $startOfDay) - 1;
// Retrieve schedules that fall within the specified date
$schedules = TutorSchedule::where('tutor_id', $tutor_id)
->where('start_time', '>=', $startOfDay)
->where('end_time', '<=', $endOfDay)
->get();
// Return the partial view with schedules
return view('frontend.default.tutor_booking.schedules', compact('schedules'));
}
public function getSchedulesByCalenderDate($date, $tutor_id)
{
// Convert the date to a timestamp for the beginning and end of the day
$startOfDay = strtotime($date);
$endOfDay = strtotime('+1 day', $startOfDay) - 1;
// Retrieve schedules that fall within the specified date
$page_data['schedules'] = TutorSchedule::where('tutor_id', $tutor_id)
->where('start_time', '>=', $startOfDay)
->where('end_time', '<=', $endOfDay)
->get();
// Generate date data for the Swiper calendar
$page_data['dateSwiperData'] = [];
$slectedDay = new \DateTime($date); // Start from the selected date
$twoYearsFromNow = (clone $slectedDay)->modify('+2 years');
while ($slectedDay <= $twoYearsFromNow) {
$day = $slectedDay->format('d');
$month = $slectedDay->format('M');
$year = $slectedDay->format('Y');
$dayName = $slectedDay->format('D');
// Check if the date is the selected day
$isToday = $slectedDay->format('Y-m-d') === (new \DateTime($date))->format('Y-m-d');
$page_data['dateSwiperData'][] = [
'day' => $day,
'month' => $month,
'year' => $year,
'dayName' => $dayName,
'isToday' => $isToday
];
// Move to the next day
$slectedDay->modify('+1 day');
}
// Return the partial view with schedules
return view('frontend.default.tutor_booking.schedules_tab', $page_data);
}
}

View File

@ -0,0 +1,158 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Blog;
use App\Models\BlogCategory;
use App\Models\FileUploader;
use App\Models\SeoField;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class BlogController extends Controller
{
public function index()
{
$query = Blog::where('user_id', auth()->user()->id);
// if route has any query
if (request()->has('search')) {
$query = $query->where('title', 'LIKE', '%' . request()->query('search') . '%');
}
$page_data["blogs"] = $query->paginate(10)->appends(request()->query());
return view("instructor.blog.index", $page_data);
}
public function create()
{
$page_data["category"] = BlogCategory::all();
return view("instructor.blog.create", $page_data);
}
public function store(Request $request)
{
$data['category_id'] = $request->category_id;
$data['user_id'] = Auth()->user()->id;
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['keywords'] = $request->keywords;
$data['description'] = $request->description;
if (isset($request->thumbnail) && $request->thumbnail != '') {
$data['thumbnail'] = "uploads/blog/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
}
if (isset($request->banner) && $request->banner != '') {
$data['banner'] = "uploads/blog/banner/" . nice_file_name($request->title, $request->banner->extension());
FileUploader::upload($request->banner, $data['banner'], 400, null, 200, 200);
}
$data['is_popular'] = $request->is_popular;
$data['status'] = 0;
Blog::insert($data);
Session::flash('success', get_phrase('Blog added successfully'));
return redirect()->route('instructor.blogs');
}
public function edit($id)
{
$page_data["blog_data"] = Blog::where('id', $id)->where('user_id', auth()->user()->id)->first();
$page_data["category"] = BlogCategory::all();
return view("instructor.blog.edit", $page_data);
}
public function update(Request $request, $id)
{
$data['category_id'] = $request->category_id;
$data['user_id'] = Auth()->user()->id;
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['keywords'] = $request->keywords;
$data['description'] = $request->description;
if (isset($request->thumbnail) && $request->thumbnail != '') {
$data['thumbnail'] = "uploads/blog/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
}
if (isset($request->banner) && $request->banner != '') {
$data['banner'] = "uploads/blog/banner/" . nice_file_name($request->title, $request->banner->extension());
FileUploader::upload($request->banner, $data['banner'], 400, null, 200, 200);
}
$data['is_popular'] = $request->is_popular;
Blog::where('id', $id)->update($data);
// Blog SEO
$blog_details = Blog::where('id', $id)->first();
$SeoField = SeoField::where('name_route', 'blog.details')->where('blog_id', $blog_details->id)->first();
$seo_data['blog_id'] = $id;
$seo_data['route'] = 'Blog Details';
$seo_data['name_route'] = 'blog.details';
$seo_data['meta_title'] = $request->meta_title;
$seo_data['meta_description'] = $request->meta_description;
$seo_data['meta_robot'] = $request->meta_robot;
$seo_data['canonical_url'] = $request->canonical_url;
$seo_data['custom_url'] = $request->custom_url;
$seo_data['json_ld'] = $request->json_ld;
$seo_data['og_title'] = $request->og_title;
$seo_data['og_description'] = $request->og_description;
$seo_data['created_at'] = date('Y-m-d H:i:s');
$seo_data['updated_at'] = date('Y-m-d H:i:s');
$meta_keywords_arr = json_decode($request->meta_keywords, true);
$meta_keywords = '';
if (is_array($meta_keywords_arr)) {
foreach ($meta_keywords_arr as $arr_key => $arr_val) {
$meta_keywords .= $meta_keywords == '' ? $arr_val['value'] : ', ' . $arr_val['value'];
}
$seo_data['meta_keywords'] = $meta_keywords;
}
if ($request->og_image) {
$originalFileName = $blog_details->id . '-' . $request->og_image->getClientOriginalName();
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
// Move the file to the destination path
FileUploader::upload($request->og_image, $destinationPath, 600);
$seo_data['og_image'] = $destinationPath;
}
if ($SeoField) {
if ($request->og_image) {
remove_file($SeoField->og_image);
}
SeoField::where('name_route', 'blog.details')->where('blog_id', $blog_details->id)->update($seo_data);
} else {
SeoField::insert($seo_data);
}
// Blog SEO Ended
Session::flash('success', get_phrase('Blog updated successfully'));
return redirect()->route('instructor.blogs');
}
public function delete($id)
{
$query = Blog::where("id", $id);
remove_file($query->first()->thumbnail);
remove_file($query->first()->banner);
$query->delete();
Session::flash('success', get_phrase('Blog deleted successfully'));
return redirect()->back();
}
public function pending()
{
$query = Blog::where('user_id', auth()->user()->id)->where('status', 0);
// if route has any query
if (request()->has('search')) {
$query = $query->where('title', 'LIKE', '%' . request()->query('search') . '%');
}
$page_data["blogs"] = $query->paginate(10)->appends(request()->query());
return view("instructor.blog.pending", $page_data);
}
}

View File

@ -0,0 +1,350 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Bootcamp;
use App\Models\BootcampCategory;
use App\Models\BootcampModule;
use App\Models\BootcampPurchase;
use App\Models\FileUploader;
use App\Models\SeoField;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class BootcampController extends Controller
{
public function __construct()
{
}
public function index()
{
$query = Bootcamp::join('bootcamp_categories', 'bootcamps.category_id', 'bootcamp_categories.id')
->select('bootcamps.*', 'bootcamp_categories.title as category', 'bootcamp_categories.slug as category_slug')
->where('bootcamps.user_id', auth()->user()->id);
if (request()->has('search')) {
$query = $query->where('bootcamps.title', 'LIKE', "%" . request()->query('search') . "%");
}
if (request()->has('category') && request()->query('category') != 'all') {
$category = BootcampCategory::where('slug', request()->query('category'))->first();
$query = $query->where('bootcamps.category_id', $category->id);
}
if (request()->has('status') && request()->query('status') != 'all') {
$status = request()->query('status') == 'active' ? 1 : 0;
$query = $query->where('bootcamps.status', $status);
}
if (request()->has('instructor') && request()->query('instructor') != 'all') {
$query = $query->where('bootcamps.user_id', request()->query('instructor'));
}
if (request()->has('price') && request()->query('price') != 'all') {
$price = request()->query('price');
$value = 1;
if ($price == 'free') {
$column = 'is_paid';
$value = 0;
} elseif ($price == 'discounted') {
$column = 'discount_flag';
} elseif ($price == 'paid') {
$column = 'is_paid';
}
$query = $query->where('bootcamps.' . $column, $value);
}
$page_data['bootcamps'] = $query->paginate(20)->appends(request()->query());
return view('instructor.bootcamp.index', $page_data);
}
public function create()
{
return view('instructor.bootcamp.create');
}
public function edit($id)
{
$bootcamp = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id)->first();
if (! $bootcamp) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->route('instructor.bootcamps');
}
$page_data['bootcamp_details'] = $bootcamp;
$page_data['modules'] = BootcampModule::where('bootcamp_id', $id)->get();
return view('instructor.bootcamp.edit', $page_data);
}
public function store(Request $request)
{
$rules = [
'title' => 'required|string',
'description' => 'required|string',
'category_id' => 'required',
'is_paid' => Rule::in(['0', '1']),
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
'discount_flag' => Rule::in(['', '1']),
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$title = Bootcamp::where('user_id', auth()->user()->id)->where('title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
$data['user_id'] = auth()->user()->id;
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['short_description'] = $request->short_description;
$data['description'] = $request->description;
$data['publish_date'] = strtotime($request->publish_date);
$data['category_id'] = $request->category_id;
$data['is_paid'] = $request->is_paid;
$data['price'] = $request->price;
$data['discount_flag'] = $request->discount_flag;
$data['discounted_price'] = $request->discounted_price;
$data['status'] = 1;
if ($request->thumbnail) {
$data['thumbnail'] = "uploads/bootcamp/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail']);
}
$insert_id = Bootcamp::insertGetId($data);
Session::flash('success', get_phrase('Bootcamp has been created.'));
return redirect()->route('instructor.bootcamp.edit', [$insert_id, 'tab' => 'curriculum']);
}
public function delete($id)
{
$bootcamp = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id);
if ($bootcamp->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$bootcamp->delete();
Session::flash('success', get_phrase('Bootcamp has been deleted.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$query = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id);
if ($query->doesntExist() || $request->tab == '') {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$rules = $data = [];
if ($request->tab == 'basic') {
$rules = [
'title' => 'required|string',
'description' => 'required|string',
'category_id' => 'required',
];
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['short_description'] = $request->short_description;
$data['description'] = $request->description;
$data['publish_date'] = strtotime($request->publish_date);
$data['category_id'] = $request->category_id;
$title = Bootcamp::where('user_id', auth()->user()->id)
->where('id', '!=', $id)
->where('title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
} elseif ($request->tab == 'pricing') {
$rules = [
'is_paid' => Rule::in(['0', '1']),
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
'discount_flag' => Rule::in(['', '1']),
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
];
$data['is_paid'] = $request->is_paid;
$data['price'] = $request->price;
$data['discount_flag'] = $request->discount_flag;
$data['discounted_price'] = $request->discounted_price;
} elseif ($request->tab == 'info') {
$rules = [
'requirements' => 'array',
'outcomes' => 'array',
'faqs' => 'array',
];
//Remove empty value by using array filter function
$data['requirements'] = json_encode(array_filter($request->requirements, fn($value) => ! is_null($value) && $value !== ''));
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn($value) => ! is_null($value) && $value !== ''));
$faqs = [];
foreach ($request->faq_title as $key => $title) {
if ($title != '') {
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
}
}
$data['faqs'] = json_encode($faqs);
} elseif ($request->tab == 'media') {
if ($request->thumbnail) {
$data['thumbnail'] = "uploads/bootcamp/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail']);
remove_file($query->first()->thumbnail);
}
} elseif ($request->tab == 'seo') {
$bootcamp_details = $query->first();
$SeoField = SeoField::where('name_route', 'bootcamp.details')->where('bootcamp_id', $bootcamp_details->id)->first();
$seo_data['bootcamp_id'] = $id;
$seo_data['route'] = 'Bootcamp Details';
$seo_data['name_route'] = 'bootcamp.details';
$seo_data['meta_title'] = $request->meta_title;
$seo_data['meta_description'] = $request->meta_description;
$seo_data['meta_robot'] = $request->meta_robot;
$seo_data['canonical_url'] = $request->canonical_url;
$seo_data['custom_url'] = $request->custom_url;
$seo_data['json_ld'] = $request->json_ld;
$seo_data['og_title'] = $request->og_title;
$seo_data['og_description'] = $request->og_description;
$seo_data['created_at'] = date('Y-m-d H:i:s');
$seo_data['updated_at'] = date('Y-m-d H:i:s');
$meta_keywords_arr = json_decode($request->meta_keywords, true);
$meta_keywords = '';
if (is_array($meta_keywords_arr)) {
foreach ($meta_keywords_arr as $arr_key => $arr_val) {
$meta_keywords .= $meta_keywords == '' ? $arr_val['value'] : ', ' . $arr_val['value'];
}
$seo_data['meta_keywords'] = $meta_keywords;
}
if ($request->og_image) {
$originalFileName = $bootcamp_details->id . '-' . $request->og_image->getClientOriginalName();
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
// Move the file to the destination path
FileUploader::upload($request->og_image, $destinationPath, 600);
$seo_data['og_image'] = $destinationPath;
}
if ($SeoField) {
if ($request->og_image) {
remove_file($SeoField->og_image);
}
SeoField::where('name_route', 'bootcamp.details')->where('bootcamp_id', $bootcamp_details->id)->update($seo_data);
} else {
SeoField::insert($seo_data);
}
}
//For ajax form submission
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$query->update($data);
//For ajax form submission
// return ['success' => get_phrase('Course updated successfully')];
//for normal form submission
Session::flash('success', get_phrase('Bootcamp has been updated successfully.'));
return redirect()->back();
}
public function duplicate($id)
{
$bootcamp = Bootcamp::where('id', $id);
if ($bootcamp->doesntExist()) {
Session::flash('success', get_phrase('Data not found.'));
return redirect()->back();
}
$bootcamp = $bootcamp->first()->toArray();
$bootcamp['title'] = $bootcamp['title'] . ' copy';
$bootcamp['slug'] = slugify($bootcamp['title']);
$bootcamp['user_id'] = auth()->user()->id;
$bootcamp['status'] = 1;
unset($bootcamp['id'], $bootcamp['created_at'], $bootcamp['updated_at']);
$insert_id = Bootcamp::insertGetId($bootcamp);
Session::flash('success', get_phrase('Bootcamp has been duplicated.'));
return redirect()->route('instructor.bootcamp.edit', [$insert_id, 'tab' => 'basic']);
}
public function status($id)
{
$bootcamp = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id);
if ($bootcamp->doesntExist()) {
$response = [
'error' => get_phrase('Data not found.'),
];
return json_encode($response);
}
$status = $bootcamp->first()->status ? 0 : 1;
Bootcamp::where('id', $id)->update(['status' => $status]);
$response = [
'success' => get_phrase('Status has been updated.'),
];
return json_encode($response);
}
public function purchase_history()
{
$page_data['purchases'] = BootcampPurchase::join('bootcamps', 'bootcamp_purchases.bootcamp_id', 'bootcamps.id')
->where('bootcamps.user_id', auth()->user()->id)
->select(
'bootcamp_purchases.*',
'bootcamps.user_id as author',
'bootcamps.title',
'bootcamps.slug',
'bootcamps.price as amount',
)
->latest('bootcamp_purchases.id')->paginate(20)->appends(request()->query());
return view('instructor.bootcamp.purchase_history', $page_data);
}
public function invoice($id)
{
$invoice = BootcampPurchase::join('bootcamps', 'bootcamp_purchases.bootcamp_id', 'bootcamps.id')
->where('bootcamps.user_id', auth()->user()->id)
->where('bootcamp_purchases.id', $id)
->select(
'bootcamp_purchases.*',
'bootcamps.title',
'bootcamps.slug',
)->first();
if (! $invoice) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$page_data['invoice'] = $invoice;
return view('instructor.bootcamp.invoice', $page_data);
}
}

View File

@ -0,0 +1,263 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Http\Controllers\ZoomMeetingController;
use App\Models\BootcampLiveClass;
use App\Models\BootcampModule;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class BootcampLiveClassController extends Controller
{
public function __construct()
{
date_default_timezone_set('Asia/Dhaka');
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|string',
'date' => 'required|date',
'start_time' => 'required|string',
'end_time' => 'required|string|after:start_time',
'module_id' => 'required',
'description' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
// check selected module
$module = BootcampModule::where('id', $request->module_id)->first();
if (! $module) {
Session::flash('error', get_phrase('Module does not exist.'));
return redirect()->back();
}
// process class schedule
$start = $request->date . ' ' . $request->start_time;
$start_timestamp = strtotime($start);
$end = $request->date . ' ' . $request->end_time;
$end_timestamp = strtotime($end);
// check module and class schedule
if ($module->restriction) {
if ($module->restriction == 1 && $start_timestamp < $module->publish_date) {
Session::flash('error', get_phrase('Please set class schedule properly.'));
return redirect()->back();
}
if ($module->restriction == 2 && (($start_timestamp < $module->publish_date || $start_timestamp > $module->expiry_date) && ($end_timestamp < $module->publish_date || $end_timestamp > $module->expiry_date))) {
Session::flash('error', get_phrase('Please set class schedule properly.'));
return redirect()->back();
}
}
// check duplicate title for same bootcamp id
$title = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamps.user_id', auth()->user()->id)
->where('bootcamp_modules.id', $request->module_id)
->where('bootcamp_live_classes.title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['description'] = $request->description;
$data['status'] = $request->status;
$data['module_id'] = $request->module_id;
$data['start_time'] = $start_timestamp;
$data['end_time'] = $end_timestamp;
// Calculate the difference in seconds
$difference_in_seconds = $data['end_time'] - $data['start_time'];
// Convert the difference to minutes
$difference_in_minutes = $difference_in_seconds / 60;
$joiningData = ZoomMeetingController::createMeeting($request->title, $start_timestamp, $difference_in_minutes);
$joiningInfoArr = json_decode($joiningData, true);
if (array_key_exists('code', $joiningInfoArr) && $joiningInfoArr) {
return redirect(route('instructor.bootcamp.edit', ['id' => $module->bootcamp_id, 'tab' => 'curriculum']))->with('error', get_phrase($joiningInfoArr['message']));
}
$data['provider'] = 'zoom';
$data['joining_data'] = $joiningData;
BootcampLiveClass::insert($data);
Session::flash('success', get_phrase('Live class has been created.'));
return redirect()->route('instructor.bootcamp.edit', ['id' => $module->bootcamp_id, 'tab' => 'curriculum']);
}
public function update(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'title' => 'required|string',
'start_time' => 'required',
'end_time' => 'required',
'module_id' => 'required',
'description' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_live_classes.id', $id)
->where('bootcamp_live_classes.module_id', $request->module_id)
->where('bootcamps.user_id', auth()->user()->id)
->select('bootcamp_live_classes.*', 'bootcamp_modules.restriction', 'bootcamp_modules.publish_date', 'bootcamp_modules.expiry_date')
->first();
if (! $class) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
// process class schedule
$start = $request->date . ' ' . $request->start_time;
$start_timestamp = strtotime($start);
$end = $request->date . ' ' . $request->end_time;
$end_timestamp = strtotime($end);
// check module and class schedule
if ($class->restriction) {
if ($class->restriction == 1 && $start_timestamp < $class->publish_date) {
Session::flash('error', get_phrase('Please set class schedule properly.'));
return redirect()->back();
}
if ($class->restriction == 2 && (($start_timestamp < $class->publish_date || $start_timestamp > $class->expiry_date) && ($end_timestamp < $class->publish_date || $end_timestamp > $class->expiry_date))) {
Session::flash('error', get_phrase('Please set class schedule properly.'));
return redirect()->back();
}
}
// check duplicate title for same bootcamp id
$title = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamps.user_id', auth()->user()->id)
->where('bootcamp_modules.id', $request->module_id)
->where('bootcamp_live_classes.id', '!=', $id)
->where('bootcamp_live_classes.title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
if ($class->start_time != $start_timestamp || $class->end_time != $end_timestamp) {
$data['force_stop'] = 0;
}
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['description'] = $request->description;
$data['status'] = $request->status;
$data['module_id'] = $request->module_id;
$data['start_time'] = $start_timestamp;
$data['end_time'] = $end_timestamp;
if ($class->provider == 'zoom') {
$oldMeetingData = json_decode($class->joining_data, true);
ZoomMeetingController::updateMeeting($request->title, $request->start_time, $oldMeetingData['id']);
$oldMeetingData["start_time"] = date('Y-m-d\TH:i:s', strtotime($request->start_time));
$oldMeetingData["topic"] = $request->class_topic;
$data['joining_data'] = json_encode($oldMeetingData);
}
$class->update($data);
Session::flash('success', get_phrase('Live class has been updated.'));
return redirect()->back();
}
public function delete($id)
{
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_live_classes.id', $id)
->where('bootcamps.user_id', auth()->user()->id);
if ($class->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$meetingData = $class->value('joining_data');
if ($meetingData) {
$oldMeetingData = json_decode($meetingData, true);
ZoomMeetingController::deleteMeeting($oldMeetingData['id']);
}
BootcampLiveClass::where('id', $id)->delete();
Session::flash('success', get_phrase('Live class has been deleted.'));
return redirect()->back();
}
public function join_class($slug)
{
$current_time = time();
$extended_time = $current_time + (60 * 15);
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_live_classes.slug', $slug)
->where('bootcamps.user_id', auth()->user()->id)
->select('bootcamp_live_classes.*', 'bootcamps.id as bootcamp_id', 'bootcamps.user_id as host_id')
->first();
if (! $class) {
Session::flash('error', get_phrase('Class not found.'));
return redirect()->back();
}
if (get_settings('zoom_web_sdk') == 'active') {
$page_data['class'] = $class;
$page_data['user'] = get_user_info($class->host_id);
$page_data['is_host'] = 1;
return view('bootcamp_online_class.index', $page_data);
} else {
$meeting_info = json_decode($class->joining_data, true);
return redirect($meeting_info['start_url']);
}
}
public function stop_class($id)
{
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_live_classes.id', $id)
->where('bootcamps.user_id', auth()->user()->id)
->select('bootcamp_live_classes.*', 'bootcamps.id as bootcamp_id')
->first();
if (! $class) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$class->update(['force_stop' => 1]);
Session::flash('success', get_phrase('Class has been ended.'));
return redirect()->back();
}
public function sort(Request $request)
{
$classes = json_decode($request->itemJSON);
foreach ($classes as $key => $value) {
$updater = $key + 1;
BootcampLiveClass::where('id', $value)->update(['sort' => $updater]);
}
return response()->json([
'status' => true,
'success' => get_phrase('Classes sorted successfully'),
]);
}
}

View File

@ -0,0 +1,125 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\BootcampModule;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class BootcampModuleController extends Controller
{
public function __construct()
{
date_default_timezone_set('Asia/Dhaka');
}
public function store(Request $request)
{
$rules = [
'title' => 'required|string',
'validity' => 'required',
'bootcamp_id' => 'required',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
// check duplicate title for same bootcamp id
$title = BootcampModule::join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamps.user_id', auth()->user()->id)->where('bootcamp_modules.title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['restriction'] = $request->restriction;
$data['bootcamp_id'] = $request->bootcamp_id;
$date = explode('-', $request->validity);
$data['publish_date'] = strtotime($date[0]);
$data['expiry_date'] = strtotime($date[1]);
BootcampModule::insert($data);
Session::flash('success', get_phrase('Module has been created.'));
return redirect()->back();
}
public function delete($id)
{
$module = BootcampModule::join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_modules.id', $id)
->where('bootcamps.user_id', auth()->user()->id);
if ($module->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$module->delete();
Session::flash('success', get_phrase('Module has been deleted.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$rules = [
'title' => 'required|string',
'validity' => 'required',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$module = BootcampModule::join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_modules.id', $id)
->where('bootcamp_modules.bootcamp_id', $request->bootcamp_id)
->where('bootcamps.user_id', auth()->user()->id)
->first();
if (! $module) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
// check duplicate title for same bootcamp id
$title = BootcampModule::join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->where('bootcamp_modules.id', '!=', $id)
->where('bootcamps.user_id', auth()->user()->id)
->where('bootcamp_modules.title', $request->title)->first();
if ($title) {
Session::flash('error', get_phrase('This title has been taken.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['restriction'] = $request->restriction;
$date = explode('-', $request->validity);
$data['publish_date'] = strtotime($date[0]);
$data['expiry_date'] = strtotime($date[1]);
BootcampModule::where('id', $id)->update($data);
Session::flash('success', get_phrase('Module has been updated.'));
return redirect()->back();
}
public function sort(Request $request)
{
$modules = json_decode($request->itemJSON);
foreach ($modules as $key => $value) {
$updater = $key + 1;
BootcampModule::where('id', $value)->update(['sort' => $updater]);
}
return response()->json([
'status' => true,
'success' => get_phrase('Modules sorted successfully'),
]);
}
}

View File

@ -0,0 +1,96 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\BootcampModule;
use App\Models\BootcampResource;
use App\Models\FileUploader;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class BootcampResourceController extends Controller
{
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'module_id' => 'required|numeric',
'upload_type' => 'required|in:resource,record',
'files' => 'required|array',
'files.*' => 'required|file',
]);
if ($validator->fails()) {
return response()->back()->withErrors($validator)->withInput();
}
$module = BootcampModule::join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
->select('bootcamp_modules.*', 'bootcamps.title as bootcamp_title')
->where('bootcamp_modules.id', $request->module_id)->first();
if (! $module) {
Session::flash('error', get_phrase('Module not found.'));
return redirect()->back();
}
$data['module_id'] = $module->id;
$data['upload_type'] = $request->upload_type;
$allowed_extensions = ['mp4', 'mov', 'avi', 'wmv', 'webm'];
$files = $request->file('files');
foreach ($files as $file) {
if ($request->upload_type == 'record' && ! in_array($file->getClientOriginalExtension(), $allowed_extensions)) {
Session::flash('error', get_phrase("Failed to upload. File type must be a video."));
return redirect()->back();
}
$file_name = $file->getClientOriginalName();
$data['title'] = replace_url_symbol($file_name);
$data['file'] = 'uploads/bootcamp/resource/' . auth()->user()->name . '/' . $module->bootcamp_title . '/' . $module->title . '/' . $data['title'];
$query = BootcampResource::where('title', $data['title']);
if ($query->exists()) {
Session::flash('error', get_phrase("File already exists."));
return redirect()->back();
}
$query->insert($data);
FileUploader::upload($file, $data['file']);
}
Session::flash('success', get_phrase(ucfirst($request->upload_type) . ' has been uploaded.'));
return redirect()->back();
}
public function delete($id)
{
$resource = BootcampResource::where('id', $id)->first();
if (! $resource) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$file_path = public_path($resource->file);
if (file_exists($file_path)) {
remove_file($file_path);
}
$resource->delete();
Session::flash('success', get_phrase(ucfirst($resource->upload_type) . ' has been deleted.'));
return redirect()->back();
}
public function download($id)
{
$resource = BootcampResource::where('id', $id);
if ($resource->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$file = $resource->first();
$file_path = public_path($file->file);
if (! file_exists($file_path)) {
Session::flash('error', get_phrase('File does not exist.'));
return redirect()->back();
}
return response()->download($file_path);
}
}

View File

@ -0,0 +1,482 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Course;
use App\Models\FileUploader;
use App\Models\Section;
use App\Models\SeoField;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Yajra\DataTables\Facades\DataTables;
class CourseController extends Controller
{
public function index(Request $request)
{
$category = 'all';
$status = 'all';
$instructor = 'all';
$price = 'all';
$query = Course::where('user_id', auth()->user()->id);
if (isset($request->category) && $request->category != '' && $request->category != 'all') {
$category_details = Category::where('slug', $request->category)->first();
if ($category_details->parent_id == 0) {
$sub_cat_id = Category::where('parent_id', $category_details->id)->pluck('id');
$query = $query->whereIn('category_id', $sub_cat_id->toArray());
$page_data['parent_cat'] = $request->category;
} else {
$page_data['child_cat'] = $request->category;
$query = $query->where('category_id', $category_details->id);
}
}
// search filter
if (isset($_GET['search']) && $_GET['search'] != '') {
$query = $query->where('title', 'LIKE', '%' . $_GET['search'] . '%');
}
// selected price
if (isset($_GET['price']) && $_GET['price'] != '' && $_GET['price'] != 'all') {
$search_price = 2;
if ($_GET['price'] == 'free') {
$search_price = 0;
} elseif ($_GET['price'] == 'paid') {
$search_price = 1;
}
$query = $query->where('is_paid', $search_price);
$price = $_GET['price'];
}
// selected instructor
if (isset($_GET['instructor']) && $_GET['instructor'] != '' && $_GET['instructor'] != 'all') {
$query = $query->where('user_id', $_GET['instructor']);
$instructor = $_GET['instructor'];
}
// status filter
if (isset($_GET['status']) && $_GET['status'] != '' && $_GET['status'] != 'all') {
if ($_GET['status'] == 'active') {
$search_status = 'active';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'inactive') {
$search_status = 'inactive';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'pending') {
$search_status = 'pending';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'private') {
$search_status = 'private';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'upcoming') {
$search_status = 'upcoming';
$query = $query->where('status', $search_status);
} elseif ($_GET['status'] == 'draft') {
$search_status = 'draft';
$query = $query->where('status', $search_status);
}
$status = $_GET['status'];
}
$page_data['status'] = $status;
$page_data['instructor'] = $instructor;
$page_data['price'] = $price;
$page_data['courses'] = $query->orderBy('id', 'desc')->paginate(20)->appends(request()->query());
$page_data['pending_courses'] = Course::where('user_id', auth()->user()->id)->where('status', 'pending')->count();
$page_data['active_courses'] = Course::where('user_id', auth()->user()->id)->where('status', 'active')->count();
$page_data['upcoming_courses'] = Course::where('user_id', auth()->user()->id)->where('status', 'upcoming')->count();
$page_data['paid_courses'] = Course::where('user_id', auth()->user()->id)->where('is_paid', 1)->count();
$page_data['free_courses'] = Course::where('user_id', auth()->user()->id)->where('is_paid', 0)->count();
return view('instructor.course.index', $page_data);
}
public function create()
{
return view('instructor.course.create');
}
public function store(Request $request)
{
$rules = [
'title' => 'required|max:255',
'category_id' => 'required|numeric|min:1',
'course_type' => 'required|in:general,scorm',
'level' => 'required|in:everyone,beginner,intermediate,advanced',
'language' => 'required',
'is_paid' => Rule::in(['0', '1']),
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
'discount_flag' => Rule::in(['', '1']),
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
'requirements' => 'array',
'outcomes' => 'array',
'faqs' => 'array',
'instructors' => 'required|array|min:1',
];
//For ajax form submission
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
//return form validation error as json formate for ajaxForm submission
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
}
//for normal form submission
$data['title'] = $request->title;
$data['slug'] = slugify($request->title);
$data['user_id'] = auth()->user()->id;
$data['category_id'] = $request->category_id;
$data['course_type'] = $request->course_type;
$data['status'] = 'pending';
$data['level'] = $request->level;
$data['language'] = strtolower($request->language);
$data['is_paid'] = $request->is_paid;
$data['price'] = $request->price;
$data['discount_flag'] = $request->discount_flag;
$data['discounted_price'] = $request->discounted_price;
$data['enable_drip_content'] = $request->enable_drip_content;
$drip_content_settings = '{"lesson_completion_role":"percentage","minimum_duration":15,"minimum_percentage":"30","locked_lesson_message":"&lt;h3 xss=&quot;removed&quot; style=&quot;text-align: center; &quot;&gt;&lt;span xss=&quot;removed&quot;&gt;&lt;strong&gt;Permission denied!&lt;\/strong&gt;&lt;\/span&gt;&lt;\/h3&gt;&lt;p xss=&quot;removed&quot; style=&quot;text-align: center; &quot;&gt;&lt;span xss=&quot;removed&quot;&gt;This course supports drip content, so you must complete the previous lessons.&lt;\/span&gt;&lt;\/p&gt;"}';
$data['drip_content_settings'] = $drip_content_settings;
$meta_keywords = '';
$meta_keywords_arr = json_decode($request->meta_keywords, true);
if (is_array($meta_keywords_arr)) {
foreach ($meta_keywords_arr as $key => $keyword) {
if ($key > 0) {
$meta_keywords .= ',' . $keyword['value'];
} else {
$meta_keywords .= $keyword['value'];
}
}
}
$data['meta_keywords'] = $meta_keywords;
$data['meta_description'] = $request->meta_description;
$data['short_description'] = $request->short_description;
$data['description'] = $request->description;
//Course expiry period
if ($request->expiry_period == 'limited_time' && is_numeric($request->number_of_month) && $request->number_of_month > 0) {
$data['expiry_period'] = $request->number_of_month;
} else {
$data['expiry_period'] = null;
}
//Remove empty value by using array filter function
if (isset($request->requirements) && $request->requirements != '') {
$data['requirements'] = json_encode(array_filter($request->requirements, fn ($value) => !is_null($value) && $value !== ''));
}
if (isset($request->outcomes) && $request->outcomes != '') {
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn ($value) => !is_null($value) && $value !== ''));
}
if (isset($request->faq_title) && $request->faq_title != '') {
$faqs = [];
foreach ($request->faq_title as $key => $title) {
if ($title != '') {
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
}
}
$data['faqs'] = json_encode($faqs);
}
$data['instructor_ids'] = json_encode($request->instructors);
$data['created_at'] = date('Y-m-d H:i:s');
$data['updated_at'] = date('Y-m-d H:i:s');
if ($request->thumbnail) {
$data['thumbnail'] = "uploads/course-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
}
if ($request->banner) {
$data['banner'] = "uploads/course-banner/" . nice_file_name($request->title, $request->banner->extension());
FileUploader::upload($request->banner, $data['banner'], 400, null, 200, 200);
}
if ($request->preview) {
$data['preview'] = "uploads/course-preview/" . nice_file_name($request->title, $request->preview->extension());
FileUploader::upload($request->preview, $data['preview']);
}
$course_id = Course::insertGetId($data);
Course::where('id', $course_id)->update(['slug' => slugify($request->title . '-' . $course_id)]);
// //For ajax form submission
Session::flash('success', get_phrase('Course added successfully'));
return [
'redirectTo' => route('instructor.course.edit', ['id' => $course_id]),
];
}
public function edit(Request $request, $course_id = "")
{
$data['course_details'] = Course::where('id', $course_id)->first();
$data['sections'] = Section::where('course_id', $course_id)->orderBy('sort')->get();
return view('instructor.course.edit', $data);
}
public function update(Request $request, $id)
{
$query = Course::where('id', $id);
if ($request->tab == '') {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$rules = $data = [];
if ($request->tab == 'basic') {
$rules = [
'title' => 'required|max:255',
'category_id' => 'required|numeric|min:1',
'level' => 'required|in:everyone,beginner,intermediate,advanced',
'language' => 'required',
'status' => 'required|in:active,pending,draft,private,upcoming,inactive',
'instructors' => 'required|array|min:1',
];
$data['title'] = $request->title;
$data['slug'] = slugify($request->title . '-' . $id);
$data['short_description'] = $request->short_description;
$data['description'] = $request->description;
$data['category_id'] = $request->category_id;
$data['level'] = $request->level;
$data['language'] = strtolower($request->language);
$data['status'] = $request->status;
$data['instructor_ids'] = json_encode($request->instructors);
} elseif ($request->tab == 'pricing') {
$rules = [
'is_paid' => Rule::in(['0', '1']),
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
'discount_flag' => Rule::in(['', '1']),
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
];
$data['is_paid'] = $request->is_paid;
$data['price'] = $request->price;
$data['discount_flag'] = $request->discount_flag;
$data['discounted_price'] = $request->discounted_price;
//Course expiry period
if ($request->expiry_period == 'limited_time' && is_numeric($request->number_of_month) && $request->number_of_month > 0) {
$data['expiry_period'] = $request->number_of_month;
} else {
$data['expiry_period'] = null;
}
} elseif ($request->tab == 'info') {
$rules = [
'requirements' => 'array',
'outcomes' => 'array',
'faqs' => 'array',
];
//Remove empty value by using array filter function
$data['requirements'] = json_encode(array_filter($request->requirements, fn ($value) => !is_null($value) && $value !== ''));
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn ($value) => !is_null($value) && $value !== ''));
$faqs = [];
foreach ($request->faq_title as $key => $title) {
if ($title != '') {
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
}
}
$data['faqs'] = json_encode($faqs);
} elseif ($request->tab == 'media') {
if ($request->thumbnail) {
$data['thumbnail'] = "uploads/course-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
remove_file($query->first()->thumbnail);
}
if ($request->banner) {
$data['banner'] = "uploads/course-banner/" . nice_file_name($request->title, $request->banner->extension());
FileUploader::upload($request->banner, $data['banner'], 1400, null, 300, 300);
remove_file($query->first()->banner);
}
if ($request->preview_video_provider == 'link') {
$data['preview'] = $request->preview_link;
} elseif ($request->preview_video_provider == 'file' && $request->preview) {
$data['preview'] = "uploads/course-preview/" . nice_file_name($request->title, $request->preview->extension());
FileUploader::upload($request->preview, $data['preview']);
remove_file($query->first()->preview);
}
} elseif ($request->tab == 'seo') {
$course_details = $query->first();
$SeoField = SeoField::where('name_route', 'course.details')->where('course_id', $course_details->id)->first();
$seo_data['course_id'] = $id;
$seo_data['route'] = 'Course Details';
$seo_data['name_route'] = 'course.details';
$seo_data['meta_title'] = $request->meta_title;
$seo_data['meta_description'] = $request->meta_description;
$seo_data['meta_robot'] = $request->meta_robot;
$seo_data['canonical_url'] = $request->canonical_url;
$seo_data['custom_url'] = $request->custom_url;
$seo_data['json_ld'] = $request->json_ld;
$seo_data['og_title'] = $request->og_title;
$seo_data['og_description'] = $request->og_description;
$seo_data['created_at'] = date('Y-m-d H:i:s');
$seo_data['updated_at'] = date('Y-m-d H:i:s');
$meta_keywords_arr = json_decode($request->meta_keywords, true);
$meta_keywords = '';
if (is_array($meta_keywords_arr)) {
foreach ($meta_keywords_arr as $arr_key => $arr_val) {
$meta_keywords .= $meta_keywords == '' ? $arr_val['value'] : ', ' . $arr_val['value'];
}
$seo_data['meta_keywords'] = $meta_keywords;
}
if ($request->og_image) {
$originalFileName = $course_details->id . '-' . $request->og_image->getClientOriginalName();
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
// Move the file to the destination path
FileUploader::upload($request->og_image, $destinationPath, 600);
$seo_data['og_image'] = $destinationPath;
}
if ($SeoField) {
if ($request->og_image) {
remove_file($SeoField->og_image);
}
SeoField::where('name_route', 'course.details')->where('course_id', $course_details->id)->update($seo_data);
} else {
SeoField::insert($seo_data);
}
} elseif ($request->tab == 'drip-content') {
$rules = [
'enable_drip_content' => Rule::in(['0', '1']),
];
$data['enable_drip_content'] = $request->enable_drip_content;
$lesson_completion_role = htmlspecialchars($request->input('lesson_completion_role'));
$minimum_duration_input = htmlspecialchars($request->input('minimum_duration'));
$minimum_percentage = htmlspecialchars($request->input('minimum_percentage'));
$locked_lesson_message = htmlspecialchars($request->input('locked_lesson_message'));
// Convert time (HH:MM:SS) to seconds
$time_parts = explode(':', $minimum_duration_input);
$seconds = ($time_parts[0] * 3600) + ($time_parts[1] * 60) + $time_parts[2];
$drip_data = [
'lesson_completion_role' => $lesson_completion_role,
'minimum_duration' => $seconds,
'minimum_percentage' => $minimum_percentage,
'locked_lesson_message' => $locked_lesson_message,
];
$data['drip_content_settings'] = json_encode($drip_data);
}
//For ajax form submission
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
}
$query->update($data);
//For ajax form submission
return ['success' => get_phrase('Course updated successfully')];
//for normal form submission
}
public function delete($id)
{
$query = Course::where('id', $id);
remove_file($query->first()->thumbnail);
remove_file($query->first()->banner);
remove_file($query->first()->preview);
$query->delete();
return redirect(route('instructor.courses'))->with('success', get_phrase('Course deleted successfully'));
}
public function status($type, $id)
{
if ($type == 'active') {
Course::where('id', $id)->update(['status' => 'active']);
} elseif ($type == 'pending') {
Course::where('id', $id)->update(['status' => 'pending']);
} elseif ($type == 'inactive') {
Course::where('id', $id)->update(['status' => 'inactive']);
} elseif ($type == 'upcoming') {
Course::where('id', $id)->update(['status' => 'upcoming']);
} elseif ($type == 'private') {
Course::where('id', $id)->update(['status' => 'private']);
} else {
Course::where('id', $id)->update(['status' => 'draft']);
}
return redirect(route('admin.courses'))->with('success', get_phrase('Course status changed successfully'));
}
public function draft($id)
{
$course = Course::where('id', $id)->first();
if (!$course) {
$response = [
'error' => get_phrase('Data not found.'),
];
return json_encode($response);
}
$status = $course->status == 'active' ? 'deactivate' : 'active';
Course::where('id', $id)->update(['status' => $status]);
$response = [
'success' => get_phrase('Status has been updated.'),
];
return json_encode($response);
}
public function duplicate($id)
{
$course = Course::where('id', $id);
if (auth()->user()->role != 'admin') {
$course = $course->where('user_id', auth()->user()->id);
}
// check course existence
if ($course->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
// collect course and remove unnecessary fields
$data = $course->first()->toArray();
if (auth()->user()->role == 'admin') {
$data['user_id'] = auth()->user()->id;
}
unset($data['id'], $data['created_at'], $data['updated_at']);
$data['status'] = 'pending';
// insert as new course
$course_id = Course::insertGetId($data);
Course::where('id', $course_id)->update(['slug' => slugify($data['title']).'-'.$course_id]);
// go to edit
Session::flash('success', get_phrase('Course duplicated.'));
return redirect()->route('instructor.course.edit', $course_id);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Course;
use App\Models\Lesson;
use App\Models\Payment_history;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
public function index()
{
$monthly_amount = array(0);
for ($i = 1; $i <= 12; $i++) {
$total_amount = date('t', strtotime(date("Y-$i-1 00:00:00")));
$amount = Payment_history::whereDate('created_at', '>=', date("Y-$i-1 00:00:00"))->whereDate('created_at', '<=', date("Y-$i-$total_amount 23:59:59"))->get();
if (count($amount) > 0) {
array_push($monthly_amount, array_sum($amount->pluck('instructor_revenue')->toArray()));
} else {
array_push($monthly_amount, 0);
}
}
$page_data['monthly_amount'] = $monthly_amount;
return view('instructor.dashboard.index', $page_data);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Course;
use App\Models\Payout;
use App\Models\User;
use Illuminate\Http\Request;
class InstructorController extends Controller {
// curriculum
}

View File

@ -0,0 +1,388 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Http\Controllers\WatermarkController;
use App\Models\Lesson;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Session;
use App\Models\FileUploader;
class LessonController extends Controller
{
public function store(Request $request)
{
$maximum_sort_value = Lesson::where('course_id', $request->course_id)->orderBy('sort', 'desc')->firstOrNew()->sort;
// duplicate check
if (Lesson::where('course_id', $request->course_id)->where('title', $request->title)->exists()) {
Session::flash('error', get_phrase('Lesson already exists.'));
return redirect()->back();
}
$lesson = new Lesson();
$lesson->title = $request->title;
$lesson->user_id = auth()->user()->id;
$lesson->course_id = $request->course_id;
$lesson->section_id = $request->section_id;
$lesson->is_free = $request->free_lesson;
$lesson->lesson_type = $request->lesson_type;
$lesson->summary = $request->summary;
$lesson->sort = $maximum_sort_value + 1;
if ($request->lesson_type == 'text') {
$lesson->attachment = $request->text_description;
$lesson->attachment_type = $request->lesson_provider;
} elseif ($request->lesson_type == 'video-url') {
$lesson->video_type = $request->lesson_provider;
$lesson->lesson_src = $request->lesson_src;
$lesson->duration = $request->duration;
} elseif ($request->lesson_type == 'html5') {
$lesson->video_type = $request->lesson_provider;
$lesson->lesson_src = $request->lesson_src;
$lesson->duration = $request->duration;
} elseif ($request->lesson_type == 'document_type') {
if ($request->attachment == '') {
$file = '';
} else {
$item = $request->file('attachment');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/attachment');
if (!File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
} else {
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
}
$file = $file_name;
}
$lesson->attachment = $file;
$lesson->attachment_type = $request->attachment_type;
} elseif ($request->lesson_type == 'scorm') {
if ($request->scorm_file == '') {
$file = '';
} else {
$item = $request->file('scorm_file');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$upload_path = public_path('uploads/lesson_file/scorm_content');
if (! File::isDirectory($upload_path)) {
File::makeDirectory($upload_path, 0777, true, true);
}
$item->move($upload_path, $file_name);
$zip = new \ZipArchive();
$zip_path = $upload_path . '/' . $file_name;
$extract_path = $upload_path . '/' . pathinfo($file_name, PATHINFO_FILENAME);
if ($zip->open($zip_path) === true) {
$zip->extractTo($extract_path);
$zip->close();
File::delete($zip_path);
} else {
return response()->json(['error' => 'Failed to extract the SCORM file.'], 500);
}
$file = pathinfo($file_name, PATHINFO_FILENAME);
}
$lesson['attachment'] = $file;
$lesson['attachment_type'] = $request->scorm_provider;
} elseif ($request->lesson_type == 'image') {
if ($request->attachment == '') {
$file = '';
} else {
$item = $request->file('attachment');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/attachment');
if (!File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
} else {
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
}
$file = $file_name;
}
$lesson->attachment = $file;
$lesson->attachment_type = $item->getClientOriginalExtension();
} elseif ($request->lesson_type == 'vimeo-url') {
$lesson->video_type = $request->lesson_provider;
$lesson->lesson_src = $request->lesson_src;
$lesson->duration = $request->duration;
} elseif ($request->lesson_type == 'iframe') {
$lesson->lesson_src = $request->iframe_source;
} elseif ($request->lesson_type == 'google_drive') {
$lesson->video_type = $request->lesson_provider;
$lesson->lesson_src = $request->lesson_src;
$lesson->duration = $request->duration;
} elseif ($request->lesson_type == 'system-video') {
if ($request->system_video_file == '') {
$file = '';
} else {
$item = $request->file('system_video_file');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/videos');
if (! File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
}
$type = get_player_settings('watermark_type');
if ($type == 'ffmpeg') {
$watermark = get_player_settings('watermark_logo');
if (! $watermark) {
return redirect()->back()->with('error', get_phrase('Please configure watermark setting.'));
}
if (! file_exists(public_path($watermark))) {
return redirect()->back()->with('error', get_phrase('File doesn\'t exists.'));
}
$watermark_status = WatermarkController::encode($item, $file_name, $path);
if (! $watermark_status) {
return redirect()->back()->with('error', get_phrase('Something went wrong.'));
}
}
$file = FileUploader::upload($request->system_video_file, 'uploads/lesson_file/videos/' . $file_name);
}
$lesson->video_type = $request->lesson_provider;
$lesson->lesson_src = $file;
if (empty($request->duration)) {
$lesson->duration = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson->duration = $hour . ':' . $min . ':' . $sec;
}
}
$lesson->save();
Session::flash('success', get_phrase('Lesson added successfully.'));
return redirect()->back();
}
public function sort(Request $request)
{
$lessons = json_decode($request->itemJSON);
foreach ($lessons as $key => $value) {
$updater = $key + 1;
Lesson::where('id', $value)->update(['sort' => $updater]);
}
}
public function update(Request $request)
{
$current_data = Lesson::find($request->id);
$lesson['title'] = $request->title;
$lesson['section_id'] = $request->section_id;
$lesson['summary'] = $request->summary;
if ($request->lesson_type == 'text') {
$lesson['attachment'] = $request->text_description;
} elseif ($request->lesson_type == 'video-url') {
$lesson['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'html5') {
$lesson['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'document_type') {
if ($request->attachment) {
$item = $request->file('attachment');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/attachment');
if (!File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
} else {
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
}
$lesson['attachment'] = $file_name;
$lesson['attachment_type'] = $request->attachment_type;
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
}
} elseif ($request->lesson_type == 'image') {
if ($request->attachment) {
$item = $request->file('attachment');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/attachment');
if (!File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
} else {
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
}
$lesson['attachment'] = $file_name;
$lesson['attachment_type'] = $item->getClientOriginalExtension();
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
}
} elseif ($request->lesson_type == 'vimeo-url') {
$lesson['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'iframe') {
$lesson['lesson_src'] = $request->iframe_source;
} elseif ($request->lesson_type == 'google_drive') {
$lesson['lesson_src'] = $request->lesson_src;
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
} elseif ($request->lesson_type == 'scorm') {
$existing_scorm_folder = $request->attachment;
if ($request->scorm_file == '') {
$file = '';
} else {
$item = $request->file('scorm_file');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$upload_path = public_path('uploads/lesson_file/scorm_content');
if (! File::isDirectory($upload_path)) {
File::makeDirectory($upload_path, 0777, true, true);
}
$this->deleteDir(public_path('uploads/lesson_file/scorm_content/' . $existing_scorm_folder));
FileUploader::upload($request->scorm_file, 'uploads/lesson_file/scorm_content/' . $file_name);
$zip = new \ZipArchive();
$zip_path = $upload_path . '/' . $file_name;
$extract_path = $upload_path . '/' . pathinfo($file_name, PATHINFO_FILENAME);
// Remove old SCORM directory if it exists
$existing_scorm_path = $upload_path . '/' . $request->scorm_file;
if (File::isDirectory($existing_scorm_path)) {
File::deleteDirectory($existing_scorm_path);
}
if ($zip->open($zip_path) === true) {
$zip->extractTo($extract_path);
$zip->close();
File::delete($zip_path);
} else {
return response()->json(['error' => 'Failed to extract the SCORM file.'], 500);
}
$file = pathinfo($file_name, PATHINFO_FILENAME);
}
$lesson['attachment'] = $file;
$lesson['attachment_type'] = $request->scorm_provider;
} elseif ($request->lesson_type == 'system-video') {
if ($request->system_video_file) {
$item = $request->file('system_video_file');
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
$path = public_path('uploads/lesson_file/videos');
if (! File::isDirectory($path)) {
File::makeDirectory($path, 0777, true, true);
}
$type = get_player_settings('watermark_type');
if ($type == 'ffmpeg') {
$watermark = get_player_settings('watermark_logo');
if (! $watermark) {
return redirect()->back()->with('error', get_phrase('Please configure watermark setting.'));
}
if (! file_exists(public_path($watermark))) {
return redirect()->back()->with('error', get_phrase('File doesn\'t exists.'));
}
$watermark_status = WatermarkController::encode($item, $file_name, $path);
if (! $watermark_status) {
return redirect()->back()->with('error', get_phrase('Something went wrong.'));
}
}
FileUploader::upload($request->system_video_file, 'uploads/lesson_file/videos/' . $file_name);
$file = str_replace(public_path('/'), '', $path).'/'. $file_name;
$lesson['lesson_src'] = $file;
remove_file($current_data->lesson_src);
}
if (empty($request->duration)) {
$lesson['duration'] = '00:00:00';
} else {
$duration_formatter = explode(':', $request->duration);
$hour = sprintf('%02d', $duration_formatter[0]);
$min = sprintf('%02d', $duration_formatter[1]);
$sec = sprintf('%02d', $duration_formatter[2]);
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
}
}
Lesson::where('id', $request->id)->update($lesson);
Session::flash('success', get_phrase('lesson update successfully'));
return redirect()->back();
}
public function deleteDir($directoryPath)
{
if (File::exists($directoryPath)) {
// Delete all files and subdirectories within the directory
File::deleteDirectory($directoryPath);
// Finally, delete the root directory itself
File::delete($directoryPath);
}
}
public function delete($id)
{
$current_data = Lesson::find($id);
remove_file($current_data->lesson_src);
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
Lesson::where('id', $id)->delete();
Session::flash('success', get_phrase('Delete successfully'));
return redirect()->back();
}
}

View File

@ -0,0 +1,260 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Course;
use App\Models\Live_class;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Http\Request;
class LiveClassController extends Controller
{
public function live_class_start($id)
{
$live_class = Live_class::where('id', $id)->first();
if ($live_class->provider == 'zoom') {
if (get_settings('zoom_web_sdk') == 'active') {
return view('course_player.live_class.zoom_live_class', ['live_class' => $live_class]);
} else {
$meeting_info = json_decode($live_class->additional_info, true);
return redirect($meeting_info['start_url']);
}
} else {
return view('course_player.live_class.zoom_live_class', ['live_class' => $live_class]);
}
}
public function live_class_store(Request $request, $course_id)
{
$validated = $request->validate([
'class_topic' => 'required|max:255',
'class_date_and_time' => 'date|required',
'user_id' => 'required',
]);
$data['class_topic'] = $request->class_topic;
$data['course_id'] = $request->course_id;
$data['user_id'] = $request->user_id;
$data['provider'] = $request->provider;
$data['class_date_and_time'] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
$data['note'] = $request->note;
if ($request->provider == 'zoom') {
$meeting_info = $this->create_zoom_live_class($request->class_topic, $request->class_date_and_time);
$meeting_info_arr = json_decode($meeting_info, true);
if (array_key_exists('code', $meeting_info_arr) && $meeting_info_arr) {
return redirect(route('instructor.course.edit', ['id' => $course_id, 'tab' => 'live-class']))->with('error', get_phrase($meeting_info_arr['message']));
}
$data['additional_info'] = $meeting_info;
}
Live_class::insert($data);
return redirect(route('instructor.course.edit', ['id' => $course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class added successfully'));
}
public function live_class_update(Request $request, $id)
{
$previous_meeting_data = Live_class::where('id', $id)->first();
$request->validate([
'class_topic' => 'required|max:255',
'class_date_and_time' => 'date|required',
'user_id' => 'required',
]);
$data['class_topic'] = $request->class_topic;
$data['user_id'] = $request->user_id;
$data['class_date_and_time'] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
$data['note'] = $request->note;
if ($previous_meeting_data->provider == 'zoom') {
$previous_meeting_info = json_decode($previous_meeting_data->additional_info, true);
$this->update_zoom_live_class($request->class_topic, $request->class_date_and_time, $previous_meeting_info['id']);
$previous_meeting_info["start_time"] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
$previous_meeting_info["topic"] = $request->class_topic;
$data['additional_info'] = json_encode($previous_meeting_info);
}
Live_class::where('id', $id)->update($data);
return redirect(route('instructor.course.edit', ['id' => $previous_meeting_data->course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class updated successfully'));
}
public function live_class_delete($id)
{
$previous_meeting_data = Live_class::where('id', $id)->first();
$course = Course::where('id', $previous_meeting_data->course_id)->first();
if ($course->instructors()->count() > 0) {
$previous_meeting_info = json_decode($previous_meeting_data->additional_info, true);
$this->delete_zoom_live_class($previous_meeting_info['id']);
Live_class::where('id', $id)->delete();
}
return redirect(route('instructor.course.edit', ['id' => $previous_meeting_data->course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class deleted successfully'));
}
public function live_class_settings()
{
return view('instructor.setting.live_class_settings');
}
public function update_live_class_settings(Request $request)
{
$validated = $request->validate([
'zoom_account_email' => 'required:email',
'zoom_web_sdk' => 'required|in:active,inactive',
'zoom_account_id' => 'required',
'zoom_client_id' => 'required',
'zoom_client_secret' => 'required',
]);
foreach ($request->all() as $name => $value) {
if (Setting::where('type', $name)->count() > 0) {
Setting::where('type', $name)->update(['description' => $value]);
} else {
Setting::insert(['type' => $name, 'description' => $value]);
}
}
return redirect(route('instructor.live.class.settings'))->with('success', get_phrase('Zoom live class settings has been configured'));
}
public function create_zoom_live_class($topic, $date_and_time)
{
$zoom_account_email = get_settings('zoom_account_email');
$token = $this->create_zoom_token();
// API Endpoint for creating a meeting
$zoomEndpoint = 'https://api.zoom.us/v2/users/me/meetings';
// Meeting data
$meetingData = [
'topic' => $topic,
'schedule_for' => $zoom_account_email,
'type' => 2, // Scheduled meeting
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // Start time (in UTC)
'duration' => 60, // Duration in minutes
'timezone' => get_settings('timezone'), // Timezone
'settings' => [
'approval_type' => 2,
'join_before_host' => true,
'jbh_time' => 0,
],
];
// Prepare headers
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
// Make POST request to create meeting
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
// JSON response
return $response;
}
public function update_zoom_live_class($topic, $date_and_time, $meetingId)
{
$token = $this->create_zoom_token(); // Obtain the access token
// API Endpoint for updating a meeting
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
// Meeting data with updated start time
$meetingData = [
'topic' => $topic,
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // New start time (in UTC)
];
// Prepare headers
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
// Make PATCH request to update meeting
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
// JSON response
return $response;
}
public function delete_zoom_live_class($meetingId)
{
$token = $this->create_zoom_token(); // Obtain the access token
// API Endpoint for deleting a meeting
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
// Prepare headers
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
];
// Make DELETE request to delete meeting
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
// JSON response
return $response;
}
public function create_zoom_token()
{
// Access the environment variables
$clientId = get_settings('zoom_client_id');
$clientSecret = get_settings('zoom_client_secret');
$accountId = get_settings('zoom_account_id');
$oauthUrl = 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId; // Replace with your OAuth endpoint URL
$authHeader = 'Basic ' . base64_encode($clientId . ':' . $clientSecret);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/x-www-form-urlencoded',
'Authorization: ' . $authHeader,
'Cookie: __cf_bm=kn5ec2sntPlDgQWVWtSYdPeISb6bp6F7NHwuAFJQaGk-1736318967-1.0.1.1-SeM4z5pIb.nrMno35jg3y5BdXib.GPP13s2_yNnqz6LxbU9zsFTfZQc3a_Di94qx3DoyQjBT2Osz7idFMWWOrw; _zm_chtaid=816; _zm_ctaid=nbT15WlMTsCEAgCyUg3rYw.1736318967206.63747957ef3128f771210fb69e8d6831; _zm_mtk_guid=fa77ae1ac8e349bea690b72d942d6de6; _zm_page_auth=us04_c_uqPDVOshQQK6FRkhQPiPRA; _zm_ssid=us04_c_atJ4QboaQZG4Lw4U-Wpx6A; cred=A404810ADF33AFC21FF517216A4CB862'
),
));
$response = curl_exec($curl);
curl_close($curl);
$oauthResponse = json_decode($response, true) ?? ['access_token' => ''];
$accessToken = $oauthResponse['access_token'];
return $accessToken;
}
}

View File

@ -0,0 +1,196 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\FileUploader;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class MyProfileController extends Controller
{
public function manage_profile()
{
return view('instructor.profile.index');
}
public function manage_profile_update(Request $request)
{
if ($request->type == 'general') {
$profile['name'] = $request->name;
$profile['email'] = $request->email;
$profile['facebook'] = $request->facebook;
$profile['twitter'] = $request->twitter;
$profile['linkedin'] = $request->linkedin;
$profile['video_url'] = $request->video_url;
$profile['about'] = $request->about;
$profile['skills'] = $request->skills;
$profile['biography'] = $request->biography;
if ($request->photo) {
if (isset($request->photo) && $request->photo != '') {
$profile['photo'] = "uploads/users/admin/" . nice_file_name($request->title, $request->photo->extension());
FileUploader::upload($request->photo, $profile['photo'], 400, null, 200, 200);
}
}
User::where('id', auth()->user()->id)->update($profile);
} else {
$old_pass_check = Auth::attempt(['email' => auth()->user()->email, 'password' => $request->current_password]);
if (! $old_pass_check) {
Session::flash('error', get_phrase('Current password wrong.'));
return redirect()->back();
}
if ($request->new_password != $request->confirm_password) {
Session::flash('error', get_phrase('Confirm password not same'));
return redirect()->back();
}
$password = Hash::make($request->new_password);
User::where('id', auth()->user()->id)->update(['password' => $password]);
}
Session::flash('success', get_phrase('Your changes has been saved.'));
return redirect()->back();
}
public function manage_resume()
{
return view('instructor.resume.index');
}
public function education_add(Request $request)
{
// Validate the form data
$validatedData = $request->validate([
'title' => 'required|string|max:255',
'institute' => 'required|string|max:255',
'country' => 'required|string|max:255',
'city' => 'required|string|max:255',
'start_date' => 'required|date',
'end_date' => 'nullable|date',
'status' => 'nullable|string|in:ongoing,completed',
'description' => 'nullable|string'
]);
// Check if 'end_date' is empty and 'status' is 'ongoing'
if ($request->has('status') && $request->status === 'ongoing') {
$validatedData['end_date'] = null;
} else {
$validatedData['status'] = 'completed';
}
// Format data for new education entry
$newEducation = [
'title' => $validatedData['title'],
'institute' => $validatedData['institute'],
'country' => $validatedData['country'],
'city' => $validatedData['city'],
'start_date' => $validatedData['start_date'],
'end_date' => $validatedData['end_date'],
'status' => $validatedData['status'],
'description' => $validatedData['description']
];
// Retrieve the currently authenticated user
$user = Auth::user();
// Decode the existing educations JSON data
$educations = json_decode($user->educations, true) ?? [];
// Append the new education entry
$educations[] = $newEducation;
// Save updated educations data back to the user's educations column as JSON
$user->educations = json_encode($educations);
$user->save();
// Redirect or return a response, e.g., to the resume index page with a success message
return redirect()->route('instructor.manage.resume')->with('success', 'Education added successfully.');
}
public function education_update(Request $request, $index)
{
// Validate the form data
$validatedData = $request->validate([
'title' => 'required|string|max:255',
'institute' => 'required|string|max:255',
'country' => 'required|string|max:255',
'city' => 'required|string|max:255',
'start_date' => 'required|date',
'end_date' => 'nullable|date',
'status' => 'nullable|string|in:ongoing,completed',
'description' => 'nullable|string'
]);
// Check if 'end_date' is empty and 'status' is 'ongoing'
if ($request->has('status') && $request->status === 'ongoing') {
$validatedData['end_date'] = null;
} else {
$validatedData['status'] = 'completed';
}
// Retrieve the currently authenticated user
$user = Auth::user();
// Decode the existing educations JSON data
$educations = json_decode($user->educations, true) ?? [];
// Check if the specified index exists in educations array
if (isset($educations[$index])) {
// Update the existing education entry
$educations[$index] = [
'title' => $validatedData['title'],
'institute' => $validatedData['institute'],
'country' => $validatedData['country'],
'city' => $validatedData['city'],
'start_date' => $validatedData['start_date'],
'end_date' => $validatedData['end_date'],
'status' => $validatedData['status'],
'description' => $validatedData['description']
];
// Save updated educations data back to the user's educations column as JSON
$user->educations = json_encode($educations);
$user->save();
// Redirect or return a response, e.g., to the resume index page with a success message
return redirect()->route('instructor.manage.resume')->with('success', 'Education updated successfully.');
} else {
// Handle the case where the specified education index does not exist
return redirect()->route('instructor.manage.resume')->with('error', 'Education data not found for the specified index.');
}
}
public function education_remove(Request $request, $index)
{
// Retrieve the currently authenticated user
$user = Auth::user();
// Decode the existing educations JSON data
$educations = json_decode($user->educations, true) ?? [];
// Check if the index exists in the educations array
if (isset($educations[$index])) {
// Remove the specific education entry
unset($educations[$index]);
// Re-index the array to ensure no gaps in the indices
$educations = array_values($educations);
// Update the user's educations column with the modified array
$user->educations = json_encode($educations);
$user->save();
return redirect()->route('instructor.manage.resume')->with('success', 'Education deleted successfully.');
} else {
return redirect()->route('instructor.manage.resume')->with('error', 'Education not found.');
}
}
}

View File

@ -0,0 +1,103 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Category;
use App\Models\FileUploader;
use App\Models\Setting;
class OpenAiController extends Controller
{
function generate(Request $request)
{
if ($request->service_type == 'Course thumbnail') {
$prompt = "We have run a online LMS system. Please generate course thumbnails for me. \n Course topic: " . $request->ai_keywords;
return $this->curl_call_to_generate_image_openai($prompt);
} else {
$prompt = "Write me a ";
$prompt .= $request->service_type;
$prompt .= " on ";
$prompt .= $request->ai_keywords;
$prompt .= " in ";
$prompt .= $request->language;
$prompt .= " language";
$instructions = "You are a " . $request->service_type . " writer.";
return $this->curl_call_to_generate_text_by_openai($prompt, $instructions);
}
}
function curl_call_to_generate_image_openai($prompt)
{
$open_ai_secret_key = get_settings('open_ai_secret_key');
$curlopt_post = ['prompt' => $prompt, 'model' => 'dall-e-3', 'size' => '1024x1024', 'n' => 1];
$curlopt_post_url = 'https://api.openai.com/v1/images/generations';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $curlopt_post_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $open_ai_secret_key,
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($curlopt_post));
$response = curl_exec($ch);
curl_close($ch);
$response_arr = json_decode($response, true);
if (array_key_exists('error', $response_arr)) {
return 'Error: ' . $response_arr['error']['message'];
} else {
return json_encode($response_arr['data']);
}
}
function curl_call_to_generate_text_by_openai($instructions, $prompt)
{
$open_ai_secret_key = get_settings('open_ai_secret_key');
$open_ai_model = get_settings('open_ai_model');
$endpoint = "https://api.openai.com/v1/chat/completions";
$data = array(
"model" => $open_ai_model,
"messages" => array(
array(
"role" => "system",
"content" => $instructions
),
array(
"role" => "user",
"content" => "$prompt"
)
)
);
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Authorization: Bearer " . $open_ai_secret_key
));
$response = curl_exec($ch);
curl_close($ch);
if ($response) {
$response = json_decode($response, true);
if (is_array($response)) {
return $response['choices'][0]['message']['content'] ?? '';
}
}
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Course;
use App\Models\Payout;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class PayoutController extends Controller
{
public function index()
{
$page_data['start_date'] = strtotime('first day of this month');
$page_data['end_date'] = strtotime('last day of this month');
// modify date and prepare to compare with database
if (request()->has('eDateRange')) {
$date = explode('-', urldecode(request()->query('eDateRange')));
$page_data['start_date'] = strtotime($date[0] . ' 00:00:00');
$page_data['end_date'] = strtotime($date[1] . ' 23:59:59');
}
$query = Payout::where('user_id', auth()->user()->id)->where('created_at', '>=', date('Y-m-d H:i:s', $page_data['start_date']))
->where('created_at', '<=', date('Y-m-d H:i:s', $page_data['end_date']))->latest('id');
$page_data['payout_reports'] = $query->paginate(10)->appends(request()->query('eDateRange'));
$page_data['payout_request'] = Payout::where('user_id', auth()->user()->id)->where('status', 0)->first();
$page_data['total_payout'] = instructor_total_payout();
$page_data['balance'] = instructor_available_balance();
return view('instructor.payout_report.index', $page_data);
}
public function store(Request $request)
{
// check old request
if (Payout::where('user_id', auth()->user()->id)->where('status', 0)->exists()) {
Session::flash('error', get_phrase('Your request is in process.'));
return redirect()->back();
}
// check amount validity
$total_income = instructor_total_revenue();
$total_payout = instructor_total_payout();
$balance_remaining = $total_income - $total_payout;
if ($request->amount < 1 || $request->amount > $balance_remaining) {
Session::flash('error', get_phrase('You do not have sufficient balance.'));
return redirect()->back();
}
$data['user_id'] = auth()->user()->id;
$data['amount'] = $request->amount;
Payout::insert($data);
Session::flash('success', get_phrase('Your request has been submitted.'));
return redirect()->back();
}
public function delete($id)
{
if (Payout::where('id', $id)->where('user_id', auth()->user()->id)->doesntExist()) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
Payout::where('id', $id)->delete();
Session::flash('success', get_phrase('Your request has been deleted.'));
return redirect()->back();
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
class PayoutSettingsController extends Controller {
public function payout_setting() {
$payment_setting = User::where('id', auth()->user()->id)->first();
$page_data['instructor'] = json_decode($payment_setting->paymentkeys, true);
return view('instructor.payout_setting.index', $page_data);
}
public function payout_setting_store(Request $request) {
$data = $request->all();
array_shift($data);
$data = json_encode($_POST['gateways']);
User::where('id', auth()->user()->id)->update(['paymentkeys' => $data]);
return redirect(route('instructor.payout.setting'))->with('success', get_phrase('Payout setting updated'));
}
}

View File

@ -0,0 +1,143 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Question;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class QuestionController extends Controller
{
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required',
'type' => 'required',
'answer' => 'required',
'options' => 'required_if:type,mcq',
], [
'options.required_if' => 'When type is MCQ, options are required.',
]);
if ($validator->fails()) {
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
}
$answer = null;
if ($request->type == 'mcq') {
$answer = json_encode($request->answer);
$data['options'] = json_encode(array_column(json_decode($request->options, true), 'value'));
} elseif ($request->type == 'fill_blanks') {
$answers = json_decode($request->answer);
$answer = json_encode(array_column($answers, 'value'));
} elseif ($request->type == 'true_false') {
$answer = $request->answer;
}
$data['quiz_id'] = $request->quiz_id;
$data['title'] = $request->title;
$data['type'] = $request->type;
$data['answer'] = $answer;
Question::insert($data);
return response()->json([
'status' => true,
'success' => get_phrase('Question has been added.'),
'functionCall' => 'responseBack()',
]);
}
public function delete($id)
{
$question = Question::where('id', $id)->first();
if (! $question) {
Session::flash('error', get_phrase('Data not found.'));
return redirect()->back();
}
$question->delete();
Session::flash('success', get_phrase('Question has been deleted.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$question = Question::where('id', $id)->first();
if (! $question) {
return response()->json_encode([
'error' => get_phrase('Data not found.'),
]);
}
$validator = Validator::make($request->all(), [
'title' => 'required',
'type' => 'required',
'answer' => 'required',
'options' => 'required_if:type,mcq',
], [
'options.required_if' => 'When type is MCQ, options are required.',
]);
if ($validator->fails()) {
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
}
$answer = $data['options'] = null;
if ($request->type == 'mcq') {
$answer = json_encode($request->answer);
$data['options'] = json_encode(array_column(json_decode($request->options, true), 'value'));
} elseif ($request->type == 'fill_blanks') {
$answers = json_decode($request->answer);
$answer = json_encode(array_column($answers, 'value'));
} elseif ($request->type == 'true_false') {
$answer = $request->answer;
}
$data['quiz_id'] = $request->quiz_id;
$data['title'] = $request->title;
$data['type'] = $request->type;
$data['answer'] = $answer;
Question::where('id', $id)->update($data);
return response()->json([
'status' => true,
'success' => get_phrase('Question has been updated.'),
'functionCall' => 'responseBack()',
]);
}
public function sort(Request $request)
{
$question = json_decode($request->itemJSON);
foreach ($question as $key => $value) {
$updater = $key + 1;
Question::where('id', $value)->update(['sort' => $updater]);
}
Session::flash('success', get_phrase('Questions has been sorted.'));
}
public function load_type(Request $request)
{
$page_data = [];
$types = [
'mcq' => 'mcq',
'fill_blanks' => 'fill_blanks',
'true_false' => 'true_false',
];
if (isset($types[$request->type])) {
$action = $request->id ? 'edit' : 'create';
$path = "admin.questions.{$action}_{$types[$request->type]}";
if ($request->id) {
$page_data['question'] = Question::where('id', $request->id)->first();
}
}
return view($path, $page_data);
}
}

View File

@ -0,0 +1,162 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Lesson;
use App\Models\Question;
use App\Models\Quiz;
use App\Models\QuizSubmission;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class QuizController extends Controller
{
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required',
'section' => 'required|numeric',
'second' => 'max:59',
'minute' => 'max:59',
'hour' => 'max:23',
'total_mark' => 'required|numeric',
'pass_mark' => 'required|numeric',
'retake' => 'required|numeric|min:1',
])->after(function ($validator) use ($request) {
$hour = $request->hour;
$minute = $request->minute;
$second = $request->second;
if ($hour == 0 && $minute == 0 && $second == 0) {
$validator->errors()->add('second', 'If hour and minute are 0, second must be greater than 0.');
} elseif ($hour == 0 && $minute == 0 && $second < 1) {
$validator->errors()->add('minute', 'If hour is 0, minute must be greater than 0.');
} elseif ($minute == 0 && $second == 0 && $hour < 1) {
$validator->errors()->add('hour', 'If minute and second are 0, hour must be greater than 0.');
}
if ($request->pass_mark > $request->total_mark) {
$validator->errors()->add('pass_mark', 'The pass mark must be less than the total mark.');
}
});
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$title = Lesson::join('sections', 'lessons.section_id', 'sections.id')
->join('courses', 'sections.course_id', 'courses.id')
->where('courses.user_id', auth()->user()->id)
->where('lessons.title', $request->title)
->first();
if ($title) {
Session::flash('error', get_phrase('Title has been taken.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['course_id'] = $request->course_id;
$data['section_id'] = $request->section;
$data['total_mark'] = $request->total_mark;
$data['pass_mark'] = $request->pass_mark;
$data['retake'] = $request->retake;
$data['description'] = $request->description;
$data['lesson_type'] = 'quiz';
$data['status'] = 1;
$hour = $request->hour ?? 0;
$minute = $request->minute ?? 0;
$second = $request->second ?? 0;
$data['duration'] = $hour . ':' . $minute . ':' . $second;
Lesson::insert($data);
Session::flash('success', get_phrase('Quiz has been created.'));
return redirect()->back();
}
public function update(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'title' => 'required',
'section' => 'required|numeric',
'second' => 'max:59',
'minute' => 'max:59',
'hour' => 'max:23',
'total_mark' => 'required|numeric',
'pass_mark' => 'required|numeric',
'retake' => 'required|numeric|min:1',
])->after(function ($validator) use ($request) {
$hour = $request->hour;
$minute = $request->minute;
$second = $request->second;
if ($hour == 0 && $minute == 0 && $second == 0) {
$validator->errors()->add('second', 'If hour and minute are 0, second must be greater than 0.');
} elseif ($hour == 0 && $minute == 0 && $second < 1) {
$validator->errors()->add('minute', 'If hour is 0, minute must be greater than 0.');
} elseif ($minute == 0 && $second == 0 && $hour < 1) {
$validator->errors()->add('hour', 'If minute and second are 0, hour must be greater than 0.');
}
if ($request->pass_mark > $request->total_mark) {
$validator->errors()->add('pass_mark', 'The pass mark must be less than the total mark.');
}
});
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$title = Lesson::join('sections', 'lessons.section_id', 'sections.id')
->join('courses', 'sections.course_id', 'courses.id')
->where('lessons.id', '!=', $id)
->where('lessons.title', $request->title)
->where('courses.user_id', auth()->user()->id)
->first();
if ($title) {
Session::flash('error', get_phrase('Title has been taken.'));
return redirect()->back();
}
$data['title'] = $request->title;
$data['section_id'] = $request->section;
$data['total_mark'] = $request->total_mark;
$data['pass_mark'] = $request->pass_mark;
$data['retake'] = $request->retake;
$data['description'] = $request->description;
$data['lesson_type'] = 'quiz';
$data['status'] = 1;
$hour = $request->hour ?? 0;
$minute = $request->minute ?? 0;
$second = $request->second ?? 0;
$data['duration'] = $hour . ':' . $minute . ':' . $second;
Lesson::where('id', $id)->update($data);
Session::flash('success', get_phrase('Quiz has been updated.'));
return redirect()->back();
}
public function result(Request $request)
{
$submissions = QuizSubmission::where('quiz_id', $request->quizId)
->where('user_id', $request->participant)->get();
$result[] = "<option>" . get_phrase('Select an option') . "</option>";
foreach ($submissions as $key => $submission) {
$result[] = "<option value=" . $submission->id . ">Attempt " . ++$key . "</option>";
}
return $result;
}
public function result_preview(Request $request)
{
$page_data['quiz'] = Lesson::where('id', $request->quizId)->first();
$page_data['results'] = QuizSubmission::where('quiz_id', $request->quizId)->where('user_id', $request->participantId)->get();
$page_data['questions'] = Question::where('quiz_id', $request->quizId)->get();
return view('instructor.quiz_result.preview', $page_data);
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Course;
use App\Models\Payment_history;
use Illuminate\Http\Request;
class SalesReportController extends Controller
{
public function index(Request $request)
{
$start_date = strtotime('first day of this month');
$end_date = strtotime('last day of this month');
if (request()->has('eDateRange')) {
// modify date and prepare to compare with database
$date = explode('-', urldecode(request()->query('eDateRange')));
$start_date = strtotime($date[0] . ' 00:00:00');
$end_date = strtotime($date[1] . ' 23:59:59');
}
$query = Payment_history::join('courses', 'payment_histories.course_id', 'courses.id')
->join('users', 'payment_histories.user_id', 'users.id')
->select(
'payment_histories.*',
'courses.title as course_title',
'courses.slug as course_slug',
'courses.user_id as instructor_id',
'users.name as student_name'
)
->where('courses.user_id', auth()->user()->id)
->where('payment_histories.created_at', '>=', date('Y-m-d H:i:s', $start_date))
->where('payment_histories.created_at', '<=', date('Y-m-d H:i:s', $end_date));
$page_data['start_date'] = $start_date;
$page_data['end_date'] = $end_date;
$page_data['sales_report'] = $query->paginate(10)->appends($request->query());
return view('instructor.sales_report.index', $page_data);
}
}

View File

@ -0,0 +1,69 @@
<?php
namespace App\Http\Controllers\instructor;
use App\Http\Controllers\Controller;
use App\Models\Section;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class SectionController extends Controller
{
public function store(Request $request)
{
$request->validate([
'title' => 'required',
]);
// check duplicate
if (Section::where('course_id', $request->course_id)->where('title', $request->title)->exists()) {
Session::flash('error', get_phrase('Section already exists.'));
return redirect()->back();
}
// insert section
$section = new Section();
$section->title = $request->title;
$section->user_id = auth()->user()->id;
$section->course_id = $request->course_id;
$done = $section->save();
// redirect back
Session::flash('success', get_phrase('Section added successfully'));
return redirect()->back();
}
public function update(Request $request)
{
// check duplicate
if (Section::where('title', $request->title)->exists()) {
Session::flash('error', get_phrase('Section already exists.'));
return redirect()->back();
}
// update data
Section::where('id', $request->section_id)->update(['title' => $request->up_title]);
// redirect back
Session::flash('success', get_phrase('update successfully'));
return redirect()->back();
}
public function delete($id)
{
Section::where('id', $id)->delete();
Session::flash('success', get_phrase('Delete successfully'));
return redirect()->back();
}
public function sort(Request $request)
{
$sections = json_decode($request->itemJSON);
foreach ($sections as $key => $value) {
$updater = $key + 1;
Section::where('id', $value)->update(['sort' => $updater]);
}
}
}

Some files were not shown because too many files have changed in this diff Show More