Showing preview only (949K chars total). Download the full file or copy to clipboard to get everything.
Repository: mshossain110/examinee
Branch: main
Commit: 0852f4cbec3e
Files: 328
Total size: 862.0 KB
Directory structure:
gitextract__3ge5ty2/
├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .github/
│ └── workflows/
│ └── laravel.yml
├── .gitignore
├── .styleci.yml
├── CHANGELOG.md
├── DOCKER.md
├── Dockerfile
├── Makefile
├── README.md
├── app/
│ ├── Actions/
│ │ ├── CourseWithSections.php
│ │ ├── GetEnrolledCousesAction.php
│ │ └── GetInstratorCousesAction.php
│ ├── Enums/
│ │ ├── Attributes/
│ │ │ └── Description.php
│ │ ├── PermissionsEnum.php
│ │ ├── StatusesEnum.php
│ │ └── Traits/
│ │ ├── AsSelectArray.php
│ │ ├── EnumToArray.php
│ │ └── GetsAttributes.php
│ ├── Events/
│ │ └── ExamCreated.php
│ ├── Exceptions/
│ │ ├── Handler.php
│ │ └── SocialProviderDeniedException.php
│ ├── Helpers/
│ │ └── Functions/
│ │ └── core.php
│ ├── Http/
│ │ ├── Controllers/
│ │ │ ├── API/
│ │ │ │ ├── FileController.php
│ │ │ │ ├── MyCourseController.php
│ │ │ │ ├── SectionableController.php
│ │ │ │ └── TakeExamController.php
│ │ │ ├── Admin/
│ │ │ │ ├── CourseStudentController.php
│ │ │ │ ├── CoursesController.php
│ │ │ │ ├── DashboardController.php
│ │ │ │ ├── ExamController.php
│ │ │ │ ├── LessonController.php
│ │ │ │ ├── QuestionController.php
│ │ │ │ ├── RolesController.php
│ │ │ │ ├── SectionController.php
│ │ │ │ ├── ServerInfoController.php
│ │ │ │ ├── SubjectController.php
│ │ │ │ ├── TopicsController.php
│ │ │ │ └── UsersController.php
│ │ │ ├── Auth/
│ │ │ │ ├── AuthenticatedSessionController.php
│ │ │ │ ├── ConfirmablePasswordController.php
│ │ │ │ ├── EmailVerificationNotificationController.php
│ │ │ │ ├── EmailVerificationPromptController.php
│ │ │ │ ├── NewPasswordController.php
│ │ │ │ ├── PasswordController.php
│ │ │ │ ├── PasswordResetLinkController.php
│ │ │ │ ├── RegisteredUserController.php
│ │ │ │ ├── SocialiteController.php
│ │ │ │ └── VerifyEmailController.php
│ │ │ ├── Controller.php
│ │ │ ├── CourseController.php
│ │ │ ├── DownloadController.php
│ │ │ ├── HomeController.php
│ │ │ ├── InstructorController.php
│ │ │ ├── LearningController.php
│ │ │ ├── ProfileController.php
│ │ │ └── UploadController.php
│ │ ├── Middleware/
│ │ │ └── HandleInertiaRequests.php
│ │ ├── Requests/
│ │ │ ├── Admin/
│ │ │ │ ├── StoreCoursesRequest.php
│ │ │ │ ├── UpdateCoursesRequest.php
│ │ │ │ └── UserRequest.php
│ │ │ ├── Auth/
│ │ │ │ └── LoginRequest.php
│ │ │ ├── ExamRequest.php
│ │ │ ├── ProfileUpdateRequest.php
│ │ │ ├── QuestionRequest.php
│ │ │ ├── SettingRequest.php
│ │ │ ├── SubjectRequest.php
│ │ │ └── TopicRequest.php
│ │ └── Resources/
│ │ ├── CourseResource.php
│ │ ├── CourseStudentsResource.php
│ │ ├── ExamResource.php
│ │ ├── FileResource.php
│ │ ├── LessonResource.php
│ │ ├── QuestionResource.php
│ │ ├── ResultResource.php
│ │ ├── RoleResource.php
│ │ ├── SectionResource.php
│ │ ├── SubjectResource.php
│ │ ├── TopicResource.php
│ │ └── UserResource.php
│ ├── Jobs/
│ │ ├── ResizedImage.php
│ │ └── UploadToCloud.php
│ ├── Models/
│ │ ├── Course.php
│ │ ├── Exam.php
│ │ ├── File.php
│ │ ├── Lesson.php
│ │ ├── Question.php
│ │ ├── Result.php
│ │ ├── Role.php
│ │ ├── Section.php
│ │ ├── Sectionable.php
│ │ ├── Setting.php
│ │ ├── SocialiteProvider.php
│ │ ├── Subject.php
│ │ ├── Topic.php
│ │ ├── Traits/
│ │ │ ├── FileStorage.php
│ │ │ ├── Fileable.php
│ │ │ ├── HashesId.php
│ │ │ └── Topicable.php
│ │ └── User.php
│ ├── Observers/
│ │ └── FileObserver.php
│ ├── Pivots/
│ │ └── StudentCasting.php
│ ├── Policies/
│ │ ├── CoursePolicy.php
│ │ ├── ExamPolicy.php
│ │ ├── RolePolicy.php
│ │ ├── SubjectPolicy.php
│ │ ├── TopicPolicy.php
│ │ └── UserPolicy.php
│ ├── Providers/
│ │ └── AppServiceProvider.php
│ ├── Response/
│ │ ├── AudioVideoResponse.php
│ │ ├── DownloadResponse.php
│ │ ├── FileBuilder.php
│ │ ├── FileContentResponseCreator.php
│ │ └── ImageResponse.php
│ └── Traits/
│ ├── AppSettingsTrait.php
│ └── SocialiteProvidersTrait.php
├── artisan
├── bootstrap/
│ ├── app.php
│ ├── cache/
│ │ └── .gitignore
│ └── providers.php
├── composer.json
├── config/
│ ├── app.php
│ ├── auth.php
│ ├── cache.php
│ ├── database.php
│ ├── filesystems.php
│ ├── logging.php
│ ├── mail.php
│ ├── permission.php
│ ├── queue.php
│ ├── services.php
│ └── session.php
├── database/
│ ├── .gitignore
│ ├── factories/
│ │ ├── CourseFactory.php
│ │ ├── ExamFactory.php
│ │ ├── LessonFactory.php
│ │ ├── QuestionFactory.php
│ │ ├── SectionFactory.php
│ │ ├── SubjectFactory.php
│ │ ├── TopicFactory.php
│ │ └── UserFactory.php
│ ├── migrations/
│ │ ├── 0001_01_01_000000_create_users_table.php
│ │ ├── 0001_01_01_000001_create_cache_table.php
│ │ ├── 0001_01_01_000002_create_jobs_table.php
│ │ ├── 2024_05_07_000001_create_personal_access_tokens_table.php
│ │ ├── 2024_05_07_054845_create_files_table.php
│ │ ├── 2024_05_07_054954_create_fileables_table.php
│ │ ├── 2024_05_07_092254_create_settings_table.php
│ │ ├── 2024_05_07_112940_create_permission_tables.php
│ │ ├── 2024_05_07_142204_create_sections_table.php
│ │ ├── 2024_05_07_145026_create_subjects_table.php
│ │ ├── 2024_05_07_152004_create_sectionables_table.php
│ │ ├── 2024_05_07_153027_create_exams_table.php
│ │ ├── 2024_05_07_153507_create_questions_table.php
│ │ ├── 2024_05_07_170835_create_topics_table.php
│ │ ├── 2024_05_07_180360_create_topicables_table.php
│ │ ├── 2024_05_07_190045_create_results_table.php
│ │ ├── 2024_05_07_191956_create_courses_table.php
│ │ ├── 2024_05_07_193251_create_lessons_table.php
│ │ ├── 2024_05_07_195152_create_subjectables_table.php
│ │ ├── 2024_05_07_200921_create_course_students_table.php
│ │ ├── 2024_05_07_201001_create_course_teachers_table.php
│ │ ├── 2024_05_07_203101_create_lesson_student_table.php
│ │ ├── 2024_07_23_104822_store_last_learning.php
│ │ ├── 2024_08_13_073632_create_socialite_providers_table.php
│ │ └── 2026_04_25_000001_add_icon_and_image_to_subjects_table.php
│ └── seeders/
│ ├── CourseSeed.php
│ ├── DatabaseSeeder.php
│ ├── RoleSeed.php
│ ├── SubjectSeed.php
│ ├── TopicSeed.php
│ └── UserSeed.php
├── docker/
│ ├── nginx/
│ │ └── default.conf
│ └── php/
│ └── local.ini
├── docker-compose.yml
├── package.json
├── phpstan.neon
├── phpunit.xml
├── postcss.config.js
├── public/
│ ├── .htaccess
│ ├── index.php
│ └── robots.txt
├── resources/
│ ├── css/
│ │ └── app.css
│ ├── js/
│ │ ├── Components/
│ │ │ ├── ApplicationLogo.vue
│ │ │ ├── Breadcrumb.vue
│ │ │ ├── Button.vue
│ │ │ ├── Card.vue
│ │ │ ├── Checkbox.vue
│ │ │ ├── CircleSvg.vue
│ │ │ ├── Datatable/
│ │ │ │ └── Table.vue
│ │ │ ├── Dropdown.vue
│ │ │ ├── DropdownLink.vue
│ │ │ ├── Form/
│ │ │ │ ├── Checkbox.vue
│ │ │ │ ├── HeroiconPicker.vue
│ │ │ │ ├── Input.vue
│ │ │ │ ├── Label.vue
│ │ │ │ ├── Listbox.examplevue
│ │ │ │ └── Select.vue
│ │ │ ├── Icon.vue
│ │ │ ├── Icons/
│ │ │ │ ├── LoadingIcon.vue
│ │ │ │ └── index.ts
│ │ │ ├── Modal.vue
│ │ │ ├── NavLink.vue
│ │ │ ├── Pagination.vue
│ │ │ ├── ResponsiveNavLink.vue
│ │ │ ├── SocialiteLogins.vue
│ │ │ └── Tabs.vue
│ │ ├── Composables/
│ │ │ ├── analytics.js
│ │ │ ├── common.js
│ │ │ ├── useAuth.ts
│ │ │ ├── useButtonGroup.ts
│ │ │ ├── useFormGroup.ts
│ │ │ ├── useSidebarState.ts
│ │ │ ├── useUI.ts
│ │ │ └── utils.ts
│ │ ├── Elements/
│ │ │ ├── Course.vue
│ │ │ ├── Description.vue
│ │ │ ├── Lesson/
│ │ │ │ ├── Question.vue
│ │ │ │ ├── Session.vue
│ │ │ │ ├── SingleExam.vue
│ │ │ │ ├── SingleLesson.vue
│ │ │ │ └── SingleResource.vue
│ │ │ ├── admin/
│ │ │ │ ├── AdminFooter.vue
│ │ │ │ ├── AdminNavBar.vue
│ │ │ │ ├── AdminSidebar.vue
│ │ │ │ └── GHButtons.vue
│ │ │ ├── course/
│ │ │ │ ├── CourseForm.vue
│ │ │ │ ├── CourseLayout.vue
│ │ │ │ ├── Exam.vue
│ │ │ │ ├── Lesson.vue
│ │ │ │ ├── LessonForm.vue
│ │ │ │ ├── SectionForm.vue
│ │ │ │ └── SingleSection.vue
│ │ │ ├── exam/
│ │ │ │ ├── CreateExam.vue
│ │ │ │ ├── CreateQuestion.vue
│ │ │ │ ├── ExamLayout.vue
│ │ │ │ └── QuestionTable.vue
│ │ │ └── roles/
│ │ │ └── RolesBadges.vue
│ │ ├── Layouts/
│ │ │ ├── AdminLayout.vue
│ │ │ ├── AuthenticatedLayout.vue
│ │ │ ├── GuestLayout.vue
│ │ │ └── MainLayout.vue
│ │ ├── Pages/
│ │ │ ├── Auth/
│ │ │ │ ├── ConfirmPassword.vue
│ │ │ │ ├── ForgotPassword.vue
│ │ │ │ ├── Login.vue
│ │ │ │ ├── Register.vue
│ │ │ │ ├── ResetPassword.vue
│ │ │ │ └── VerifyEmail.vue
│ │ │ ├── Course/
│ │ │ │ ├── Course.vue
│ │ │ │ └── Partials/
│ │ │ │ ├── Instractor.vue
│ │ │ │ └── Pricing.vue
│ │ │ ├── Home/
│ │ │ │ ├── Home.vue
│ │ │ │ └── Slider.vue
│ │ │ ├── Instructor/
│ │ │ │ └── Courses.vue
│ │ │ ├── Learning/
│ │ │ │ ├── Courses.vue
│ │ │ │ └── SingleResource.vue
│ │ │ ├── Profile/
│ │ │ │ ├── Edit.vue
│ │ │ │ └── Partials/
│ │ │ │ ├── DeleteUserForm.vue
│ │ │ │ ├── UpdatePasswordForm.vue
│ │ │ │ └── UpdateProfileInformationForm.vue
│ │ │ └── admin/
│ │ │ ├── Dashboard.vue
│ │ │ ├── ServerInfo.vue
│ │ │ ├── courses/
│ │ │ │ ├── CourseStudent.vue
│ │ │ │ ├── CreateCourse.vue
│ │ │ │ ├── Index.vue
│ │ │ │ └── Sections.vue
│ │ │ ├── exams/
│ │ │ │ ├── Create.vue
│ │ │ │ ├── CreateQuestion.vue
│ │ │ │ ├── Edit.vue
│ │ │ │ ├── Index.vue
│ │ │ │ └── Questions.vue
│ │ │ ├── roles/
│ │ │ │ ├── Create.vue
│ │ │ │ ├── Edit.vue
│ │ │ │ └── Index.vue
│ │ │ ├── subjects/
│ │ │ │ ├── Create.vue
│ │ │ │ ├── Edit.vue
│ │ │ │ └── Index.vue
│ │ │ ├── topics/
│ │ │ │ ├── Create.vue
│ │ │ │ ├── Edit.vue
│ │ │ │ └── Index.vue
│ │ │ └── users/
│ │ │ ├── Create.vue
│ │ │ ├── Edit.vue
│ │ │ └── Index.vue
│ │ ├── app.ts
│ │ ├── bootstrap.ts
│ │ ├── types/
│ │ │ ├── forms.d.ts
│ │ │ ├── global.d.ts
│ │ │ ├── icons.d.ts
│ │ │ ├── index.d.ts
│ │ │ ├── resources.d.ts
│ │ │ ├── vite-env.d.ts
│ │ │ └── vuex.d.ts
│ │ └── ui.config/
│ │ ├── buttonGroup.ts
│ │ └── index.ts
│ └── views/
│ ├── app.blade.php
│ ├── errors/
│ │ ├── 401.blade.php
│ │ ├── 403.blade.php
│ │ ├── 500.blade.php
│ │ ├── 503.blade.php
│ │ └── layout.blade.php
│ └── socialite/
│ ├── callback.blade.php
│ └── denied.blade.php
├── routes/
│ ├── api.php
│ ├── auth.php
│ ├── console.php
│ └── web.php
├── storage/
│ ├── app/
│ │ └── .gitignore
│ ├── framework/
│ │ ├── .gitignore
│ │ ├── cache/
│ │ │ └── .gitignore
│ │ ├── sessions/
│ │ │ └── .gitignore
│ │ ├── testing/
│ │ │ └── .gitignore
│ │ └── views/
│ │ └── .gitignore
│ └── logs/
│ └── .gitignore
├── tailwind.config.js
├── tests/
│ ├── Feature/
│ │ ├── Auth/
│ │ │ ├── AuthenticationTest.php
│ │ │ ├── EmailVerificationTest.php
│ │ │ ├── PasswordConfirmationTest.php
│ │ │ ├── PasswordResetTest.php
│ │ │ ├── PasswordUpdateTest.php
│ │ │ └── RegistrationTest.php
│ │ ├── ExampleTest.php
│ │ ├── Http/
│ │ │ └── Controllers/
│ │ │ └── Admin/
│ │ │ └── UsersControllerTest.php
│ │ └── ProfileTest.php
│ ├── TestCase.php
│ └── Unit/
│ └── ExampleTest.php
├── tsconfig.json
└── vite.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
# Git
.git
.gitignore
.gitattributes
# Environment
.env
.env.*
!.env.example
# IDE
.idea
.vscode
*.sublime*
# OS
.DS_Store
Thumbs.db
# Build artifacts
node_modules
npm-debug.log
yarn-error.log
# Laravel
/vendor
/storage/*.key
/public/hot
/public/storage
/public/build
# Testing
/coverage
/.phpunit.result.cache
# Documentation
README.md
CHANGELOG.md
/doc
# Docker
docker-compose*.yml
Dockerfile
.dockerignore
================================================
FILE: .editorconfig
================================================
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
================================================
FILE: .gitattributes
================================================
* 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
================================================
FILE: .github/workflows/laravel.yml
================================================
name: Laravel
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
laravel-tests:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:latest
env:
MYSQL_DATABASE: posts-test
MYSQL_ROOT_PASSWORD: 123456
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping"
steps:
- uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e
with:
php-version: '8.2'
- uses: actions/checkout@v4
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: phpstan
run: ./vendor/bin/phpstan analyse --memory-limit=1G
- name: Create Database
run: |
mkdir -p database
touch database/database.sqlite
- name: Execute tests (Unit and Feature tests) via PHPUnit/Pest
env:
DB_CONNECTION: sqlite
DB_DATABASE: database/database.sqlite
run: php artisan test
================================================
FILE: .gitignore
================================================
/.phpunit.cache
/node_modules
/public/build
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.env.production
.phpunit.result.cache
Homestead.json
Homestead.yaml
auth.json
npm-debug.log
yarn-error.log
/.fleet
/.idea
/.vscode
/.composer
/.npm
/.config
.DS_Store
================================================
FILE: .styleci.yml
================================================
php:
preset: laravel
disabled:
- no_unused_imports
finder:
not-name:
- index.php
js: true
css: true
================================================
FILE: CHANGELOG.md
================================================
# Release Notes
## [Unreleased](https://github.com/laravel/laravel/compare/v11.0.7...11.x)
## [v11.0.7](https://github.com/laravel/laravel/compare/v11.0.6...v11.0.7) - 2024-05-03
* Remove obsolete driver option by [@u01jmg3](https://github.com/u01jmg3) in https://github.com/laravel/laravel/pull/6395
## [v11.0.6](https://github.com/laravel/laravel/compare/v11.0.5...v11.0.6) - 2024-04-09
* Fix PHPUnit constraint by [@szepeviktor](https://github.com/szepeviktor) in https://github.com/laravel/laravel/pull/6389
* [11.x] Add missing roundrobin transport driver config by [@u01jmg3](https://github.com/u01jmg3) in https://github.com/laravel/laravel/pull/6392
## [v11.0.5](https://github.com/laravel/laravel/compare/v11.0.4...v11.0.5) - 2024-03-26
* [11.x] Use PHPUnit v11 by [@philbates35](https://github.com/philbates35) in https://github.com/laravel/laravel/pull/6385
## [v11.0.4](https://github.com/laravel/laravel/compare/v11.0.3...v11.0.4) - 2024-03-15
* [11.x] Removed useless null parameter for env helper (cache.php) by [@siarheipashkevich](https://github.com/siarheipashkevich) in https://github.com/laravel/laravel/pull/6374
* [11.x] Removed useless null parameter for env helper (queue.php) by [@siarheipashkevich](https://github.com/siarheipashkevich) in https://github.com/laravel/laravel/pull/6373
* [11.x] Fix retry_after to be an integer by [@driesvints](https://github.com/driesvints) in https://github.com/laravel/laravel/pull/6377
* [11.x] Fix on hover animation and ring by [@michaelnabil230](https://github.com/michaelnabil230) in https://github.com/laravel/laravel/pull/6376
## [v11.0.3](https://github.com/laravel/laravel/compare/v11.0.2...v11.0.3) - 2024-03-14
* [11.x] Revert collation change by [@driesvints](https://github.com/driesvints) in https://github.com/laravel/laravel/pull/6372
## [v11.0.2](https://github.com/laravel/laravel/compare/v11.0.1...v11.0.2) - 2024-03-13
* [11.x] Remove branch alias from composer.json by [@zepfietje](https://github.com/zepfietje) in https://github.com/laravel/laravel/pull/6366
* [11.x] Fixes typo in welcome page by [@jrd-lewis](https://github.com/jrd-lewis) in https://github.com/laravel/laravel/pull/6363
* change mariadb default by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/laravel/commit/79969c99c6456a6d6edfbe78d241575fe1f65594
## [v11.0.1](https://github.com/laravel/laravel/compare/v11.0.0...v11.0.1) - 2024-03-12
* [11.x] Fixes SQLite driver missing by [@nunomaduro](https://github.com/nunomaduro) in https://github.com/laravel/laravel/pull/6361
## [v11.0.0 (2023-02-17)](https://github.com/laravel/laravel/compare/v10.3.2...v11.0.0)
Laravel 11 includes a variety of changes to the application skeleton. Please consult the diff to see what's new.
================================================
FILE: DOCKER.md
================================================
# Docker Setup for Examinee Application
## Quick Start
### 1. Build and start the containers
```bash
docker compose up -d
```
### 2. Install dependencies and build assets
```bash
# Install PHP dependencies (if not already done)
docker compose exec app composer install
# Install Node dependencies and build assets
docker compose run --rm node sh -c "npm install && npm run build"
# Or use the build profile
docker compose --profile build up node
```
### 3. Setup the application
```bash
# Copy environment file
cp .env.example .env
# Generate application key
docker compose exec app php artisan key:generate
# Run migrations
docker compose exec app php artisan migrate
# Run seeders (optional)
docker compose exec app php artisan db:seed
# Create storage link
docker compose exec app php artisan storage:link
# Clear and cache config
docker compose exec app php artisan config:cache
docker compose exec app php artisan route:cache
docker compose exec app php artisan view:cache
```
### 4. Access the application
- **Application**: http://localhost:8000
- **Database**: localhost:3307
- Database: examinee_db
- User: examinee_user
- Password: examinee_password
- Root Password: root_password
- **Redis**: localhost:6380
## Services
- **app**: PHP 8.2-FPM application container
- **nginx**: Nginx web server (port 8000)
- **db**: MySQL 8.0 database (port 3307)
- **redis**: Redis cache and queue backend (port 6380)
- **queue**: Laravel queue worker
- **node**: Node.js for asset compilation (run on-demand)
## Common Commands
### Container Management
```bash
# Start containers
docker compose up -d
# Stop containers
docker compose down
# View logs
docker compose logs -f
# View specific service logs
docker compose logs -f app
docker compose logs -f nginx
docker compose logs -f queue
# Restart a service
docker compose restart app
```
### Laravel Commands
```bash
# Run artisan commands
docker compose exec app php artisan [command]
# Access Laravel tinker
docker compose exec app php artisan tinker
# Clear caches
docker compose exec app php artisan cache:clear
docker compose exec app php artisan config:clear
docker compose exec app php artisan route:clear
docker compose exec app php artisan view:clear
# Run migrations
docker compose exec app php artisan migrate
docker compose exec app php artisan migrate:fresh --seed
```
### Asset Building
```bash
# Development build
docker compose run --rm node npm run dev
# Production build
docker compose run --rm node npm run build
# Watch mode (for development)
docker compose run --rm node npm run watch
```
### Database Access
```bash
# Access MySQL CLI
docker compose exec db mysql -u examinee_user -pexaminee_password examinee_db
# Import database
docker compose exec -T db mysql -u examinee_user -pexaminee_password examinee_db < backup.sql
# Export database
docker compose exec db mysqldump -u examinee_user -pexaminee_password examinee_db > backup.sql
```
### Queue Management
```bash
# View queue logs
docker compose logs -f queue
# Restart queue worker
docker compose restart queue
# Run queue manually (for testing)
docker compose exec app php artisan queue:work
```
### Shell Access
```bash
# Access app container shell
docker compose exec app bash
# Access as root
docker compose exec -u root app bash
```
## Environment Variables
Update your `.env` file with these Docker settings:
```env
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=examinee_db
DB_USERNAME=examinee_user
DB_PASSWORD=examinee_password
REDIS_HOST=redis
REDIS_PORT=6379
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
```
## Troubleshooting
### Permission Issues
```bash
# Fix storage permissions
docker compose exec -u root app chown -R www-data:www-data /var/www/html/storage
docker compose exec -u root app chmod -R 755 /var/www/html/storage
```
### Reset Everything
```bash
# Stop and remove containers, volumes
docker compose down -v
# Rebuild from scratch
docker compose build --no-cache
docker compose up -d
```
### Database Connection Issues
- Ensure the `db` service is running: `docker compose ps`
- Check database logs: `docker compose logs db`
- Verify credentials in `.env` match `docker-compose.yml`
## Production Considerations
1. **Change default passwords** in `docker-compose.yml`
2. **Use environment-specific files**: Create `docker-compose.prod.yml`
3. **Enable HTTPS**: Add SSL certificates and update nginx config
4. **Set proper APP_ENV**: Change to `production` in `.env`
5. **Disable debug mode**: Set `APP_DEBUG=false`
6. **Use proper storage**: Mount volumes for persistent data
7. **Implement backups**: Regular database and file backups
8. **Monitoring**: Add logging and monitoring solutions
## Development vs Production
For development with hot reload:
```bash
# Run Vite dev server on host machine
npm install
npm run dev
# Access via http://localhost:5173
```
Update `.env`:
```env
VITE_DEV_SERVER_URL=http://localhost:5173
```
================================================
FILE: Dockerfile
================================================
FROM php:8.3-fpm
# Set working directory
WORKDIR /var/www/html
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
libzip-dev \
libpq-dev \
zip \
unzip \
libfreetype6-dev \
libjpeg62-turbo-dev \
libwebp-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \
&& docker-php-ext-install pdo_mysql pdo_pgsql mbstring exif pcntl bcmath gd zip
# Install Redis extension
RUN pecl install redis && docker-php-ext-enable redis
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Copy application files
COPY . /var/www/html
# Copy php.ini configuration
RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
&& echo "upload_max_filesize = 50M" >> "$PHP_INI_DIR/php.ini" \
&& echo "post_max_size = 50M" >> "$PHP_INI_DIR/php.ini" \
&& echo "memory_limit = 512M" >> "$PHP_INI_DIR/php.ini"
# Expose port 9000 for PHP-FPM
EXPOSE 9000
CMD ["php-fpm"]
================================================
FILE: Makefile
================================================
.PHONY: help build up down restart logs shell composer artisan migrate fresh test clean
# Colors for output
BLUE=\033[0;34m
GREEN=\033[0;32m
RED=\033[0;31m
NC=\033[0m # No Color
help: ## Show this help message
@echo '${BLUE}Available commands:${NC}'
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " ${GREEN}%-15s${NC} %s\n", $$1, $$2}'
build: ## Build Docker containers
@echo "${BLUE}Building Docker containers...${NC}"
docker compose build
up: ## Start all containers
@echo "${BLUE}Starting containers...${NC}"
docker compose up -d
@echo "${GREEN}Containers started! Access the app at http://localhost:8000${NC}"
down: ## Stop all containers
@echo "${BLUE}Stopping containers...${NC}"
docker compose down
restart: ## Restart all containers
@echo "${BLUE}Restarting containers...${NC}"
docker compose restart
logs: ## Show logs from all containers
docker compose logs -f
logs-app: ## Show logs from app container
docker compose logs -f app
logs-queue: ## Show logs from queue container
docker compose logs -f queue
logs-nginx: ## Show logs from nginx container
docker compose logs -f nginx
shell: ## Access app container shell
docker compose exec app bash
shell-root: ## Access app container shell as root
docker compose exec -u root app bash
composer: ## Install PHP dependencies
@echo "${BLUE}Installing PHP dependencies...${NC}"
docker compose exec app composer install
npm: ## Install Node dependencies and build assets
@echo "${BLUE}Installing Node dependencies and building assets...${NC}"
docker compose run --rm node sh -c "npm install && npm run build"
npm-dev: ## Run Vite in development mode
@echo "${BLUE}Running Vite dev server...${NC}"
docker compose run --rm -p 5173:5173 node npm run dev
npm-watch: ## Build assets and watch for changes
@echo "${BLUE}Watching for asset changes...${NC}"
docker compose run --rm node npm run watch
artisan: ## Run artisan command (usage: make artisan cmd="migrate")
docker compose exec app php artisan $(cmd)
migrate: ## Run database migrations
@echo "${BLUE}Running migrations...${NC}"
docker compose exec app php artisan migrate
migrate-fresh: ## Fresh migration with seeding
@echo "${BLUE}Running fresh migrations with seeding...${NC}"
docker compose exec app php artisan migrate:fresh --seed
seed: ## Run database seeders
@echo "${BLUE}Running seeders...${NC}"
docker compose exec app php artisan db:seed
test: ## Run tests
@echo "${BLUE}Running tests...${NC}"
docker compose exec app php artisan test
tinker: ## Run Laravel tinker
docker compose exec app php artisan tinker
cache-clear: ## Clear all caches
@echo "${BLUE}Clearing caches...${NC}"
docker compose exec app php artisan cache:clear
docker compose exec app php artisan config:clear
docker compose exec app php artisan route:clear
docker compose exec app php artisan view:clear
cache: ## Cache config, routes, and views
@echo "${BLUE}Caching configuration...${NC}"
docker compose exec app php artisan config:cache
docker compose exec app php artisan route:cache
docker compose exec app php artisan view:cache
optimize: ## Optimize the application
@echo "${BLUE}Optimizing application...${NC}"
docker compose exec app php artisan optimize
queue-restart: ## Restart queue worker
@echo "${BLUE}Restarting queue worker...${NC}"
docker compose restart queue
db: ## Access MySQL CLI
docker compose exec db mysql -u examinee_user -pexaminee_password examinee_db
setup: ## Initial setup (for first time)
@echo "${BLUE}Setting up the application...${NC}"
@if [ ! -f .env ]; then \
cp .env.docker .env; \
echo "${GREEN}.env file created from .env.docker${NC}"; \
fi
@echo "${BLUE}Building containers...${NC}"
docker compose build
@echo "${BLUE}Starting containers...${NC}"
docker compose up -d
@echo "${BLUE}Installing dependencies...${NC}"
docker compose exec app composer install
@echo "${BLUE}Generating application key...${NC}"
docker compose exec app php artisan key:generate
@echo "${BLUE}Running migrations...${NC}"
docker compose exec app php artisan migrate
@echo "${BLUE}Creating storage link...${NC}"
docker compose exec app php artisan storage:link
@echo "${BLUE}Installing Node dependencies and building assets...${NC}"
docker compose run --rm node sh -c "npm install && npm run build"
@echo "${GREEN}Setup complete! Access the app at http://localhost:8000${NC}"
clean: ## Remove all containers, volumes, and images
@echo "${RED}Removing all containers, volumes, and images...${NC}"
docker compose down -v
docker system prune -f
fix-permissions: ## Fix storage permissions
@echo "${BLUE}Fixing permissions...${NC}"
docker compose exec -u root app chown -R www-data:www-data /var/www/html/storage
docker compose exec -u root app chown -R www-data:www-data /var/www/html/bootstrap/cache
docker compose exec -u root app chmod -R 755 /var/www/html/storage
docker compose exec -u root app chmod -R 755 /var/www/html/bootstrap/cache
status: ## Show status of all containers
docker compose ps
================================================
FILE: README.md
================================================
# examinee on Online exam system
“examinee” is a platform for Schools, Colleges, Institute & Coaching Centers. With the help of this platform, you can take Online-Offline Course, Lesson, Exams, Quiz, Test, Quiz Competition, Challenges etc
# Key Features
- Course and lesson
- Scholar and student mangement
- Course enrollment
- Quiz and Exam System
- File Management
- Login System
- Secure login and change password
- Bootstrap 4 Framework
- Cross Browser Compatible
- Unique and Exclusive Idea
- Unique and Creative Project
- Clean Code and Clean Design
- Easy To Customize
## Requirements
------------
- PHP >= 7.3.0
- Laravel => 7.5.0
- Fileinfo PHP Extension
## How to install
-------------
1. Clone the repo ```git clone https://github.com/mshossain110/examinee.git```
2. Move Directory ```cd examinee```
3. Install composer ```composer install```
4. Copy .env file ```cp .env.example .env```
5. Generate key ```php artisan key:generate```
6. Create database and edit ```.env``` file to add database, MAIL_DRIVER
7. Dont forget to edit APP_URL (required to assest compile ) and SANCTUM_STATEFUL_DOMAINS (For API Authentication)
8. Migrate database ```php artisan migrate:fresh --seed```
9. Install npm ```npm i```
10. Watch file ```npm run watch```
## Screen Shorts
---



================================================
FILE: app/Actions/CourseWithSections.php
================================================
<?php
namespace App\Actions;
use App\Http\Resources\CourseResource;
use App\Models\Course;
use App\Models\Section;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Collection;
class CourseWithSections
{
public static function getCourses(Course $course)
{
return Cache::remember('courseforStudent-' . $course->id, now()->addDays(1), function()use ($course) {
$course->load(['sections.lessons', 'sections.exams']);
$course->sections->map( function(Section $section) {
$resources = new Collection([]);
$section->lessons->each(function($lesson) use($resources) {
$resources->push($lesson);
});
$section->exams->each(function($exam) use($resources) {
$resources->push($exam);
});
$resources->sortBy('pivot.order');
$section->resources = $resources;
unset($section->lessons);
unset($section->exams);
return $section;
});
return new CourseResource($course);
});
}
}
================================================
FILE: app/Actions/GetEnrolledCousesAction.php
================================================
<?php
namespace App\Actions;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
class GetEnrolledCousesAction
{
public static function getCourses(User $student, bool $pagination = false):LengthAwarePaginator | Collection
{
if ($pagination) {
return $student->enrolledCourses()->paginate();
}
return $student->enrolledCourses;
}
}
================================================
FILE: app/Actions/GetInstratorCousesAction.php
================================================
<?php
namespace App\Actions;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
class GetInstratorCousesAction
{
public static function getCourses(User $instraotor, bool $pagination = false):LengthAwarePaginator | Collection
{
if ($pagination) {
return $instraotor->instructCourses()->paginate();
}
return $instraotor->instructCourses;
}
}
================================================
FILE: app/Enums/Attributes/Description.php
================================================
<?php
namespace App\Domain\Common\Enums\Attributes;
use Attribute;
#[Attribute]
class Description
{
public function __construct(
public string $description,
) {
//
}
}
================================================
FILE: app/Enums/PermissionsEnum.php
================================================
<?php
namespace App\Enums;
enum PermissionsEnum
{
//
}
================================================
FILE: app/Enums/StatusesEnum.php
================================================
<?php
namespace App\Domain\Common\Enums;
use App\Domain\Common\Enums\Traits\EnumToArray;
enum StatusesEnum: string
{
use EnumToArray;
case DISABLED = 'disabled';
case ENABLED = 'enabled';
public static function localizedList(): array
{
$result = [];
foreach (self::values() as $value) {
$result[$value] = __('statuses.'.$value);
}
return $result;
}
}
================================================
FILE: app/Enums/Traits/AsSelectArray.php
================================================
<?php
namespace App\Domain\Common\Enums\Traits;
trait AsSelectArray
{
/**
* @return array<string,string>
*/
public static function asSelectArray(): array
{
/** @var array<string,string> $values */
$values = collect(self::cases())
->map(function ($enum) {
return [
'name' => self::getDescription($enum),
'value' => $enum->value,
];
})->toArray();
return $values;
}
}
================================================
FILE: app/Enums/Traits/EnumToArray.php
================================================
<?php
namespace App\Domain\Common\Enums\Traits;
trait EnumToArray
{
public static function names(): array
{
return array_column(self::cases(), 'name');
}
public static function values(): array
{
return array_column(self::cases(), 'value');
}
public static function array(): array
{
return array_combine(self::names(), self::values());
}
}
================================================
FILE: app/Enums/Traits/GetsAttributes.php
================================================
<?php
namespace App\Domain\Common\Enums\Traits;
use App\Domain\Common\Enums\Attributes\Description;
use Illuminate\Support\Str;
use ReflectionClassConstant;
trait GetsAttributes
{
private static function getDescription(self $enum): string
{
$ref = new ReflectionClassConstant(self::class, $enum->name);
$classAttributes = $ref->getAttributes(Description::class);
if (count($classAttributes) === 0) {
return Str::headline($enum->value);
}
return $classAttributes[0]->newInstance()->description;
}
public function description(): string
{
return self::getDescription($this);
}
}
================================================
FILE: app/Events/ExamCreated.php
================================================
<?php
namespace App\Events;
use App\Models\Exam;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class ExamCreated implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $exam;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Exam $exam)
{
$this->exam = $exam;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('exams');
}
}
================================================
FILE: app/Exceptions/Handler.php
================================================
<?php
namespace App\Exceptions;
use App\Mail\ExceptionOccured;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use Mail;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array<int, string|null>
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array<int, string>
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->reportable(function (Throwable $e) {
$this->sendEmail($e);
if (app()->bound('sentry') && config('services.sentry.enabled')) {
app('sentry')->captureException($e);
}
});
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $e
* @return \Illuminate\Http\Response
*/
public function render($request, Throwable $e)
{
$userLevelCheck = $e instanceof \jeremykenedy\LaravelRoles\App\Exceptions\RoleDeniedException ||
$e instanceof \jeremykenedy\LaravelRoles\App\Exceptions\PermissionDeniedException ||
$e instanceof \jeremykenedy\LaravelRoles\App\Exceptions\LevelDeniedException;
if ($userLevelCheck) {
if ($request->expectsJson()) {
return Response::json([
'error' => 403,
'message' => 'Unauthorized.',
], 403);
}
abort(403);
}
return parent::render($request, $e);
}
/**
* Sends an email upon exception.
*
* @param \Throwable $exception
* @return void
*/
public function sendEmail(Throwable $exception)
{
try {
$content['message'] = $exception->getMessage();
$content['file'] = $exception->getFile();
$content['line'] = $exception->getLine();
$content['trace'] = $exception->getTrace();
$content['url'] = request()->url();
$content['body'] = request()->all();
$content['ip'] = request()->ip();
Mail::send(new ExceptionOccured($content));
} catch (Throwable $exception) {
Log::error($exception);
}
}
}
================================================
FILE: app/Exceptions/SocialProviderDeniedException.php
================================================
<?php
namespace App\Exceptions;
use Exception;
class SocialProviderDeniedException extends Exception
{
/**
* Render the exception as an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function render($request)
{
return response()->view('socialite.denied', [], 401);
}
}
================================================
FILE: app/Helpers/Functions/core.php
================================================
<?php
/**
* Get either a Gravatar URL or complete image tag for a specified email address.
*
* @param string $email The email address
* @param string $s Size in pixels, defaults to 80px [ 1 - 2048 ]
* @param string $d Default imageset to use [ 404 | mp | identicon | monsterid | wavatar ]
* @param string $r Maximum rating (inclusive) [ g | pg | r | x ]
* @param boole $img True to return a complete IMG tag False for just the URL
* @param array $atts Optional, additional key/value attributes to include in the IMG tag
* @return String containing either just a URL or a complete image tag
* @source https://gravatar.com/site/implement/images/php/
*/
function get_gravatar( $email, $s = 40, $d = 'mp', $r = 'g', $img = false, $atts = array() ) {
$url = 'https://www.gravatar.com/avatar/';
$url .= md5( strtolower( trim( $email ) ) );
$url .= "?s=$s&d=$d&r=$r";
if ( $img ) {
$url = '<img src="' . $url . '"';
foreach ( $atts as $key => $val )
$url .= ' ' . $key . '="' . $val . '"';
$url .= ' />';
}
return $url;
}
================================================
FILE: app/Http/Controllers/API/FileController.php
================================================
<?php
namespace App\Http\Controllers\API;
use App\Models\File;
use App\Http\Controllers\Controller;
use App\Jobs\UploadToCloud;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Auth;
use Intervention\Image\Facades\Image;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\File as FileAdapdar;
use Illuminate\Http\Resources\Json\JsonResource;
use Pion\Laravel\ChunkUpload\Receiver\FileReceiver;
use Pion\Laravel\ChunkUpload\Handler\HandlerFactory;
use Pion\Laravel\ChunkUpload\Handler\AbstractHandler;
use Pion\Laravel\ChunkUpload\Exceptions\UploadMissingFileException;
class FileController extends Controller
{
public function index(Request $request)
{
$user = $request->user();
$perpage = $request->get('per_page') ?: 30;
$type = $request->get('type');
$search = $request->get('search');
$files = File::with('uploader')->where('uploaded_by', $user->id);
if ($type) {
$files = $files->where('type', $type);
}
if ($search) {
$files = $files->where('name', 'like', "%$search%");
}
$files = $files->paginate($perpage);
$resource = JsonResource::collection($files);
return $resource;
}
public function show(Request $request, File $file)
{
$with = ['uploader'];
$file->load($with);
$resource = New JsonResource($file);
return $resource;
}
/**
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\UserRequest $request
*
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->input('file_name', $request->get('dzuuid'));
$inputs = $request->all();
$inputs['meta']['sizes'] = $this->getDefaultSizes();
$inputs['meta']['permissions'] = $this->getFilePermissions($request);
$chunkupload = true;
if ($chunkupload) {
// create the file receiver
$receiver = new FileReceiver('file', $request, HandlerFactory::classFromRequest($request));
// check if the upload is success, throw exception or return response you need
if ($receiver->isUploaded() === false) {
throw new UploadMissingFileException();
}
// receive the file
$save = $receiver->receive();
// check if the upload has finished (in chunk mode it will send smaller files)
if ($save->isFinished()) {
// save the file and return any response you need, current example uses `move` function. If you are
// not using move, you need to manually delete the file by unlink($save->getFile()->getPathname())
$filedata = $this->getFileData($save->getFile(), $inputs);
$fileEntry = File::create($filedata);
$this->storeLocalUpload($fileEntry, $save->getFile());
// $this->file->resizeImage($fileEntry, $save->getFile());
// UploadToCloud::dispatch($fileEntry)->delay(now()->addMinutes(10)); // fire resize event and uplad to cloud
$resource = new JsonResource($fileEntry);
return $resource;
}
// we are in chunk mode, lets send the current progress
/** @var AbstractHandler $handler */
$handler = $save->handler();
return response()->json([
'done' => $handler->getPercentageDone(),
'status' => true,
]);
}
// $fileEntry = $this->file->createFile($uploadedFile, ['parent_id' => $parent_id, 'path' => $path] );
// $this->file->storePrivateUpload($fileEntry, $uploadedFile);
// return $this->respondWithItem($fileEntry, new FileTransformer);
}
/**
* Update the specified resource in storage.
*
* @param $request
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$user = $request->user();
$data = $request->only(['name', 'description']);
$file = File::findOrFail($id);
// not file owner
if ($file->uploaded_by != $user->id) {
return $this->errorUnauthorized('Unauthorized', ["You can\'t Update the file details."]);
}
$file->fill($data);
$file->save();
$resource = new JsonResource($file);
return $resource;
}
/**
* Remove the specified resource from storage.
*
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request, $id)
{
$user = $request->user();
$file = File::findOrFail($id);
// not file owner
if ($file->uploaded_by != $user->id) {
return $this->errorUnauthorized('Unauthorized', ["You can\'t Delete the file."]);
}
$file->delete();
return $this->respondWithMessage('file deleted successfully.');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function destroyAll(Request $request)
{
$user = $request->user();
$ids = $request->get('ids');
File::whereIn('id', $ids)->where('uploaded_by', $user->id)->delete();
return $this->respondWithMessage('file deleted successfully.');
}
protected function getFilePermissions(Request $request)
{
return [
'public' => true,
];
}
protected function getDefaultSizes() {
return [
'120x80' => false
];
}
/**
* @param UploadedFile $file
* @param array $extra
*
* @return array
*/
public function getFileData(UploadedFile $file, $extra)
{
// TODO: move mime/extension/type guessing into separate class
$originalMime = $file->getMimeType();
if ($originalMime === 'application/octet-stream') {
$originalMime = $file->getClientMimeType();
}
$file_name = Arr::get($extra, 'file_name') ? Arr::get($extra, 'file_name') : Str::random(36);
$data = [
'name' => Arr::get($extra, 'name', $file->getClientOriginalName()),
'file_name' => $file_name,
'mime' => $originalMime,
'type' => $this->getTypeFromMime($originalMime),
'extension' => $this->getExtension($file, $originalMime),
'path' => Arr::get($extra, 'path'),
'parent_id' => Arr::get($extra, 'parent_id'),
'public_path' => Arr::get($extra, 'public_path'),
'uploaded_by' => Arr::get($extra, 'uploaded_by', Auth::id()),
'driver' => Arr::get($extra, 'driver', config('filesystems.default')),
'driver_data' => Arr::get($extra, 'driver_data'),
'meta' => Arr::get($extra, 'meta'),
];
return $data;
}
/**
* Extract file extension from specified file data.
*
* @param UploadedFile $file
* @param string $mime
*
* @return string
*/
private function getExtension(UploadedFile $file, $mime)
{
if ($extension = $file->getClientOriginalExtension()) {
return $extension;
}
$pathinfo = pathinfo($file->getClientOriginalName());
if (isset($pathinfo['extension'])) {
return $pathinfo['extension'];
}
return explode('/', $mime)[1];
}
/**
* Get type of file entry from specified mime.
*
* @param string $mime
*
* @return string
*/
protected function getTypeFromMime($mime)
{
$default = explode('/', $mime)[0];
switch ($mime) {
case 'application/x-zip-compressed':
case 'application/zip':
return 'archive';
case 'application/pdf':
return 'pdf';
case 'vnd.android.package-archive':
return 'android package';
case Str::contains($mime, 'xml'):
return 'spreadsheet';
default:
return $default === 'application' ? 'file' : $default;
}
}
public function createThumbanile (File $entry, UploadedFile $file, $size = '120x80') {
if ($entry->type !== 'image') return;
// Image not resized let resize it
$rs = explode('x', $size); // [150, 50]
// create Intervention images
$image = Image::make($file)->resize($rs[0], $rs[1]);
$path = storage_path("app/uploads/{$entry->file_name}");
$localFile = "{$path}/{$size}-{$entry->name}";
$image->save($localFile);
return $localFile;
}
/**
* @param FileEntry $entry
* @param UploadedFile $contents
*/
public function moveFile(file $entry, UploadedFile $file, $public = 'public', $disk = null, $file_name = null)
{
if (!$disk) {
$disk = config('filesystems.default');
}
if (!$file_name) {
$file_name = $entry->name;
}
Storage::disk($disk)->putFileAs($entry->file_name, $file, $file_name, $public);
$entry->updatePublicPaths($disk);
}
/**
* @param FileEntry $entry
* @param UploadedFile $contents
*/
public function storePublicUpload(File $entry, UploadedFile $file, $file_name = null)
{
$this->moveFile($entry, $file, 'public', 'public', $file_name);
}
/**
* @param FileEntry $entry
* @param UploadedFile $contents
*/
public function storeLocalUpload(File $entry, UploadedFile $file, $file_name = null)
{
$this->moveFile($entry, $file, 'public', 'local', $file_name);
}
}
================================================
FILE: app/Http/Controllers/API/MyCourseController.php
================================================
<?php
namespace App\Http\Controllers\API;
use App\Models\Course;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Http\Resources\Json\JsonResource;
class MyCourseController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$user = $request->user();
$courses = Course::withCount('lessons')->whereHas('students', function($query) use($user){
$query->where('user_id', $user->id);
})->get();
$collection = JsonResource::collection($courses);
return $collection->response();
}
/**
* Display the specified resource.
*
* @param \App\Course $course
* @return \Illuminate\Http\Response
*/
public function show(Request $request, Course $course)
{
$course->load([
'teachers'
]);
$resource = New JsonResource($course);
return $resource;
}
}
================================================
FILE: app/Http/Controllers/API/SectionableController.php
================================================
<?php
namespace App\Http\Controllers\API;
use App\Models\Course;
use App\Models\Sectionable;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Resources\Json\JsonResource;
class SectionableController extends Controller
{
public function lessons(Request $request, Course $course)
{
$hasVisibility = $this->hasVisibility($course);
$with = ['lessons', 'exams'];
if ($hasVisibility) {
$with[] = 'lessons.files';
}
$sections= Sectionable::with($with)->where('course_id', $course->id)->get();
$sections = $sections->map(function($s) use($hasVisibility) {
$exams = $s->exams;
$lessons = $s->lessons;
if ($hasVisibility) {
$lessons->makeVisible(['object', 'full_text']);
}
unset($s->exams);
unset($s->lessons);
$s->resources = $lessons->merge($exams);
return $s;
});
return JsonResource::collection($sections);
}
protected function hasVisibility (Course $course) {
if (!Auth::check()) {
return false;
}
$user = Auth::user();
if ($course->teachers->where('id', $user->id)->isEmpty()) {
return false;
}
return true;
}
}
================================================
FILE: app/Http/Controllers/API/TakeExamController.php
================================================
<?php
namespace App\Http\Controllers\API;
use App\Models\Exam;
use App\Models\User;
use App\Models\Result;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Support\Facades\Session;
class TakeExamController extends Controller
{
public function show(Request $request, Exam $exam)
{
$user = $request->user();
$questions= collect();
$time = Session::get("exam.$exam->id");
$exam->load('topics', 'subjects');
$result = $exam->results()->where('examinee', $user->id)->orderBy('created_at', "DESC")->first();
if ($result && !empty($exam->meta['show_answer']) && $exam->meta['show_answer']) {
$q = $exam->questions;
collect($result->answers)->map(function($qi) use($q, $questions){
$questions->push($q->firstWhere('id', $qi['id']));
});
// $questions = $questions->map(function($q) use($questionFields){
// return collect($q->toArray())->only($questionFields)->all();
// })->values()->all();
if (!(!empty($exam->meta['show_answer']) && $exam->meta['show_answer'])) {
$questions = $questions->map(function($ques) {
unset($ques->answers);
return $ques;
});
}
}
return response()->json(compact(['exam', 'time', 'result', 'questions']));
}
public function start (Request $request, Exam $exam)
{
$user = $request->user();
if (!$this->userCanTakeExam($user, $exam)) {
return;
}
$time = Session::get("exam.$exam->id");
if (!$time) {
$time = Session::put("exam.$exam->id", Carbon::now());
$time = Session::get("exam.$exam->id");
}
$answers = Session::get("exam_question");
$answers = collect($answers);
$questionFields = ['id', 'qtype', 'question', 'options' , 'mark', 'nmark'];
if (!empty($exam->meta['show_hint']) && $exam->meta['show_hint']) {
$questionFields[] = 'hint';
}
if ($answers->isEmpty()) {
$questions = $exam->questions->shuffle()->take($exam->number_of_questions)->map(function($q) use($answers, $questionFields){
$answers->push(['id'=> $q->id]);
return collect($q->toArray())->only($questionFields)->all();
})->values()->all(); //
Session::put("exam_question", $answers);
} else {
$q = $exam->questions;
$questions= collect();
$answers->map(function($qi) use($q, $questions){
$questions->push($q->firstWhere('id', $qi['id']));
});
$questions = $questions->map(function($q) use($questionFields){
return collect($q->toArray())->only($questionFields)->all();
})->values()->all();
}
return response()->json(compact('exam', 'time', 'questions', 'answers'));
}
public function answer(Request $request, Exam $exam)
{
$user = $request->user();
$time = Session::get("exam.$exam->id");
$answers = Session::get("exam_question");
$answers = collect($answers);
if ($time && Carbon::parse($time)->diffInMinutes(Carbon::now()) < $exam->duration ) {
if(sizeof($request->keys()) === 1) {
$key = $request->keys()[0];
$ans = $request->get($key, []);
if (!empty($ans)) {
$answers = $answers->map(function($q) use($ans, $key) {
if ($q['id'] === $key) {
$q['answer'] = $ans;
}
return $q;
});
Session::put("exam_question", $answers);
}
}
}
$answers = Session::get("exam_question");
return compact('answers', 'time');
}
public function complete(Request $request, Exam $exam)
{
$time = Session::get("exam.$exam->id");
$answers = Session::get("exam_question");
$answers = collect($answers);
$obtainMark = $this->obtain_mark($exam);
$timeTaken = Carbon::parse($time)->diffInMinutes(Carbon::now());
$user = $request->user();
$result = new Result;
$result->examinee = $user->id;
$result->exam_id = $exam->id;
$result->answers = $answers;
$result->time_taken = $timeTaken;
$result->obtain_mark = $obtainMark;
$result->is_pass = $exam->pass_mark < $obtainMark;
if ($result->save()) {
Session::forget("exam_question");
Session::forget("exam");
}
return response()->json(compact('result'));
}
private function obtain_mark(Exam $exam)
{
$number = 0;
$answers = Session::get("exam_question");
$answers = collect($answers);
$questions = $exam->questions;
$answers->each(function($ans) use($questions, &$number) {
if(!empty($ans['answer'])) {
$ques = $questions->firstWhere('id', $ans['id']);
$intersect = array_intersect($ques->answers, $ans['answer'] );
if (sizeof($intersect) === sizeof($ques->answers)) {
// answer is correct
$number += floatval($ques->mark);
} else {
$number -= floatval($ques->nmark);
}
}
});
return $number;
}
private function userCanTakeExam(User $user, Exam $exam)
{
$time = Session::get("exam");
if ($time && empty($time[$exam->id])){
throw new Exception(__("Exam id :key running", ["key" => array_keys($time)[0]]));
}
$result = $exam->results()->where('examinee', $user->id)->orderBy('created_at', "DESC")->first();
if ($result) {
$differ = ((intval($exam->meta['retake'])?: 0 )- Carbon::parse($result->created_at)->diffInDays(Carbon::now()) );
if ( $differ > 0){
throw new Exception(__("You can retry after :day days", ["day" => $differ]));
}
}
return true;
}
}
================================================
FILE: app/Http/Controllers/Admin/CourseStudentController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use Inertia\Inertia;
use App\Models\Course;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\CourseResource;
use App\Http\Resources\CourseStudentsResource;
class CourseStudentController extends Controller
{
public function __invoke(Course $course)
{
$students = $course->students;
return Inertia::render('admin/courses/CourseStudent', [
'course' => new CourseResource($course),
'students' => CourseStudentsResource::collection($students)
]);
}
}
================================================
FILE: app/Http/Controllers/Admin/CoursesController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use Inertia\Inertia;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\CourseResource;
use App\Models\Course;
class CoursesController extends Controller
{
public function __construct()
{
$this->authorizeResource(Course::class);
}
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$user = $request->user();
$courses = Course::query();
if(! $user->isAdmin() ) {
$courses = $courses->whereHas('teachers', function($q) use($user){
$q->where('id', $user->id);
});
}
$courses = $courses->paginate();
return Inertia::render(
'admin/courses/Index',
[
'response' => CourseResource::collection($courses),
]
);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return Inertia::render('admin/courses/CreateCourse');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$user = $request->user();
$data = $request->only(['title', 'subtitle', 'slug', 'description', 'price', 'discount', 'thumbnail', 'start_date', 'status', 'certified']);
$data['created_by'] = $user->id;
$data['updated_by'] = $user->id;
$course = $user->instructCourses()->create($data);
return to_route('admin.courses.edit', $course);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Course $course)
{
return Inertia::render('admin/courses/CreateCourse', [ 'course' => new CourseResource($course) ]);
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, course $course)
{
$user = $request->user();
$data = $request->all();
$data['updated_by'] = $user->id;
$course->update($data);
return to_route('admin.courses.edit', $course);
}
/**
* Remove the specified resource from storage.
*/
public function destroy(course $course)
{
$course->delete();
return to_route('admin.courses.index');
}
}
================================================
FILE: app/Http/Controllers/Admin/DashboardController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use Inertia\Inertia;
use App\Models\Subject;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\SubjectResource;
class DashboardController extends Controller
{
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function __invoke(Request $request)
{
return Inertia::render('admin/Dashboard');
}
}
================================================
FILE: app/Http/Controllers/Admin/ExamController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Exam;
use Inertia\Inertia;
use Illuminate\Http\Request;
use App\Http\Requests\ExamRequest;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use App\Http\Resources\ExamResource;
use Illuminate\Http\Resources\Json\JsonResource;
class ExamController extends Controller
{
public function __construct()
{
$this->authorizeResource(Exam::class);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$user = $request->user();
$courseId = $request->get('course_id');
return (Exam::select(['exams.*'])->addSelect(['users' => DB::table('users')->whereColumn('users.id', 'exams.examiner')->select('email')->limit(1)])->where('exams.id', 10)->get()->toArray());
$exams = Exam::with(['subjects', 'questions', 'topics']);
if ($courseId) {
$exams = $exams->whereHas('courses', function ($q) use ($courseId) {
$q->where('course_id', $courseId);
});
}
$exams = $exams->paginate();
$resource = ExamResource::collection($exams);
return Inertia::render(
'admin/exams/Index',
[
'response' => $resource
]
);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return Inertia::render('admin/exams/Create');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(ExamRequest $request)
{
$user = $request->user();
$subject_id = $request->input('subject_id');
$data = $request->all();
$data['examiner'] = $user->id;
$exam = Exam::create($data);
$topics = $request->get('topics');
if ($topics) {
$exam->topics()->attach($topics);
}
$exam->subjects()->attach($subject_id);
return to_route('admin.exams.edit', $exam);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Exam $exam)
{
return Inertia::render('admin/exams/Edit', ['exam' => new ExamResource($exam)]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Exam $exam
* @return \Illuminate\Http\Response
*/
public function update(ExamRequest $request, Exam $exam)
{
$exam->fill($request->all());
$exam->save();
$exam->subjects()->detach();
$exam->subjects()->attach($request->subject_id);
$topics = $request->get('topics');
if ($topics) {
$exam->topics()->attach($topics);
}
return to_route('admin.exams.edit', $exam);
}
/**
* Remove the specified resource from storage.
*
* @param \App\Exam $exam
* @return \Illuminate\Http\Response
*/
public function destroy(Exam $exam)
{
$exam->subjects()->detach();
$exam->questions()->delete();
$exam->topics()->detach();
$exam->delete();
return to_route('admin.exams.index');
}
}
================================================
FILE: app/Http/Controllers/Admin/LessonController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use Inertia\Inertia;
use App\Models\Course;
use App\Models\Lesson;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\CourseResource;
use App\Http\Resources\LessonResource;
class LessonController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request, Course $course)
{
$courseId = $request->get('course_id');
// $course = Course::find($courseId);
$lessons = $course->lessons()->orderBy('position')->get();
$resource = LessonResource::collection($lessons);
return Inertia::render(
'admin/courses/Lessons',
[
'course' => new CourseResource($course),
'response' => $resource,
]
);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return Inertia::render('admin/courses/CreateLesson');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request, Course $course)
{
$user = $request->user();
$courseId = $request->get('course_id');
$topics = $request->get('topics');
$data = $request->all();
$data['created_by'] = $user->id;
$data['updated_by'] = $user->id;
$lesson = Lesson::create($data);
if ($topics) {
$lesson->topics()->attach($topics);
}
if ($request->section) {
$lesson->sections()->attach($request->section, [
'course_id' => $courseId,
]);
$lesson->load(['sectionable']);
}
if ($request->has('object')) {
$lesson->setLessonObject();
}
return to_route('admin.lessons.edit', [$course, $lesson] );
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Course $course, Lesson $lesson)
{
return Inertia::render('admin/courses/CreateLesson', [
'course' => new CourseResource($course),
'lesson' => new LessonResource($$lesson)
]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Lesson $lesson
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Course $course, Lesson $lesson)
{
$courseId = $request->get('course_id');
$topics = $request->get('topics');
$lesson->update($request->all());
if ($topics) {
$lesson->topics()->attach($topics);
}
if ($request->section) {
$lesson->sections()->attach($request->section, [
'course_id' => $courseId,
]);
$lesson->load(['sectionable']);
}
if ($request->has('object')) {
$lesson->setLessonObject();
}
return to_route('admin.lessons.edit', [$course, $lesson] );
}
/**
* Remove the specified resource from storage.
*
* @param \App\Lesson $lesson
* @return \Illuminate\Http\Response
*/
public function destroy(Course $course, Lesson $lesson)
{
$lesson->delete();
return to_route('admin.lessons.index', [$course] );
}
}
================================================
FILE: app/Http/Controllers/Admin/QuestionController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Exam;
use Inertia\Inertia;
use App\Models\Question;
use App\Http\Controllers\Controller;
use App\Http\Resources\QuestionResource;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Requests\QuestionRequest as Request;
use App\Http\Resources\ExamResource;
class QuestionController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Exam $exam)
{
$questions = $exam->questions;
$resource = QuestionResource::collection($questions);
return Inertia::render(
'admin/exams/Questions',
[
'exam' => new ExamResource($exam),
'questions' => $resource
]
);
}
/**
* Show the form for creating a new resource.
*/
public function create(Exam $exam)
{
return Inertia::render('admin/exams/CreateQuestion', [
'exam' => new ExamResource($exam)
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request, Exam $exam)
{
$user = $request->user();
$question = $exam->questions()->create([
'created_by' => $user->id,
'qtype' => $request->qtype,
'question' => $request->question,
'options' => $request->options,
'answers' => $request->answers,
'hint' => $request->hint,
'mark' => $request->mark,
'nmark' => $request->nmark,
'explanation' => $request->explanation
]);
return to_route('admin.questions.edit', [$exam, $question]);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Exam $exam, Question $question)
{
return Inertia::render('admin/exams/CreateQuestion', [
'exam' => new ExamResource($exam),
'question' => new QuestionResource($question)
]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Question $question
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Exam $exam, Question $question)
{
$question->update( $request->all() );
$resource = New JsonResource($question);
return to_route('admin.questions.edit', [$exam, $question]);
}
/**
* Remove the specified resource from storage.
*
* @param \App\Question $question
* @return \Illuminate\Http\Response
*/
public function destroy(Exam $exam, Question $question)
{
$question->delete();
return to_route('admin.questions.index', [$exam]);
}
}
================================================
FILE: app/Http/Controllers/Admin/RolesController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Role;
use App\Models\User;
use Inertia\Inertia;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\RoleResource;
use Spatie\Permission\Models\Permission;
class RolesController extends Controller
{
public function __construct()
{
$this->authorizeResource(Role::class);
}
/**
* Display a listing of the resource.
*/
public function index()
{
return Inertia::render(
'admin/roles/Index',
[
'response' => RoleResource::collection(
Role::with('permissions')->withCount(['users', 'permissions'])->paginate()
),
'app_roles' => Role::appRoles()
]
);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return Inertia::render('admin/roles/Create', [
'permissions' => Permission::all(['id', 'name'])->toArray(),
]);
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string',
'permissions' => ['nullable', 'array'],
'permissions.*' => ['integer', 'exists:permissions,id'],
]);
$role = Role::create(['name' => $request->name]);
if ($request->filled('permissions')) {
$role->syncPermissions($request->permissions);
}
return to_route('admin.roles.edit', $role)
->with('success', "Role '{$role->name}' created successfully.");
}
/**
* Display the specified resource.
*/
public function show(User $user)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Role $role)
{
return Inertia::render('admin/roles/Edit', [
'role' => new RoleResource($role->load('permissions')),
'permissions' => Permission::all(['id', 'name'])->toArray(),
]);
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Role $role)
{
$request->validate([
'name' => 'required|string',
'permissions' => ['nullable', 'array'],
'permissions.*' => ['integer', 'exists:permissions,id'],
]);
$role->update(['name' => $request->name]);
$role->syncPermissions($request->permissions ?? []);
return to_route('admin.roles.edit', $role)
->with('success', "Role '{$role->name}' updated successfully.");
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Role $role)
{
if(collect([Role::SUPERADMIN, Role::ADMIN])->contains($role->name)){
// exception not possible
}
$role->delete();
return to_route('admin.roles.index');
}
}
================================================
FILE: app/Http/Controllers/Admin/SectionController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Exam;
use Inertia\Inertia;
use App\Models\Course;
use App\Models\Lesson;
use App\Models\Section;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\CourseResource;
use App\Http\Resources\SectionResource;
class SectionController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Course $course, Request $request)
{
$sections = $course->sections()->with(['lessons', 'exams'])->get();
return Inertia::render(
'admin/courses/Sections',
[
'course' => new CourseResource($course),
'sections' => SectionResource::collection($sections),
]
);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Course $course, Request $request)
{
$section = $course->sections()->create($request->all());
return to_route('admin.sections.index', $course);
}
/**
* Update the specified resource in storage.
*
* @param \App\Models\Section $section
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function update(Course $course, Section $section, Request $request)
{
$section->title = $request->title;
$section->description = $request->description;
$section->save();
return to_route('admin.sections.index', $course);
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Section $Section
* @return \Illuminate\Http\Response
*/
public function destroy(Course $course, Section $section)
{
$section->delete();
return to_route('admin.sections.index', $course);
}
public function attachExam (Request $request, Section $section) {
$exam = Exam::find($request->exam_id);
$section->exams()->attach($exam, ['course_id' => $section->course_id]);
return to_route('admin.sections.index', $section->course_id);
}
public function attachLession (Request $request, Section $section) {
$lesson = Lesson::find($request->lesson_id);
$section->lessons()->attach($lesson, ['course_id' => $section->course_id]);
return to_route('admin.sections.index', $section->course_id);
}
}
================================================
FILE: app/Http/Controllers/Admin/ServerInfoController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use Inertia\Inertia;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
class ServerInfoController extends Controller
{
public function __construct()
{
$this->middleware('auth');
// $this->middleware('role:super.admin');
try {
ob_start('ob_gzhandler');
} catch (\Exception $e) {
//
}
}
public function index(Request $request)
{
ob_start();
phpinfo();
$pinfo = ob_get_contents();
ob_end_clean();
// $pinfo = preg_replace('%^.*<body>(.*)</body>.*$%ms', '$1', $pinfo);
return Inertia::render('admin/ServerInfo', [
'info' => $pinfo,
]);
}
}
================================================
FILE: app/Http/Controllers/Admin/SubjectController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use Inertia\Inertia;
use App\Models\Subject;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\Controller;
use App\Http\Resources\SubjectResource;
class SubjectController extends Controller
{
public function __construct()
{
$this->authorizeResource(Subject::class);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$search = $request->get('s');
$subjects = Subject::query()
->where('parent', 0)
->withCount(['courses', 'exams'])
->with(['children' => fn ($q) => $q->withCount(['courses', 'exams'])->latest()])
->latest();
if ($search) {
$subjects = $subjects->where('title', 'ilike', "%$search%");
}
$subjects = $subjects->paginate();
$resource = SubjectResource::collection($subjects);
return Inertia::render(
'admin/subjects/Index',
[
'response' => $resource,
'filters' => ['search' => $search ?? ''],
]
);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return Inertia::render('admin/subjects/Create', [
'parentSubjects' => Subject::where('parent', 0)->orderBy('title')->get(['id', 'title']),
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string',
'icon' => 'nullable|string|max:100',
'image' => 'nullable|image|max:2048',
'parent' => 'nullable|integer|exists:subjects,id',
]);
$data = $request->only(['title', 'description', 'icon']);
$data['slug'] = $request->slug ?: Str::slug($request->title);
$data['parent'] = $request->input('parent', 0);
if ($request->hasFile('image')) {
$data['image'] = $request->file('image')->store('subjects', 'public');
}
$subject = Subject::create($data);
return to_route('admin.subjects.edit', $subject)->with('success', 'Subject created successfully.');
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Subject $subject)
{
return Inertia::render('admin/subjects/Edit', [
'subject' => new SubjectResource($subject->loadCount('children')),
'parentSubjects' => Subject::where('parent', 0)
->where('id', '!=', $subject->id)
->orderBy('title')
->get(['id', 'title']),
]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Subject $subject
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Subject $subject)
{
$request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string',
'icon' => 'nullable|string|max:100',
'image' => 'nullable|image|max:2048',
'parent' => 'nullable|integer|exists:subjects,id',
]);
$subject->title = $request->title;
$subject->slug = $request->slug ?: Str::slug($request->title);
$subject->description = $request->description;
$subject->icon = $request->icon;
$subject->parent = $request->input('parent', 0);
if ($request->hasFile('image')) {
// Delete old image
if ($subject->image) {
Storage::disk('public')->delete($subject->image);
}
$subject->image = $request->file('image')->store('subjects', 'public');
}
$subject->save();
return to_route('admin.subjects.edit', $subject)->with('success', 'Subject updated successfully.');
}
/**
* Remove the specified resource from storage.
*
* @param \App\Subject $subject
* @return \Illuminate\Http\Response
*/
public function destroy(Subject $subject)
{
$subject->delete();
return to_route('admin.subjects.index');
}
}
================================================
FILE: app/Http/Controllers/Admin/TopicsController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use Inertia\Inertia;
use App\Models\Topic;
use Illuminate\Http\Request;
use App\Http\Requests\TopicRequest;
use App\Http\Controllers\Controller;
use App\Http\Resources\TopicResource;
class TopicsController extends Controller
{
public function __construct()
{
$this->authorizeResource(Topic::class);
}
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$search = $request->get('s');
$topics = Topic::query();
$topics = $topics->withCount(['courses', 'exams']);
if($search) {
$topics = $topics->where('title', 'ilike', "%$search%");
}
$topics = $topics->paginate();
$resource = TopicResource::collection($topics);
return Inertia::render(
'admin/topics/Index',
[
'response' => $resource,
'filters' => ['search' => $search ?? ''],
]
);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return Inertia::render('admin/topics/Create');
}
/**
* Store a newly created resource in storage.
*/
public function store(TopicRequest $request)
{
$topic = Topic::create( $request->all() );
return to_route('admin.topics.edit', $topic);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Topic $topic)
{
return Inertia::render('admin/topics/Edit', [ 'topic' => new TopicResource($topic) ]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Topic $topic
* @return \Illuminate\Http\Response
*/
public function update(TopicRequest $request, Topic $topic)
{
$topic->title = $request->title;
$topic->description = $request->description;
$topic->save();
return to_route('admin.topics.edit', $topic);
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Topic $topic)
{
$topic->delete();
return to_route('admin.topics.index');
}
public function bulkDelete(Request $request)
{
$this->authorize('delete', Topic::class);
$request->validate([
'ids' => ['required', 'array'],
'ids.*' => ['integer', 'exists:topics,id'],
]);
Topic::whereIn('id', $request->ids)->delete();
return back()->with('success', 'Selected topics deleted.');
}
}
================================================
FILE: app/Http/Controllers/Admin/UsersController.php
================================================
<?php
namespace App\Http\Controllers\Admin;
use App\Models\User;
use App\Models\Role;
use Inertia\Inertia;
use App\Http\Requests\Admin\UserRequest;
use App\Http\Controllers\Controller;
use App\Http\Resources\UserResource;
use App\Http\Resources\RoleResource;
use Illuminate\Http\Request;
class UsersController extends Controller
{
public function __construct()
{
$this->authorizeResource(User::class);
}
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$query = User::with('roles')
->when($request->filled('search'), function ($q) use ($request) {
$search = '%' . $request->search . '%';
$q->where(function ($q2) use ($search) {
$q2->where('name', 'ilike', $search)
->orWhere('email', 'ilike', $search)
->orWhere('firstname', 'ilike', $search)
->orWhere('lastname', 'ilike', $search);
});
})
->when($request->filled('role'), function ($q) use ($request) {
$q->whereHas('roles', fn ($q2) => $q2->where('name', $request->role));
});
return Inertia::render('admin/users/Index', [
'response' => UserResource::collection($query->paginate()->withQueryString()),
'roles' => RoleResource::collection(Role::all()),
'filters' => $request->only(['search', 'role']),
]);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return Inertia::render('admin/users/Create');
}
/**
* Store a newly created resource in storage.
*/
public function store(UserRequest $request)
{
$validated = $request->validated();
$data = $request->only([
'firstname',
'lastname',
'name',
'email',
'password',
'role',
'avatar'
]);
$user = User::create($data);
return Inertia::render('admin/users/Edit', [ 'user' => new UserResource($user) ]);
}
/**
* Display the specified resource.
*/
public function show(User $user)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(User $user)
{
return Inertia::render('admin/users/Edit', [ 'user' => new UserResource($user) ]);
}
/**
* Update the specified resource in storage.
*/
public function update(UserRequest $request, User $user)
{
$validated = $request->validated();
$data = $request->only([
'firstname',
'lastname',
'name',
'email',
'password',
'role',
'avatar',
'permissions',
'status'
]);
$user = $user->update($data);
return Inertia::render('admin/users/Edit', [ 'user' => new UserResource($user) ]);
}
/**
* Sync roles for a user.
*/
public function syncRoles(Request $request, User $user)
{
$this->authorize('update', $user);
$request->validate([
'roles' => ['nullable', 'array'],
'roles.*' => ['integer', 'exists:roles,id'],
]);
$user->syncRoles($request->roles ?? []);
return back()->with('success', "Roles updated for {$user->name}.");
}
/**
* Delete multiple users at once.
*/
public function bulkDelete(Request $request)
{
$this->authorize('delete', User::class);
$request->validate([
'ids' => ['required', 'array'],
'ids.*' => ['integer', 'exists:users,id'],
]);
$authId = auth()->id();
User::whereIn('id', $request->ids)
->where('id', '!=', $authId)
->delete();
return back()->with('success', 'Selected users deleted.');
}
/**
* Sync roles for multiple users at once.
*/
public function bulkSyncRoles(Request $request)
{
$this->authorize('update', User::class);
$request->validate([
'ids' => ['required', 'array'],
'ids.*' => ['integer', 'exists:users,id'],
'roles' => ['nullable', 'array'],
'roles.*' => ['integer', 'exists:roles,id'],
]);
User::whereIn('id', $request->ids)->each(
fn (User $user) => $user->syncRoles($request->roles ?? [])
);
return back()->with('success', 'Roles synced for selected users.');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(User $user)
{
if ($user->is(auth()->user())) {
return $this->errorUnauthorized('You can\'t delete for yourself and other Administrators!');
}
$user->delete();
return to_route('admin.users.index');
}
}
================================================
FILE: app/Http/Controllers/Auth/AuthenticatedSessionController.php
================================================
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
use Inertia\Response;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*/
public function create(): Response
{
return Inertia::render('Auth/Login', [
'canResetPassword' => Route::has('password.request'),
'status' => session('status'),
]);
}
/**
* Handle an incoming authentication request.
*/
public function store(LoginRequest $request): RedirectResponse
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(route('admin.dashboard', absolute: false));
}
/**
* Destroy an authenticated session.
*/
public function destroy(Request $request): RedirectResponse
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
================================================
FILE: app/Http/Controllers/Auth/ConfirmablePasswordController.php
================================================
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;
use Inertia\Response;
class ConfirmablePasswordController extends Controller
{
/**
* Show the confirm password view.
*/
public function show(): Response
{
return Inertia::render('Auth/ConfirmPassword');
}
/**
* 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(route('admin.dashboard', absolute: false));
}
}
================================================
FILE: app/Http/Controllers/Auth/EmailVerificationNotificationController.php
================================================
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
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(route('admin.dashboard', absolute: false));
}
$request->user()->sendEmailVerificationNotification();
return back()->with('status', 'verification-link-sent');
}
}
================================================
FILE: app/Http/Controllers/Auth/EmailVerificationPromptController.php
================================================
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
class EmailVerificationPromptController extends Controller
{
/**
* Display the email verification prompt.
*/
public function __invoke(Request $request): RedirectResponse|Response
{
return $request->user()->hasVerifiedEmail()
? redirect()->intended(route('admin.dashboard', absolute: false))
: Inertia::render('Auth/VerifyEmail', ['status' => session('status')]);
}
}
================================================
FILE: app/Http/Controllers/Auth/NewPasswordController.php
================================================
<?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\Validation\ValidationException;
use Inertia\Inertia;
use Inertia\Response;
class NewPasswordController extends Controller
{
/**
* Display the password reset view.
*/
public function create(Request $request): Response
{
return Inertia::render('Auth/ResetPassword', [
'email' => $request->email,
'token' => $request->route('token'),
]);
}
/**
* 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.
if ($status == Password::PASSWORD_RESET) {
return redirect()->route('login')->with('status', __($status));
}
throw ValidationException::withMessages([
'email' => [trans($status)],
]);
}
}
================================================
FILE: app/Http/Controllers/Auth/PasswordController.php
================================================
<?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->validate([
'current_password' => ['required', 'current_password'],
'password' => ['required', Password::defaults(), 'confirmed'],
]);
$request->user()->update([
'password' => Hash::make($validated['password']),
]);
return back();
}
}
================================================
FILE: app/Http/Controllers/Auth/PasswordResetLinkController.php
================================================
<?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\Validation\ValidationException;
use Inertia\Inertia;
use Inertia\Response;
class PasswordResetLinkController extends Controller
{
/**
* Display the password reset link request view.
*/
public function create(): Response
{
return Inertia::render('Auth/ForgotPassword', [
'status' => session('status'),
]);
}
/**
* 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')
);
if ($status == Password::RESET_LINK_SENT) {
return back()->with('status', __($status));
}
throw ValidationException::withMessages([
'email' => [trans($status)],
]);
}
}
================================================
FILE: app/Http/Controllers/Auth/RegisteredUserController.php
================================================
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
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\Validation\Rules;
use Inertia\Inertia;
use Inertia\Response;
class RegisteredUserController extends Controller
{
/**
* Display the registration view.
*/
public function create(): Response
{
return Inertia::render('Auth/Register');
}
/**
* Handle an incoming registration request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|lowercase|email|max:255|unique:'.User::class,
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($user));
Auth::login($user);
return redirect(route('admin.dashboard', absolute: false));
}
}
================================================
FILE: app/Http/Controllers/Auth/SocialiteController.php
================================================
<?php
namespace App\Http\Controllers\Auth;
use Abraham\TwitterOAuth\TwitterOAuth;
use App\Exceptions\SocialProviderDeniedException;
use App\Http\Controllers\Controller;
use App\Models\SocialiteProvider;
use App\Traits\SocialiteProvidersTrait;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use Laravel\Socialite\Facades\Socialite;
class SocialiteController extends Controller
{
use SocialiteProvidersTrait;
private $providerSettings;
private $providerConfigs;
public function __construct()
{
$this->setupProviders();
try {
ob_start('ob_gzhandler');
} catch (\Exception $e) {
//
}
}
public function guard($guard = 'web')
{
return Auth::guard($guard);
}
/**
* Get a list of enabled socialite logins.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function loginsEnabled(Request $request)
{
return response()->json([
'logins' => $this->loginsList(),
]);
}
/**
* Gets the social redirect.
*
* @param string $provider The provider
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function getSocialRedirect(Request $request, string $provider)
{
$providerKey = Config::get('services.'.$provider);
if (empty($providerKey)) {
abort(419);
}
$url = null;
$token = null;
$state = null;
$user = null;
$scopes = [];
$with = [];
if (auth('sanctum')->check()) {
$user = auth('sanctum')->user();
}
if ($user) {
$token = $user->createToken($provider.'-user-token')->plainTextToken;
$state = Crypt::encrypt($token);
} else {
$state = Crypt::encrypt(config('app.key'));
}
$with = ['state' => $state];
// https://developers.facebook.com/docs/instagram-basic-display-api/guides/getting-access-tokens-and-permissions/
if ($provider == 'instagram') {
$scopes = ['user_profile'];
$with += ['response_type' => 'code'];
}
// https://docs.snap.com/snap-kit/login-kit/Tutorials/web#understand-scopes
if ($provider == 'snapchat') {
$scopes = [
'https://auth.snapchat.com/oauth2/api/user.display_name',
'https://auth.snapchat.com/oauth2/api/user.external_id',
'https://auth.snapchat.com/oauth2/api/user.bitmoji.avatar',
];
$with += ['response_type' => 'code'];
}
if ($provider == 'tiktok') {
$scopes = [
'user.info.basic',
];
$with += ['response_type' => 'code'];
}
if ($provider == 'twitter') {
$url = $this->twitterUserAuthenticationUrl($state);
} else {
$url = Socialite::driver($provider)
->stateless()
->with($with)
->scopes($scopes)
->redirect()
->getTargetUrl();
}
if ($provider == 'stackexchange') {
$url = $this->cacheStatePutKeyInUrl($url, $state);
}
return response()->json([
'url' => $url,
]);
}
/**
* Gets the social handle information from the provider.
*
* @param string $provider The provider
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function handleSocialCallback(Request $request, string $provider)
{
$denied = $request->denied ? $request->denied : null;
if ($denied != null || $denied != '') {
throw new SocialProviderDeniedException;
}
if ($provider == 'twitter') {
$socialUser = $this->twitterUserAuthentication($request);
$state = $request->state ? Crypt::decrypt(Cache::pull($request->state)) : null;
} elseif ($provider == 'stackexchange') {
$socialUser = Socialite::driver($provider)->stateless()->user();
$state = $request->state ? Crypt::decrypt(Cache::pull($request->state)) : null;
} else {
$socialUser = Socialite::driver($provider)->stateless()->user();
$state = $request->state ? Crypt::decrypt($request->state) : null;
}
$userData = $this->findOrCreateUser($provider, $socialUser, $state);
$user = $userData['user'];
$token = $userData['token'];
if ($user && $token) {
auth()->login($user);
} else {
$token = 'cannot_add';
}
return view('socialite/callback', [
'token' => $token,
'token_type' => 'bearer',
]);
}
/**
* Get Twitter Oauth1.0 Url built with identifier if user is present.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function twitterUserAuthenticationUrl($state = null)
{
$consumerKey = config('services.twitter.client_id');
$consumerSecret = config('services.twitter.client_secret');
$consumerRedirect = config('services.twitter.redirect');
$connection = new TwitterOAuth($consumerKey, $consumerSecret);
$tempId = $this->generateTempId();
$requestToken = $connection->oauth('oauth/request_token', [
'oauth_callback' => $consumerRedirect.'?state='.$tempId,
]);
$this->tempStoreStateInCache($tempId, $state);
$url = $connection->url('oauth/authorize', [
'oauth_token' => $requestToken['oauth_token'],
]);
return $url;
}
/**
* Get Twitter user credentials from Oauth1.0.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function twitterUserAuthentication(Request $request)
{
$consumerKey = config('services.twitter.client_id');
$consumerSecret = config('services.twitter.client_secret');
$consumerRedirect = config('services.twitter.redirect');
$connection = new TwitterOAuth($consumerKey, $consumerSecret, $request->oauth_token);
$access_token = $connection->oauth('oauth/access_token', [
'oauth_verifier' => $request->oauth_verifier,
'oauth_token' => $request->oauth_token,
]);
$connection = new TwitterOAuth($consumerKey, $consumerSecret, $access_token['oauth_token'], $access_token['oauth_token_secret']);
return $connection->get('account/verify_credentials', [
'include_email' => true,
'skip_status' => true,
'include_entities' => false,
]);
}
/**
* Revoke a social media login provider for
* a user from the app and from the provider.
*
* @param \App\Models\SocialiteProvider $provider
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function revokeSocialProvider(SocialiteProvider $provider, Request $request)
{
$user = auth('sanctum')->user();
if ($provider->user_id != $user->id) {
abort(403);
}
$provider->delete();
return response()->json([
'status' => 'success',
'provider' => $provider,
'user' => $user,
]);
}
}
================================================
FILE: app/Http/Controllers/Auth/VerifyEmailController.php
================================================
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
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(route('admin.dashboard', absolute: false).'?verified=1');
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return redirect()->intended(route('admin.dashboard', absolute: false).'?verified=1');
}
}
================================================
FILE: app/Http/Controllers/Controller.php
================================================
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
abstract class Controller extends BaseController
{
use AuthorizesRequests, ValidatesRequests;
}
================================================
FILE: app/Http/Controllers/CourseController.php
================================================
<?php
namespace App\Http\Controllers;
use App\Http\Resources\CourseResource;
use App\Models\Course;
use Auth;
use Illuminate\Http\Request;
use Inertia\Inertia;
class CourseController extends Controller
{
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function show(Request $request, Course $course)
{
$course->loadCount(['lessons', 'exams', 'sections', 'students']);
$course->load(['subjects', 'topics', 'teachers']);
return Inertia::render('Course/Course', [
'course' => new CourseResource($course)
]);
}
public function subscribe(Request $request, Course $course)
{
$user = $request->user();
$enrolled = $user->enrolledCourses->firstWhere('id', $course->id);
if($enrolled) {
return response()->json([],200);
}
$user->enrolledCourses()->attach($course);
$lessons = $course->lessons->pluck('id');
$user->enrolledLessons()->attach($lessons);
return response()->json([],200);
}
}
================================================
FILE: app/Http/Controllers/DownloadController.php
================================================
<?php
namespace App\Http\Controllers;
use App\Models\File;
use Illuminate\Http\Request;
use App\Response\DownloadResponse;
class DownloadController extends Controller
{
/**
* @var Request
*/
private $request;
/**
* @var File
*/
private $file;
/**
* download response.
*
* @var DownloadResponse
*/
private $downloadResponse;
public function __construct(Request $request, File $file, DownloadResponse $downloadResponse)
{
$this->request = $request;
$this->file = $file;
$this->downloadResponse = $downloadResponse;
}
public function download(Request $request)
{
$ids = $request->get('ids');
if (sizeof($ids) > 1) {
return $this->downloadResponse->multipleDownload($ids);
} else {
return $this->downloadResponse->singleDownload($ids[0]);
}
}
}
================================================
FILE: app/Http/Controllers/HomeController.php
================================================
<?php
namespace App\Http\Controllers;
use App\Http\Resources\CourseResource;
use App\Http\Resources\SubjectResource;
use App\Models\Course;
use App\Models\Subject;
use Illuminate\Http\Request;
use Inertia\Inertia;
class HomeController extends Controller
{
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function __invoke(Request $request)
{
$subjects = Subject::withCount(['courses', 'exams'])
->with(['courses', 'exams'])
->whereHas('courses')
->get();
$featuredCourses = Course::with(['teachers', 'subjects'])
->withCount(['lessons', 'students'])
->latest()
->limit(8)
->get();
return Inertia::render('Home/Home', [
'subjects' => SubjectResource::collection($subjects),
'featuredCourses' => CourseResource::collection($featuredCourses),
]);
}
}
================================================
FILE: app/Http/Controllers/InstructorController.php
================================================
<?php
namespace App\Http\Controllers;
use App\Actions\GetInstratorCousesAction;
use App\Models\User;
use Inertia\Inertia;
use Illuminate\Http\Request;
class InstructorController extends Controller
{
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function courses(Request $request)
{
if ($request->user)
{
$user = User::where('name', $request->user)->first();
}else {
$user = $request->user();
}
if(!$user) {
return to_route('home');
}
return Inertia::render('Instructor/Courses', [
'courses' => GetInstratorCousesAction::getCourses($user),
'canModify' => $request->user()->id == $user->id
]);
}
}
================================================
FILE: app/Http/Controllers/LearningController.php
================================================
<?php
namespace App\Http\Controllers;
use App\Actions\CourseWithSections;
use Auth;
use Inertia\Inertia;
use App\Models\Course;
use Illuminate\Http\Request;
use App\Actions\GetEnrolledCousesAction;
use App\Http\Resources\CourseResource;
use App\Http\Resources\ExamResource;
use App\Http\Resources\LessonResource;
use App\Models\Exam;
use App\Models\Lesson;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
class LearningController extends Controller
{
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function myCourses(Request $request)
{
$user = $request->user();
return Inertia::render('Learning/Courses', [
'courses' => GetEnrolledCousesAction::getCourses($user),
'canModify' => $request->user()->id == $user->id
]);
}
public function startCourse(Course $course)
{
$last = DB::table('course_students')->where('course_id', $course->id)->first()->last_lesson;
if (!$last) {
$course = CourseWithSections::getCourses($course);
$firstResource = $course->sections?->first()?->resources?->first();
if ($firstResource) {
if (is_a($firstResource, Lesson::class)) {
$type = 'lesson';
$slug = $firstResource->slug;
} else {
$type = 'exam';
$slug = $firstResource->slug;
}
}
return to_route('start.resource', [$course->slug, $type, $slug]);
}
}
public function singleResource(Course $course, $type, $slug)
{
if ($type == 'lesson') {
$resource = new LessonResource(Lesson::where('slug', $slug)->first()) ;
} else {
$resource = new ExamResource(Exam::where('slug', $slug)->first()) ;
}
return Inertia::render('Learning/SingleResource', [
'course' => CourseWithSections::getCourses($course),
'resource' => $resource
]);
}
}
================================================
FILE: app/Http/Controllers/ProfileController.php
================================================
<?php
namespace App\Http\Controllers;
use App\Http\Requests\ProfileUpdateRequest;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
use Inertia\Inertia;
use Inertia\Response;
class ProfileController extends Controller
{
/**
* Display the user's profile form.
*/
public function edit(Request $request): Response
{
return Inertia::render('Profile/Edit', [
'mustVerifyEmail' => $request->user() instanceof MustVerifyEmail,
'status' => session('status'),
]);
}
/**
* Update the user's profile information.
*/
public function update(ProfileUpdateRequest $request): RedirectResponse
{
$request->user()->fill($request->validated());
if ($request->user()->isDirty('email')) {
$request->user()->email_verified_at = null;
}
$request->user()->save();
return Redirect::route('profile.edit');
}
/**
* Delete the user's account.
*/
public function destroy(Request $request): RedirectResponse
{
$request->validate([
'password' => ['required', 'current_password'],
]);
$user = $request->user();
Auth::logout();
$user->delete();
$request->session()->invalidate();
$request->session()->regenerateToken();
return Redirect::to('/');
}
}
================================================
FILE: app/Http/Controllers/UploadController.php
================================================
<?php
namespace App\Http\Controllers;
use App\Models\File;
use App\Response\FileContentResponseCreator;
class UploadController extends Controller
{
/**
* Create a new controller instance.
*/
public function __invoke(FileContentResponseCreator $fileResponse, $id)
{
$entry = File::where('file_name', $id)->first();
return $fileResponse->create($entry);
}
}
================================================
FILE: app/Http/Middleware/HandleInertiaRequests.php
================================================
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Inertia\Middleware;
class HandleInertiaRequests extends Middleware
{
/**
* The root template that is loaded on the first page visit.
*
* @var string
*/
protected $rootView = 'app';
/**
* Determine the current asset version.
*/
public function version(Request $request): string|null
{
return parent::version($request);
}
/**
* Define the props that are shared by default.
*
* @return array<string, mixed>
*/
public function share(Request $request): array
{
return [
...parent::share($request),
'auth' => [
'user' => $request->user(),
],
'appEnv' => app()->environment(),
'flash' => [
'success' => $request->session()->get('success'),
'error' => $request->session()->get('error'),
],
];
}
}
================================================
FILE: app/Http/Requests/Admin/StoreCoursesRequest.php
================================================
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Foundation\Http\FormRequest;
class StoreCoursesRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'teachers.*' => 'exists:users,id',
'title' => 'required',
'start_date' => 'date_format:'.config('app.date_format'),
];
}
}
================================================
FILE: app/Http/Requests/Admin/UpdateCoursesRequest.php
================================================
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Foundation\Http\FormRequest;
class UpdateCoursesRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'teachers.*' => 'exists:users,id',
'title' => 'required',
'start_date' => 'date_format:'.config('app.date_format'),
];
}
}
================================================
FILE: app/Http/Requests/Admin/UserRequest.php
================================================
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Foundation\Http\FormRequest;
class UserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
//
];
}
}
================================================
FILE: app/Http/Requests/Auth/LoginRequest.php
================================================
<?php
namespace App\Http\Requests\Auth;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class LoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
];
}
/**
* Attempt to authenticate the request's credentials.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function authenticate(): void
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
/**
* Ensure the login request is not rate limited.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function ensureIsNotRateLimited(): void
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
/**
* Get the rate limiting throttle key for the request.
*/
public function throttleKey(): string
{
return Str::transliterate(Str::lower($this->string('email')).'|'.$this->ip());
}
}
================================================
FILE: app/Http/Requests/ExamRequest.php
================================================
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ExamRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|min:5|max:255'
];
}
}
================================================
FILE: app/Http/Requests/ProfileUpdateRequest.php
================================================
<?php
namespace App\Http\Requests;
use App\Models\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class ProfileUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)],
];
}
}
================================================
FILE: app/Http/Requests/QuestionRequest.php
================================================
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class QuestionRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'question' => 'required',
];
}
}
================================================
FILE: app/Http/Requests/SettingRequest.php
================================================
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SettingRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'key' => 'required',
'value' => 'required',
];
}
}
================================================
FILE: app/Http/Requests/SubjectRequest.php
================================================
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SubjectRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required'
];
}
}
================================================
FILE: app/Http/Requests/TopicRequest.php
================================================
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class TopicRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required'
];
}
}
================================================
FILE: app/Http/Resources/CourseResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\Course */
class CourseResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'subtitle' => $this->subtitle,
'slug' => $this->slug,
'description' => $this->description,
'requirements' => $this->requirements,
'price' => $this->price,
'discount' => $this->discount,
'status' => $this->status,
'thumbnail' => $this->thumbnail,
'start_date' => $this->start_date,
'features' => $this->features,
'permalink' => $this->permalink,
'rating' => $this->rating,
'certified' => $this->certified,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'teachers' => UserResource::collection($this->whenLoaded('teachers')),
'students' => UserResource::collection($this->whenLoaded('students')),
'sections' => SectionResource::collection($this->whenLoaded('sections')),
'lessons' => LessonResource::collection($this->whenLoaded('lessons')),
'exams' => ExamResource::collection($this->whenLoaded('exams')),
'topics' => TopicResource::collection($this->whenLoaded('topics')),
'subjects' => SubjectResource::collection($this->whenLoaded('subjects')),
'lessons_count' => $this->whenCounted('lessons'),
'students_count' => $this->whenCounted('students'),
'sections_count' => $this->whenCounted('sections'),
'exams_count' => $this->whenCounted('exams'),
];
}
}
================================================
FILE: app/Http/Resources/CourseStudentsResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\User */
class CourseStudentsResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'full_name' => $this->full_name,
'avatar' => $this->avatar,
'rating' => $this->pivot->rating,
'progress' => $this->pivot->progress
];
}
}
================================================
FILE: app/Http/Resources/ExamResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\Exam */
class ExamResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'permalink' => $this->permalink,
'status' => $this->status,
'price' => $this->price,
'duration' => $this->duration,
'pass_mark' => $this->pass_mark,
'meta' => $this->meta,
'number_of_questions' => $this->number_of_questions,
'random_questions' => (boolean) $this->random_questions,
'certification' => (boolean) $this->certification,
'difficulty' => $this->difficulty,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'subjects' => SubjectResource::collection($this->whenLoaded('subjects')),
'courses' => CourseResource::collection($this->whenLoaded('courses')),
'questions' => QuestionResource::collection($this->whenLoaded('questions')),
'examiner' => new UserResource($this->whenLoaded('examiner')),
'topics' => TopicResource::collection($this->whenLoaded('topics')),
'results' => ResultResource::collection($this->whenLoaded('results')),
'pivot' => $this->when($this->pivot, [
'sectionable_type' => $this->pivot->sectionable_type,
'order' => $this->pivot->order
])
];
}
}
================================================
FILE: app/Http/Resources/FileResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\File */
class FileResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'path' => $this->path,
'file_name' => $this->file_name,
'extension' => $this->extension,
'mime' => $this->mime,
'type' => $this->type,
'public_path' => $this->public_path,
'parent_id' => $this->parent_id,
'uploaded_by' => $this->uploaded_by,
];
}
}
================================================
FILE: app/Http/Resources/LessonResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\Lesson */
class LessonResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
$lesson = [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
'thumbnail' => $this->thumbnail,
'type' => $this->type,
'object' => $this->object,
'short_text' => $this->short_text,
'full_text' => $this->full_text,
'position' => $this->position,
'status' => $this->status,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'courses' => CourseResource::collection($this->whenLoaded('courses')),
'students' => UserResource::collection($this->whenLoaded('students')),
'sections' => SectionResource::collection($this->whenLoaded('sections')),
];
if ($this->pivot) {
$lesson['pivot'] = [
'sectionable_type' => $this->pivot->sectionable_type,
'order' => $this->pivot->order
];
}
return $lesson;
}
}
================================================
FILE: app/Http/Resources/QuestionResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\Question */
class QuestionResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'qtype' => $this->qtype,
'question' => $this->question,
'options' => $this->options,
'answers' => $this->answers,
'hint' => $this->hint,
'mark' => $this->mark,
'nmark' => $this->nmark,
'explanation' => $this->explanation,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'topics' => TopicResource::collection($this->whenLoaded('topics')),
'exam' => new ExamResource($this->whenLoaded('exam')),
];
}
}
================================================
FILE: app/Http/Resources/ResultResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\Result */
class ResultResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'answers' => $this->answers,
'obtain_mark' => $this->obtain_mark,
'is_pass' => $this->is_pass,
'time_taken' => $this->time_taken,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'examinee' => new UserResource($this->whenLoaded('examinee')),
'exam' => new ExamResource($this->whenLoaded('exam')),
];
}
}
================================================
FILE: app/Http/Resources/RoleResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\Role */
class RoleResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'guard_name' => $this->guard_name,
'permissions' => $this->permissions->toArray(),
'users_count' => $this->users_count ?? 0,
'permissions_count' => $this->permissions_count ?? 0,
];
}
}
================================================
FILE: app/Http/Resources/SectionResource.php
================================================
<?php
namespace App\Http\Resources;
use App\Models\Lesson;
use Illuminate\Http\Request;
use App\Http\Resources\ExamResource;
use App\Http\Resources\LessonResource;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\Section */
class SectionResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'lessons' => LessonResource::collection($this->whenLoaded('lessons')),
'exams' => ExamResource::collection($this->whenLoaded('exams')),
'resources' => $this->transform($this->resources, function($resources){
return $resources->map(function($resource) {
if (is_a($resource, Lesson::class)) {
return new LessonResource($resource);
} else {
return new ExamResource($resource);
}
});
})
];
}
}
================================================
FILE: app/Http/Resources/SubjectResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\Subject */
class SubjectResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
'description' => $this->description,
'icon' => $this->icon,
'image' => $this->image,
'image_url' => $this->image_url,
'parent' => $this->parent,
'children_count' => $this->resource->children_count ?? 0,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'courses_count' => $this->when($this->courses_count, $this->courses_count),
'exams_count' => $this->when($this->exams_count, $this->exams_count),
'courses' => CourseResource::collection($this->whenLoaded('courses')),
'exams' => CourseResource::collection($this->whenLoaded('exams')),
'children' => SubjectResource::collection($this->whenLoaded('children')),
];
}
}
================================================
FILE: app/Http/Resources/TopicResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\Topic */
class TopicResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'courses_count' => $this->when($this->courses_count, $this->courses_count),
'exams_count' => $this->when($this->exams_count, $this->exams_count),
'courses' => CourseResource::collection($this->whenLoaded('courses')),
'exams' => CourseResource::collection($this->whenLoaded('exams')),
];
}
}
================================================
FILE: app/Http/Resources/UserResource.php
================================================
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \App\Models\User */
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'firstname' => $this->firstname,
'lastname' => $this->lastname,
'full_name' => $this->full_name,
'email' => $this->email,
'avatar' => $this->avatar,
'email_verified_at' => $this->email_verified_at?->format('Y-m-d H:i:s'),
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
'updated_at' => $this->updated_at->format('Y-m-d H:i:s'),
'deleted_at' => $this->deleted_at?->format('Y-m-d H:i:s'),
'roles' => RoleResource::collection($this->whenLoaded('roles')),
'results' => ResultResource::collection($this->whenLoaded('results')),
'instructCourses' => CourseResource::collection($this->whenLoaded('instructCourses')),
'enrolledCourses' => CourseResource::collection($this->whenLoaded('enrolledCourses')),
];
}
}
================================================
FILE: app/Jobs/ResizedImage.php
================================================
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Intervention\Image\Facades\Image;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\File as FileAdapdar;
use App\Models\File;
class ResizedImage implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* App\File object.
*
* @var App\Models\File;
*/
protected $file;
/**
* Create a new job instance.
*/
public function __construct(File $file)
{
$this->file = $file;
}
/**
* Execute the job.
*/
public function handle()
{
// we cant anything without image
if ($this->file->type !== 'image') {
return;
}
// get sizes of images
$meta = $this->file->meta;
$sizes = $meta['sizes'];
// there are not any sizes;
if (!is_array($sizes)) {
return;
}
/*
* is file in cloude then,
* Download from cloud to local then resize it.
*/
if ($this->file->driver == config('filesystems.cloud')) {
if (!Storage::disk(config('filesystems.cloud'))->exists($this->file->getStoragePath())) {
throw new Exception();
}
$s3file = Storage::disk(config('filesystems.cloud'))->get($this->file->getStoragePath());
Storage::disk('local')->put("{$this->file->file_name}/{$this->file->name}", $s3file);
}
$path = storage_path("app/uploads/{$this->file->file_name}");
$file = new FileAdapdar("{$path}/{$this->file->name}");
$public = 'public';
foreach ($sizes as $key => $value) {
// already we resized this size
if ($value == true) {
continue;
}
// Image not resized let resize it
$rs = explode('x', $key); // [150, 50]
// create Intervention images
$image = Image::make($file)->resize($rs[0], $rs[1]);
$localFile = "{$path}/{$key}-{$this->file->name}";
$image->save($localFile);
if ($this->file->driver == config('filesystems.cloud')) {
Storage::disk(config('filesystems.cloud'))->putFileAs($this->file->file_name, new FileAdapdar($localFile), "{$key}-{$this->file->name}", $public);
}
$sizes[$key] = true;
}
// save meta values;
$meta['sizes'] = $sizes;
$this->file->meta = $meta;
if ($this->file->isDirty()) {
$this->file->save();
}
if ($this->file->driver == config('filesystems.cloud')) {
Storage::deleteDirectory($path);
}
}
}
================================================
FILE: app/Jobs/UploadToCloud.php
================================================
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\File as FileAdapdar;
use App\Models\File;
class UploadToCloud implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* App\File object.
*
* @var App\Models\File;
*/
protected $file;
/**
* Create a new job instance.
*/
public function __construct(File $file)
{
$this->file = $file;
}
/**
* Execute the job.
*/
public function handle()
{
$disk = config('filesystems.cloud');
// is already uploaded
if ($this->file->driver == $disk) {
return;
}
$path = storage_path('app/uploads/');
$public = 'public';
$localfiles = Storage::disk('local')->allFiles($this->file->file_name);
foreach ($localfiles as $lfile) {
Storage::disk($disk)->putFileAs($this->file->file_name, new FileAdapdar("{$path}/{$lfile}"), $this->file->name, $public);
}
// save to path;
$this->file->updatePublicPaths($disk);
// wait 5 second to delete directorr so all local request is complete and new request to cloud
sleep(5);
Storage::disk('local')->deleteDirectory($this->file->file_name);
}
}
================================================
FILE: app/Models/Course.php
================================================
<?php
namespace App\Models;
use App\Models\Exam;
use Illuminate\Support\Carbon;
use App\Models\Traits\Fileable;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property int $id
* @property string $title
* @property string $subtitle
* @property string $slug
* @property string $description
* @property string $features
* @property string $requirements
* @property string $thumbnail
* @property int $price
* @property int $discount
* @property int $status
* @property int $created_by
* @property int $updated_by
* @property bool $certified
* @property Carbon $start_date
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Collection<User> $teachers
* @property Collection<User> $students
* @property Collection<Sections> $sections
* @property Collection<Lesson> $lessons
* @property Collection<Lesson> $publishedLessons
* @property Collection<Exam> $exams
* @property Collection<Topic> $topics
* @property Collection<Subject> $subjects
*/
class Course extends Model
{
use SoftDeletes, Fileable, HasFactory;
protected $fillable = [
'title',
'subtitle',
'slug',
'description',
'requirements',
'price',
'discount',
'thumbnail',
'start_date',
'status',
'features',
'certified',
'created_by',
'updated_by'
];
/*
|--------------------------------------------------------------------------
| ACCESORS Variables
|--------------------------------------------------------------------------
*/
protected $with = [
'thumbnail'
];
protected $appends = [
'permalink',
];
protected $casts = [
'features' => 'array'
];
/*
|--------------------------------------------------------------------------
| Booting
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESORS
|--------------------------------------------------------------------------
*/
public function getRatingAttribute()
{
return number_format(DB::table('course_students')->where('course_id', $this->attributes['id'])->average('rating'), 2);
}
public function getPermalinkAttribute()
{
return route('course.show', ['course' => $this->slug]);
}
/**
* Set attribute to money format
* @param $input
*/
public function setPriceAttribute($input)
{
$this->attributes['price'] = $input ? $input : null;
}
/*
|--------------------------------------------------------------------------
| Scopes
|--------------------------------------------------------------------------
*/
public function scopeOfTeacher($query)
{
return $query->whereHas('teachers', function ($q) {
$q->where('user_id', Auth::user()->id);
});
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function teachers()
{
return $this->belongsToMany(User::class, 'course_teachers');
}
public function students()
{
return $this->belongsToMany(User::class, 'course_students')->withTimestamps()->withPivot(['rating', 'progress']);
}
public function sections()
{
return $this->hasMany(Section::class);
}
public function lessons()
{
return $this->belongsToMany(Lesson::class, 'sectionables', 'course_id', 'sectionable_id')->wherePivot('sectionable_type', Lesson::class);
}
public function publishedLessons()
{
return $this->hasMany(Lesson::class)->orderBy('position')->where('status', 1);
}
public function exams()
{
return $this->belongsToMany(Exam::class, 'sectionables', 'course_id', 'sectionable_id')->wherePivot('sectionable_type', Exam::class);
}
public function topics()
{
return $this->morphToMany(Topic::class, 'topicable');
}
public function subjects()
{
return $this->morphToMany(Subject::class, 'subjectables');
}
public function thumbnail()
{
return $this->belongsTo(File::class, 'thumbnail');
}
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
}
================================================
FILE: app/Models/Exam.php
================================================
<?php
namespace App\Models;
use App\Models\User;
use App\Models\Course;
use App\Models\Result;
use App\Models\Subject;
use App\Models\Question;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property int $id
* @property string $title
* @property string $description
* @property int $status
* @property int $duration
* @property int $price
* @property int $pass_mark
* @property array $meta
* @property int $number_of_questions
* @property bool $random_questions
* @property bool $certification
* @property bool $difficulty
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Carbon $deleted_at
* @property Collection<Course> $courses
* @property Collection<Exam> $exams
* @property User $examiner
*/
class Exam extends Model
{
use SoftDeletes, HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'title',
'description',
'examiner',
'price',
'status',
'duration',
'pass_mark',
'meta',
'number_of_questions',
'random_questions',
'certification',
'difficulty',
];
protected $casts = [
'meta' => 'array',
];
public function subjects()
{
return $this->morphToMany(Subject::class, 'subjectables');
}
public function courses()
{
return $this->belongsToMany(Course::class, 'sectionables', 'sectionable_id', 'course_id')->wherePivot('sectionable_type', Exam::class);
}
public function questions()
{
return $this->hasMany(Question::class);
}
public function topics()
{
return $this->morphToMany(Topic::class, 'topicable');
}
public function results()
{
return $this->hasMany(Result::class, 'exam_id', 'id');
}
public function examiner()
{
return $this->belongsTo(User::class, 'examiner');
}
public static function calculateTotalMark($marks)
{
$count = 0;
foreach ($marks as $mark) {
$count = $count + $mark->mark;
}
return $count;
}
public function sectionable()
{
return $this->morphOne(Sectionable::class, 'sectionable');
}
}
================================================
FILE: app/Models/File.php
================================================
<?php
namespace App\Models;
use App\Models\User;
use App\Jobs\ResizedImage;
use Illuminate\Support\Carbon;
use App\Models\Traits\HashesId;
use App\Observers\FileObserver;
use App\Models\Traits\FileStorage;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* @property int $id
* @property string $name
* @property string $description
* @property string $path
* @property string $file_name
* @property string $extension
* @property string $mime
* @property string $type
* @property string $public_path
* @property string $driver_data
* @property string $driver
* @property int $parent_id
* @property int $uploaded_by
* @property array $meta
* @property Carbon $created_at
* @property Carbon $updated_at
* @property File $children
* @property File $parent
* @property User $uploader
* @property Collection<Exam> $exams
*/
class File extends Model
{
use HashesId, FileStorage, SoftDeletes;
protected $fillable = [
'name',
'description',
'path',
'file_name',
'extension',
'mime',
'type',
'public_path',
'parent_id',
'driver',
'driver_data',
'uploaded_by',
'meta',
];
protected $casts = [
'id' => 'integer',
'file_size' => 'integer',
'user_id' => 'integer',
'parent_id' => 'integer',
'meta' => 'array',
'permissions' => 'array',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array<int, string>
*/
protected $hidden = [
'meta',
'file_name'
];
/**
* the accessor that should append with response.
*
* @var array<int, string>
*/
protected $appends = [
'sizes',
'hash'
];
/*
|--------------------------------------------------------------------------
| Booting
|--------------------------------------------------------------------------
*/
public static function boot()
{
parent::boot();
File::observe(FileObserver::class);
}
/*
|--------------------------------------------------------------------------
| ACCESORS Variables
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESORS & Mutation
|--------------------------------------------------------------------------
*/
public function getSizesAttribute()
{
if ($this->type == 'image') {
return $this->getImageSizes();
}
return [];
}
/*
|--------------------------------------------------------------------------
| Scopes
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function children()
{
return $this->hasMany(static::class, 'folder_id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function parent()
{
return $this->belongsTo(static::class, 'folder_id');
}
public function uploader()
{
return $this->hasOne(User::class, 'id', 'uploaded_by');
}
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public function setPermission($permission, $value)
{
$meta = $this->meta;
$permissions = $meta['permissions'];
$permissions[$permission] = $value;
$meta['permissions'] = $permissions;
$this->meta = $meta;
return $this;
}
public function getPermission($permission = null)
{
$permissions = $this->meta['permissions'];
if ($permission !== null) {
if (array_key_exists($permission, $permissions)) {
return $permissions[$permission];
} else {
return false;
}
}
return $permissions;
}
public function hasPermission($permission)
{
return $this->getPermission($permission) === true;
}
public function setImageSize($size)
{
$sizes = $this->meta['sizes'];
$sizes[$size] = false;
$this->meta['sizes'] = $sizes;
return $this;
}
public function getImageSizes()
{
return $this->meta['sizes'];
}
public function updatePublicPaths($driver = null)
{
if ($this->driver !== $driver) {
$this->driver = $driver;
}
if ($this->hasPermission('public')) {
$this->public_path = Storage::disk($this->driver)->url($this->getStoragePath());
} else {
$this->public_path = Storage::disk('local')->url($this->getStoragePath());
}
$this->save();
}
public function getStoragePath($prefix = null)
{
return "$this->file_name/$this->name";
}
/**
* set the image resize attribute;.
*
* @param array $sizes
*/
public function setImageSizes(array $sizes)
{
$meta = $this->meta;
$exiting = $meta['sizes'];
$hasnew = false;
foreach ($sizes as $size) {
if (is_array($size) && is_array($exiting) && array_key_exists(implode('x', $size), $exiting)) {
continue;
}
$exiting[implode('x', $size)] = false;
$hasnew = true;
}
if ($hasnew) {
$meta['sizes'] = $exiting;
$this->meta = $meta;
$this->save();
ResizedImage::dispatch($this);
}
return $this;
}
}
================================================
FILE: app/Models/Lesson.php
================================================
<?php
namespace App\Models;
use Auth;
use App\Models\File;
use Illuminate\Support\Carbon;
use App\Models\Traits\Fileable;
use App\Models\Traits\Topicable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property int $id
* @property string $title
* @property string $slug
* @property string $thumbnail
* @property int $type
* @property array $object
* @property string $short_text
* @property string $full_text
* @property int $position
* @property int $status
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Carbon $deleted_at
* @property int $created_by
* @property int $updated_by
* @property Collection<Course> $courses
* @property Collection<User> $students
* @property Collection<Section> $sections
* @property Sectionable $sectionable
* @property File $objectFile
*/
class Lesson extends Model
{
use Topicable, Fileable, SoftDeletes, HasFactory;
protected $fillable = [
'title',
'slug',
'thumbnail',
'short_text',
'full_text',
'position',
'type',
'object',
'status',
'created_by',
'updated_by'
];
/*
|--------------------------------------------------------------------------
| ACCESORS Variables
|--------------------------------------------------------------------------
*/
// protected $casts = [
// 'object' => 'array'
// ];
/**
* The attributes that should be hidden for arrays.
*
* @var array<int, string>
*/
protected $hidden = ['object', 'full_text'];
public static $types = [
'text' => 1,
'video' => 2,
'audio' => 3,
'pdf' => 4
];
public static $statuses = [
'free' => 1,
'subscriber' => 2,
'paid' => 3,
];
/*
|--------------------------------------------------------------------------
| ACCESORS
|--------------------------------------------------------------------------
*/
public function getTypeAttribute($value)
{
$key = array_search($value, self::$types);
if ($key) {
return ucfirst($key);
}
}
public function setTypeAttribute($value)
{
$value = strtolower($value);
$key = array_search($value, self::$types);
if ($key) {
$this->attributes['type'] = $value;
} else {
$this->attributes['type'] = self::$types[$value];
}
}
public function getStatusAttribute($value)
{
$key = array_search($value, self::$statuses);
if ($key) {
return ucfirst($key);
}
}
public function setStatusAttribute($value)
{
$value = strtolower($value);
$key = array_search($value, self::$statuses);
if ($key) {
$this->attributes['status'] = $value;
} else {
$this->attributes['status'] = self::$statuses[$value];
}
}
public function getObjectAttribute($value)
{
return $this->files->where('id', $value)->first();
}
/*
|--------------------------------------------------------------------------
| Scopes
|--------------------------------------------------------------------------
*/
public function scopePublished($query)
{
return $query->where('status', 1);
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function courses()
{
return $this->belongsToMany(Course::class, 'sectionables', 'sectionable_id', 'course_id')->wherePivot('sectionable_type', Lesson::class);
}
public function students()
{
return $this->belongsToMany(User::class, 'lesson_student')->withTimestamps();
}
public function sectionable()
{
return $this->morphOne(Sectionable::class, 'sectionable');
}
public function sections()
{
return $this->morphToMany(Section::class, 'sectionable');
}
public function objectFile()
{
return $this->belongsTo(File::class, 'object');
}
/*
|--------------------------------------------------------------------------
| OVERWRITE FUNCTIONS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public function setLessonObject(File $file = null)
{
if ($file && $file->id !== $this->object) {
$this->object = $file->id;
$this->save();
} else {
$file = File::find($this->object);
}
if (!$file) {
return;
}
$this->files()->sync($file);
$file->setPermission('public', false)->setPermission('lesson', true)->save();
}
}
================================================
FILE: app/Models/Question.php
================================================
<?php
namespace App\Models;
use App\Models\Exam;
use App\Models\Topic;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property int $id
* @property string $hint
* @property string $question
* @property array $options
* @property array $answers
* @property string $explanation
* @property int $mark
* @property int $nmark
* @property int $qtype
* @property int $created_by
* @property int $exam_id
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Carbon $deleted_at
* @property Collection<Topic> $topics
* @property Exam $exam
*/
class Question extends Model
{
use SoftDeletes, HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'qtype', 'question', 'options', 'answers', 'hint', 'mark', 'nmark', 'explanation', 'created_by'
];
protected $casts = [
'answers' => 'array',
'options' => 'array'
];
/*
|--------------------------------------------------------------------------
| ACCESORS Variables
|--------------------------------------------------------------------------
*/
public static $qtypes = [
'Objective' => 0,
'TrueFalse' => 1,
];
/*
|--------------------------------------------------------------------------
| ACCESORS
|--------------------------------------------------------------------------
*/
public function getQtypeAttribute($value)
{
$key = array_search($value, self::$qtypes);
if ($key) {
return ucfirst($key);
}
}
public function setQtypeAttribute($value)
{
$key = array_search($value, self::$qtypes);
if ($key) {
$this->attributes['qtype'] = $value;
} else {
$this->attributes['qtype'] = self::$qtypes[$value];
}
}
public function topics()
{
return $this->morphToMany(Topic::class, 'topicable');
}
public function exam()
{
return $this->belongsTo(Exam::class);
}
public function setAnswerAttribute($value)
{
$this->attributes['answers'] = json_encode($value);
}
}
================================================
FILE: app/Models/Result.php
================================================
<?php
namespace App\Models;
use App\Models\Exam;
use App\Models\User;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property int $id
* @property int $examinee
* @property int $exam_id
* @property array $answers
* @property float $obtain_mark
* @property float $time_taken
* @property boolean $is_pass
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Collection<Course> $courses
* @property Exam $exam
* @property User $examinee
*/
class Result extends Model
{
use HasFactory;
protected $fillable = ['answers', 'obtain'];
protected $casts = [
'answers' => 'array',
'is_pass' => 'bool'
];
public function exam()
{
return $this->belongsTo(Exam::class, 'exam_id');
}
public function examinee()
{
return $this->belongsTo(User::class, 'examinee');
}
public static function calculateMark($answer)
{
$count = 0;
if (!empty($answer)) {
foreach ($answer as $resultKey => $resultValue) {
$question = Question::where('id', $resultKey)->first();
if (!empty($question)) {
foreach ($question->answers as $key => $value) {
if ($resultValue == $value) {
$count = $count + $question->mark;
}
}
}
}
}
return $count;
}
}
================================================
FILE: app/Models/Role.php
================================================
<?php
namespace App\Models;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Spatie\Permission\Models\Role as ModelsRole;
/**
* @property int $id
* @property string $name
* @property string $guard_name
* @property int $course_id
* @property Carbon $created_at
* @property Carbon $updated_at
*/
class Role extends ModelsRole
{
const SUPERADMIN = 'superadmin';
const ADMIN = 'admin';
public static function appRoles(): Collection
{
return collect([Role::SUPERADMIN, Role::ADMIN]);
}
public function modifiable(): bool
{
return ! $this->appRoles()->include($this->name);
}
}
================================================
FILE: app/Models/Section.php
================================================
<?php
namespace App\Models;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property int $id
* @property string $title
* @property string $description
* @property int $course_id
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Collection<Sectionable> $sectionables
* @property Collection<Lesson> $lessons
* @property Exam<Lesson> $exams
*/
class Section extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'title', 'description', 'course_id'
];
public function sectionables()
{
return $this->hasMany(Sectionable::class, 'section_id')->orderBy('order', 'asc');
}
public function lessons()
{
return $this->morphedByMany(Lesson::class, 'sectionable')->orderBy('order', 'asc')->withPivot(['order']);
}
public function exams()
{
return $this->morphedByMany(Exam::class, 'sectionable')->orderBy('order', 'asc')->withPivot(['order']);
}
}
================================================
FILE: app/Models/Sectionable.php
================================================
<?php
namespace App\Models;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property int $id
* @property int $section_id
* @property int $sectionable_id
* @property string $sectionable_type
* @property int $order
* @property int $course_id
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Collection<Section> $sectionable
* @property Section $section
*/
class Sectionable extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $guarded = [];
public function sectionable()
{
return $this->morphTo();
}
public function section()
{
return $this->belongsTo(Section::class, 'section_id');
}
}
================================================
FILE: app/Models/Setting.php
================================================
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* @property int $id
* @property int $resource_id
* @property string $resource_type
* @property string $key
* @property string $value
*/
class Setting extends Model
{
//
}
================================================
FILE: app/Models/SocialiteProvider.php
================================================
<?php
namespace App\Models;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SocialiteProvider extends Model
{
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'socialite_providers';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
/**
* The attributes that are not mass assignable.
*
* @var array<int, string>
*/
protected $guarded = [
'id',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array<int, string>
*/
protected $hidden = [
'access_token',
'refresh_token',
];
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'user_id',
'provider',
'provider_user_id',
'access_token',
'refresh_token',
'avatar',
];
/**
* The attributes that should be cast to native types.
*
* @var array<int, string>
*/
protected $casts = [
'id' => 'integer',
'user_id' => 'integer',
'provider' => 'string',
'provider_user_id' => 'string',
'access_token' => 'string',
'refresh_token' => 'string',
'avatar' => 'string',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
/**
* Get the user that owns the socialite provider.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
================================================
FILE: app/Models/Subject.php
================================================
<?php
namespace App\Models;
use App\Models\Exam;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Storage;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property int $id
* @property int $parent
* @property string $title
* @property string $slug
* @property string $description
* @property string|null $icon
* @property string|null $image
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Collection<Course> $courses
* @property Collection<Exam> $exams
*/
class Subject extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'title', 'slug', 'description', 'icon', 'image'
];
protected $appends = ['image_url'];
public function getImageUrlAttribute(): ?string
{
if (! $this->image) {
return null;
}
return Storage::disk('public')->url($this->image);
}
/**
* Get all of the courses that are assigned this tag.
*/
public function courses()
{
return $this->morphedByMany(Course::class, 'subjectables');
}
/**
* Get all of the exams that are assigned this tag.
*/
public function exams()
{
return $this->morphedByMany(Exam::class, 'subjectables');
}
/**
* Get child subjects.
*/
public function children()
{
return $this->hasMany(Subject::class, 'parent');
}
}
================================================
FILE: app/Models/Topic.php
================================================
<?php
namespace App\Models;
use Carbon\Carbon;
use App\Models\Exam;
use App\Models\Course;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property int $id
* @property string $title
* @property string $description
* @property Carbon $created_at
* @property Carbon $updated_at
* @property Collection<Course> $courses
* @property Collection<Exam> $exams
*/
class Topic extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'title', 'description',
];
/**
* Get all of the courses that are assigned this tag.
*/
public function courses()
{
return $this->morphedByMany(Course::class, 'topicable');
}
/**
* Get all of the exams that are assigned this tag.
*/
public function exams()
{
return $this->morphedByMany(Exam::class, 'topicable');
}
}
================================================
FILE: app/Models/Traits/FileStorage.php
================================================
<?php
namespace App\Models\Traits;
use Intervention\Image\Facades\Image;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\UploadedFile;
use App\Models\File;
trait FileStorage
{
/**
* @param File $entry
* @param UploadedFile $contents
*/
public function storeUpload(UploadedFile $file, $public = 'public', $disk = null, $file_name = null)
{
if (!$disk) {
$disk = config('filesystems.default');
}
if (!$file_name) {
$file_name = $this->hash;
}
Storage::disk($disk)->putFileAs($this->file_name, $file, $file_name, $public);
$entry->updatePublicPaths($disk);
}
/**
* @param File $entry
* @param UploadedFile $contents
*/
public function storePublicUpload(UploadedFile $file, $file_name = null)
{
$this->moveFile($file, 'public', 'public', $file_name);
}
/**
* @param File $entry
* @param UploadedFile $contents
*/
public function storeLocalUpload(UploadedFile $file, $file_name = null)
{
$this->moveFile($file, 'public', 'local', $file_name);
}
}
================================================
FILE: app/Models/Traits/Fileable.php
================================================
<?php
namespace App\Models\Traits;
use App\Models\File;
trait Fileable
{
public function files()
{
return $this->morphToMany(File::class, 'fileable');
}
}
================================================
FILE: app/Models/Traits/HashesId.php
================================================
<?php
namespace App\Models\Traits;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Builder;
trait HashesId
{
public function getHashAttribute()
{
return trim(base64_encode(str_pad($this->getOriginal('id').'|', 10, 'padding')), '=');
}
public function scopeWhereHash(Builder $query, $value)
{
$id = $this->decodeHash($value);
return $query->where('id', $id);
}
public function decodeHash($hash)
{
if ((int) $hash !== 0) {
return $hash;
}
return (int) explode('|', base64_decode($hash))[0];
}
}
================================================
FILE: app/Models/Traits/Topicable.php
================================================
<?php
namespace App\Models\Traits;
use App\Models\Topic;
trait Topicable
{
/**
* Return polymorphic relationship with json casted meta.
*/
public function topics()
{
return $this->morphToMany(Topic::class, 'topicable');
}
}
================================================
FILE: app/Models/User.php
================================================
<?php
namespace App\Models;
use Carbon\Carbon;
use App\Models\Result;
use App\Pivots\StudentCasting;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
/**
* @property int $id
* @property string $name
* @property string $email
* @property string $firstname
* @property string $lastname
* @property Carbon $email_verified_at
* @property string $password
* @property Carbon $last_loged_in
* @property STDClass $avatar
* @property string $ip
* @property string $fullName
* @property Carbon $created_at
* @property Carbon $updated_at
* @property ?Carbon $deleted_at
* @property Collection<Role> $roles
* @property Collection<Result> $results
* @property Collection<Course> $instructCourses
* @property Collection<Course> $enrolledCourses
* @property Collection<Lesson> $enrolledLessons
*/
class User extends Authenticatable
{
use Notifiable, HasRoles, SoftDeletes, HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'firstname', 'lastname', 'name', 'email', 'password', 'avatar'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array<int, string>
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be append for arrays.
*
* @var array<int, string>
*/
protected $appends = [
'full_name'
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime:Y-m-d',
'password' => 'hashed',
'created_at' => 'datetime:Y-m-d',
'updated_at' => 'datetime:Y-m-d',
'deleted_at' => 'datetime:Y-m-d h:i:s'
];
}
/** --------------------Attributes--------------------------- */
public function getFullNameAttribute()
{
return "$this->firstname $this->lastname";
}
public function getAvatarAttribute($value)
{
if (!is_array($value)) {
$value = json_decode($value);
}
if (empty($value) && empty($value->avatar)) {
$value = new \STDClass();
$value->avatar = $this->get_gravatar($this->email, 200);
}
return $value;
}
/** --------------------Relations--------------------------- */
public function results()
{
return $this->hasMany(Result::class, 'examinee');
}
public function instructCourses()
{
return $this->belongsToMany(Course::class, 'course_teachers');
}
public function enrolledCourses()
{
return $this->belongsToMany(Course::class, 'course_students')->using(StudentCasting::class)->withPivot(['rating', 'progress', 'created_at', 'updated_at']);
}
public function enrolledLessons()
{
return $this->belongsToMany(Lesson::class, 'lesson_student')->using(StudentCasting::class)->withPivot(['status', 'created_at', 'updated_at']);
}
/** --------------------Methods--------------------------- */
protected function get_gravatar($email, $s = 40, $d = 'mp', $r = 'g', $img = false, $atts = array())
{
$url = 'https://www.gravatar.com/avatar/';
$url .= md5(strtolower(trim($email)));
$url .= "?s=$s&d=$d&r=$r";
if ($img) {
$url = '<img src="' . $url . '"';
foreach ($atts as $key => $val) {
$url .= ' ' . $key . '="' . $val . '"';
}
$url .= ' />';
}
return $url;
}
public function isSuperAdmin(): bool
{
return $this->hasRole(Role::SUPERADMIN);
}
public function isAdmin(): bool
{
return $this->hasAnyRole(Role::SUPERADMIN, Role::ADMIN);
}
}
================================================
FILE: app/Observers/FileObserver.php
================================================
<?php
namespace App\Observers;
use App\Models\File;
use Illuminate\Support\Facades\Auth;
class FileObserver
{
/**
* Handle the file "created" event.
*
* @param App\Models\File $file
*/
public function created(File $file)
{
$id = Auth::id();
$file->uplaoded_by = $id;
}
/**
* Handle the file "updated" event.
*
* @param App\Models\File $file
*/
public function updated(File $file)
{
}
/**
* Handle the File "deleted" event.
*
* @param App\Models\File $file
*/
public function deleting(File $file)
{
$id = Auth::id();
$file->deleted_by = $id;
}
/**
* Handle the file "deleted" event.
*
* @param App\Models\File $file
*/
public function deleted(File $file)
{
}
/**
* Handle the file "restored" event.
*
* @param App\Models\File $file
*/
public function restored(File $file)
{
}
/**
* Handle the file "force deleted" event.
*
* @param App\Models\File $file
*/
public function forceDeleted(File $file)
{
}
}
================================================
FILE: app/Pivots/StudentCasting.php
================================================
<?php
namespace App\Pivots;
use Illuminate\Database\Eloquent\Relations\MorphPivot;
class StudentCasting extends MorphPivot
{
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
}
================================================
FILE: app/Policies/CoursePolicy.php
================================================
<?php
namespace App\Policies;
use App\Models\Course;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
class CoursePolicy
{
use HandlesAuthorization;
public function before(User $user)
{
if ($user->isAdmin()) {
return true;
}
}
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return false;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, Course $model): bool
{
return false;
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return false;
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Course $model): bool
{
return false;
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, Course $model): bool
{
return false;
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, Course $model): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, Course $model): bool
{
return false;
}
}
================================================
FILE: app/Policies/ExamPolicy.php
================================================
<?php
namespace App\Policies;
use App\Models\Exam;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
class ExamPolicy
{
use HandlesAuthorization;
public function before(User $user)
{
if ($user->isAdmin()) {
return true;
}
}
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return false;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, Exam $model): bool
{
return false;
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return false;
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Exam $model): bool
{
return false;
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, Exam $model): bool
{
return false;
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, Exam $model): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, Exam $model): bool
{
return false;
}
}
================================================
FILE: app/Policies/RolePolicy.php
================================================
<?php
namespace App\Policies;
use App\Models\Role;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
class RolePolicy
{
use HandlesAuthorization;
public function before(User $user)
{
if ($user->isAdmin()) {
return true;
}
}
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return false;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, Role $model): bool
{
return false;
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return false;
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Role $model): bool
{
return false;
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, Role $model): bool
{
return false;
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, Role $model): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, Role $model): bool
{
return false;
}
}
================================================
FILE: app/Policies/SubjectPolicy.php
================================================
<?php
namespace App\Policies;
use App\Models\Subject;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
class SubjectPolicy
{
use HandlesAuthorization;
public function before(User $user)
{
if ($user->isAdmin()) {
return true;
}
}
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return false;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, Subject $model): bool
{
return false;
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return false;
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Subject $model): bool
{
return false;
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, Subject $model): bool
{
return false;
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, Subject $model): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, Subject $model): bool
{
return false;
}
}
================================================
FILE: app/Policies/TopicPolicy.php
================================================
<?php
namespace App\Policies;
use App\Models\Topic;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
class TopicPolicy
{
use HandlesAuthorization;
public function before(User $user)
{
if ($user->isAdmin()) {
return true;
}
}
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return false;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, Topic $model): bool
{
return false;
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return false;
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Topic $model): bool
{
return false;
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, Topic $model): bool
{
return false;
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, Topic $model): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, Topic $model): bool
{
return false;
}
}
================================================
FILE: app/Policies/UserPolicy.php
================================================
<?php
namespace App\Policies;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
class UserPolicy
{
use HandlesAuthorization;
public function before(User $user)
{
if ($user->isAdmin()) {
return true;
}
}
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return false;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, User $model): bool
{
return false;
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return false;
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, User $model): bool
{
return false;
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, User $model): bool
{
return false;
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, User $model): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, User $model): bool
{
return false;
}
}
================================================
FILE: app/Providers/AppServiceProvider.php
================================================
<?php
namespace App\Providers;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
//
JsonResource::withoutWrapping();
}
}
================================================
FILE: app/Response/AudioVideoResponse.php
================================================
<?php
namespace App\Response;
use Storage;
use App\Models\File;
class AudioVideoResponse
{
/**
* Stream specified video/audio file.
*
* @param File $upload
*
* @return mixed
*/
public function create(File $upload)
{
$disk = Storage::disk($upload->driver);
$size = $disk->size($upload->getStoragePath());
$time = date('r', $disk->lastModified($upload->getStoragePath()));
$fm = $disk->getDriver()->readStream($upload->getStoragePath());
$begin = 0;
$end = $size - 1;
if (isset($_SERVER['HTTP_RANGE'])) {
if (preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) {
$begin = intval($matches[1]);
if (!empty($matches[2])) {
$end = intval($matches[2]);
}
}
}
if (isset($_SERVER['HTTP_RANGE'])) {
header('HTTP/1.1 206 Partial Content');
} else {
header('HTTP/1.1 200 OK');
}
header("Content-Type: $upload->mime");
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Accept-Ranges: bytes');
header('Content-Length:'.(($end - $begin) + 1));
if (isset($_SERVER['HTTP_RANGE'])) {
header("Content-Range: bytes $begin-$end/$size");
}
header("Content-Disposition: inline; filename=$upload->file_name");
header('Content-Transfer-Encoding: binary');
header("Last-Modified: $time");
$cur = $begin;
fseek($fm, $begin, 0);
while (!feof($fm) && $cur <= $end && (connection_status() == 0)) {
echo fread($fm, min(1024 * 16, ($end - $cur) + 1));
$cur += 1024 * 16;
}
}
}
================================================
FILE: app/Response/DownloadResponse.php
================================================
<?php
namespace App\Response;
use Response;
use App\Models\File;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
// use Chumper\Zipper\Zipper;
class DownloadResponse
{
// private $zipper;
private $file;
public function __construct(File $file)
{
$this->file = $file;
// $this->zipper = $zipper;
}
/**
* Return download or preview response for given file.
*
* @param File $upload
*
* @return mixed
*/
public function singleDownload($id)
{
$upload = $this->file->whereHash($id)->firstOrFail();
if ($upload->type == 'folder') {
return $this->folderDownload($upload);
}
$headers = [
'Content-Type' => $upload->mime,
];
$filename = Str::slug(Str::before($upload->name, '.'), '-');
$filename = "$filename.$upload->extension";
$filepath = Storage::drive('uploads_local')->path($upload->getStoragePath());
return response()->download($filepath, $filename, $headers);
}
public function folderDownload($upload)
{
$zip_name = Str::random(10);
$zip_name = config('app.name').'-'.$zip_name;
$this->zipper->make(storage_path("public/$zip_name.zip"));
$this->fileRecussive($upload);
$this->zipper->close();
$headers = [
'Content-Type' => 'application/zip',
];
return response()->download(storage_path("public/$zip_name.zip"), "$zip_name.zip", $headers)->deleteFileAfterSend(true);
}
public function fileRecussive($file, $folderName = '')
{
if ($file->type == 'folder') {
$folderName = "$folderName/$file->name";
foreach ($this->file->where('parent_id', $file->id)->cursor() as $chield) {
$this->fileRecussive($chield, $folderName);
}
} else {
$filename = Str::slug(Str::before($file->name, '.'), '-');
$filename = "$filename.$file->extension";
$this->zipper->folder($folderName)->addString($filename, Storage::drive('uploads_local')->get($file->getStoragePath()));
}
}
public function multipleDownload($ids)
{
$zip_name = Str::random(10);
$zip_name = config('app.name').'-'.$zip_name;
$this->zipper->make(storage_path("public/$zip_name.zip"));
if (is_array($ids)) {
foreach ($this->file->whereIn('id', $ids)->cursor() as $chield) {
$this->fileRecussive($chield);
}
}
$this->zipper->close();
$headers = [
'Content-Type' => 'application/zip',
];
return response()->download(storage_path("public/$zip_name.zip"), "$zip_name.zip", $headers)->deleteFileAfterSend(true);
}
}
================================================
FILE: app/Response/FileBuilder.php
================================================
<?php
namespace App\Response;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Auth;
class FileBuilder
{
/**
* @param UploadedFile $file
* @param array $extra
*
* @return array
*/
public function getFileData(UploadedFile $file, $extra)
{
// TODO: move mime/extension/type guessing into separate class
$originalMime = $file->getMimeType();
if ($originalMime === 'application/octet-stream') {
$originalMime = $file->getClientMimeType();
}
$file_name = Arr::get($extra, 'file_name') ? Arr::get($extra, 'file_name') : Str::random(36);
$data = [
'name' => Arr::get($extra,
gitextract__3ge5ty2/ ├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .github/ │ └── workflows/ │ └── laravel.yml ├── .gitignore ├── .styleci.yml ├── CHANGELOG.md ├── DOCKER.md ├── Dockerfile ├── Makefile ├── README.md ├── app/ │ ├── Actions/ │ │ ├── CourseWithSections.php │ │ ├── GetEnrolledCousesAction.php │ │ └── GetInstratorCousesAction.php │ ├── Enums/ │ │ ├── Attributes/ │ │ │ └── Description.php │ │ ├── PermissionsEnum.php │ │ ├── StatusesEnum.php │ │ └── Traits/ │ │ ├── AsSelectArray.php │ │ ├── EnumToArray.php │ │ └── GetsAttributes.php │ ├── Events/ │ │ └── ExamCreated.php │ ├── Exceptions/ │ │ ├── Handler.php │ │ └── SocialProviderDeniedException.php │ ├── Helpers/ │ │ └── Functions/ │ │ └── core.php │ ├── Http/ │ │ ├── Controllers/ │ │ │ ├── API/ │ │ │ │ ├── FileController.php │ │ │ │ ├── MyCourseController.php │ │ │ │ ├── SectionableController.php │ │ │ │ └── TakeExamController.php │ │ │ ├── Admin/ │ │ │ │ ├── CourseStudentController.php │ │ │ │ ├── CoursesController.php │ │ │ │ ├── DashboardController.php │ │ │ │ ├── ExamController.php │ │ │ │ ├── LessonController.php │ │ │ │ ├── QuestionController.php │ │ │ │ ├── RolesController.php │ │ │ │ ├── SectionController.php │ │ │ │ ├── ServerInfoController.php │ │ │ │ ├── SubjectController.php │ │ │ │ ├── TopicsController.php │ │ │ │ └── UsersController.php │ │ │ ├── Auth/ │ │ │ │ ├── AuthenticatedSessionController.php │ │ │ │ ├── ConfirmablePasswordController.php │ │ │ │ ├── EmailVerificationNotificationController.php │ │ │ │ ├── EmailVerificationPromptController.php │ │ │ │ ├── NewPasswordController.php │ │ │ │ ├── PasswordController.php │ │ │ │ ├── PasswordResetLinkController.php │ │ │ │ ├── RegisteredUserController.php │ │ │ │ ├── SocialiteController.php │ │ │ │ └── VerifyEmailController.php │ │ │ ├── Controller.php │ │ │ ├── CourseController.php │ │ │ ├── DownloadController.php │ │ │ ├── HomeController.php │ │ │ ├── InstructorController.php │ │ │ ├── LearningController.php │ │ │ ├── ProfileController.php │ │ │ └── UploadController.php │ │ ├── Middleware/ │ │ │ └── HandleInertiaRequests.php │ │ ├── Requests/ │ │ │ ├── Admin/ │ │ │ │ ├── StoreCoursesRequest.php │ │ │ │ ├── UpdateCoursesRequest.php │ │ │ │ └── UserRequest.php │ │ │ ├── Auth/ │ │ │ │ └── LoginRequest.php │ │ │ ├── ExamRequest.php │ │ │ ├── ProfileUpdateRequest.php │ │ │ ├── QuestionRequest.php │ │ │ ├── SettingRequest.php │ │ │ ├── SubjectRequest.php │ │ │ └── TopicRequest.php │ │ └── Resources/ │ │ ├── CourseResource.php │ │ ├── CourseStudentsResource.php │ │ ├── ExamResource.php │ │ ├── FileResource.php │ │ ├── LessonResource.php │ │ ├── QuestionResource.php │ │ ├── ResultResource.php │ │ ├── RoleResource.php │ │ ├── SectionResource.php │ │ ├── SubjectResource.php │ │ ├── TopicResource.php │ │ └── UserResource.php │ ├── Jobs/ │ │ ├── ResizedImage.php │ │ └── UploadToCloud.php │ ├── Models/ │ │ ├── Course.php │ │ ├── Exam.php │ │ ├── File.php │ │ ├── Lesson.php │ │ ├── Question.php │ │ ├── Result.php │ │ ├── Role.php │ │ ├── Section.php │ │ ├── Sectionable.php │ │ ├── Setting.php │ │ ├── SocialiteProvider.php │ │ ├── Subject.php │ │ ├── Topic.php │ │ ├── Traits/ │ │ │ ├── FileStorage.php │ │ │ ├── Fileable.php │ │ │ ├── HashesId.php │ │ │ └── Topicable.php │ │ └── User.php │ ├── Observers/ │ │ └── FileObserver.php │ ├── Pivots/ │ │ └── StudentCasting.php │ ├── Policies/ │ │ ├── CoursePolicy.php │ │ ├── ExamPolicy.php │ │ ├── RolePolicy.php │ │ ├── SubjectPolicy.php │ │ ├── TopicPolicy.php │ │ └── UserPolicy.php │ ├── Providers/ │ │ └── AppServiceProvider.php │ ├── Response/ │ │ ├── AudioVideoResponse.php │ │ ├── DownloadResponse.php │ │ ├── FileBuilder.php │ │ ├── FileContentResponseCreator.php │ │ └── ImageResponse.php │ └── Traits/ │ ├── AppSettingsTrait.php │ └── SocialiteProvidersTrait.php ├── artisan ├── bootstrap/ │ ├── app.php │ ├── cache/ │ │ └── .gitignore │ └── providers.php ├── composer.json ├── config/ │ ├── app.php │ ├── auth.php │ ├── cache.php │ ├── database.php │ ├── filesystems.php │ ├── logging.php │ ├── mail.php │ ├── permission.php │ ├── queue.php │ ├── services.php │ └── session.php ├── database/ │ ├── .gitignore │ ├── factories/ │ │ ├── CourseFactory.php │ │ ├── ExamFactory.php │ │ ├── LessonFactory.php │ │ ├── QuestionFactory.php │ │ ├── SectionFactory.php │ │ ├── SubjectFactory.php │ │ ├── TopicFactory.php │ │ └── UserFactory.php │ ├── migrations/ │ │ ├── 0001_01_01_000000_create_users_table.php │ │ ├── 0001_01_01_000001_create_cache_table.php │ │ ├── 0001_01_01_000002_create_jobs_table.php │ │ ├── 2024_05_07_000001_create_personal_access_tokens_table.php │ │ ├── 2024_05_07_054845_create_files_table.php │ │ ├── 2024_05_07_054954_create_fileables_table.php │ │ ├── 2024_05_07_092254_create_settings_table.php │ │ ├── 2024_05_07_112940_create_permission_tables.php │ │ ├── 2024_05_07_142204_create_sections_table.php │ │ ├── 2024_05_07_145026_create_subjects_table.php │ │ ├── 2024_05_07_152004_create_sectionables_table.php │ │ ├── 2024_05_07_153027_create_exams_table.php │ │ ├── 2024_05_07_153507_create_questions_table.php │ │ ├── 2024_05_07_170835_create_topics_table.php │ │ ├── 2024_05_07_180360_create_topicables_table.php │ │ ├── 2024_05_07_190045_create_results_table.php │ │ ├── 2024_05_07_191956_create_courses_table.php │ │ ├── 2024_05_07_193251_create_lessons_table.php │ │ ├── 2024_05_07_195152_create_subjectables_table.php │ │ ├── 2024_05_07_200921_create_course_students_table.php │ │ ├── 2024_05_07_201001_create_course_teachers_table.php │ │ ├── 2024_05_07_203101_create_lesson_student_table.php │ │ ├── 2024_07_23_104822_store_last_learning.php │ │ ├── 2024_08_13_073632_create_socialite_providers_table.php │ │ └── 2026_04_25_000001_add_icon_and_image_to_subjects_table.php │ └── seeders/ │ ├── CourseSeed.php │ ├── DatabaseSeeder.php │ ├── RoleSeed.php │ ├── SubjectSeed.php │ ├── TopicSeed.php │ └── UserSeed.php ├── docker/ │ ├── nginx/ │ │ └── default.conf │ └── php/ │ └── local.ini ├── docker-compose.yml ├── package.json ├── phpstan.neon ├── phpunit.xml ├── postcss.config.js ├── public/ │ ├── .htaccess │ ├── index.php │ └── robots.txt ├── resources/ │ ├── css/ │ │ └── app.css │ ├── js/ │ │ ├── Components/ │ │ │ ├── ApplicationLogo.vue │ │ │ ├── Breadcrumb.vue │ │ │ ├── Button.vue │ │ │ ├── Card.vue │ │ │ ├── Checkbox.vue │ │ │ ├── CircleSvg.vue │ │ │ ├── Datatable/ │ │ │ │ └── Table.vue │ │ │ ├── Dropdown.vue │ │ │ ├── DropdownLink.vue │ │ │ ├── Form/ │ │ │ │ ├── Checkbox.vue │ │ │ │ ├── HeroiconPicker.vue │ │ │ │ ├── Input.vue │ │ │ │ ├── Label.vue │ │ │ │ ├── Listbox.examplevue │ │ │ │ └── Select.vue │ │ │ ├── Icon.vue │ │ │ ├── Icons/ │ │ │ │ ├── LoadingIcon.vue │ │ │ │ └── index.ts │ │ │ ├── Modal.vue │ │ │ ├── NavLink.vue │ │ │ ├── Pagination.vue │ │ │ ├── ResponsiveNavLink.vue │ │ │ ├── SocialiteLogins.vue │ │ │ └── Tabs.vue │ │ ├── Composables/ │ │ │ ├── analytics.js │ │ │ ├── common.js │ │ │ ├── useAuth.ts │ │ │ ├── useButtonGroup.ts │ │ │ ├── useFormGroup.ts │ │ │ ├── useSidebarState.ts │ │ │ ├── useUI.ts │ │ │ └── utils.ts │ │ ├── Elements/ │ │ │ ├── Course.vue │ │ │ ├── Description.vue │ │ │ ├── Lesson/ │ │ │ │ ├── Question.vue │ │ │ │ ├── Session.vue │ │ │ │ ├── SingleExam.vue │ │ │ │ ├── SingleLesson.vue │ │ │ │ └── SingleResource.vue │ │ │ ├── admin/ │ │ │ │ ├── AdminFooter.vue │ │ │ │ ├── AdminNavBar.vue │ │ │ │ ├── AdminSidebar.vue │ │ │ │ └── GHButtons.vue │ │ │ ├── course/ │ │ │ │ ├── CourseForm.vue │ │ │ │ ├── CourseLayout.vue │ │ │ │ ├── Exam.vue │ │ │ │ ├── Lesson.vue │ │ │ │ ├── LessonForm.vue │ │ │ │ ├── SectionForm.vue │ │ │ │ └── SingleSection.vue │ │ │ ├── exam/ │ │ │ │ ├── CreateExam.vue │ │ │ │ ├── CreateQuestion.vue │ │ │ │ ├── ExamLayout.vue │ │ │ │ └── QuestionTable.vue │ │ │ └── roles/ │ │ │ └── RolesBadges.vue │ │ ├── Layouts/ │ │ │ ├── AdminLayout.vue │ │ │ ├── AuthenticatedLayout.vue │ │ │ ├── GuestLayout.vue │ │ │ └── MainLayout.vue │ │ ├── Pages/ │ │ │ ├── Auth/ │ │ │ │ ├── ConfirmPassword.vue │ │ │ │ ├── ForgotPassword.vue │ │ │ │ ├── Login.vue │ │ │ │ ├── Register.vue │ │ │ │ ├── ResetPassword.vue │ │ │ │ └── VerifyEmail.vue │ │ │ ├── Course/ │ │ │ │ ├── Course.vue │ │ │ │ └── Partials/ │ │ │ │ ├── Instractor.vue │ │ │ │ └── Pricing.vue │ │ │ ├── Home/ │ │ │ │ ├── Home.vue │ │ │ │ └── Slider.vue │ │ │ ├── Instructor/ │ │ │ │ └── Courses.vue │ │ │ ├── Learning/ │ │ │ │ ├── Courses.vue │ │ │ │ └── SingleResource.vue │ │ │ ├── Profile/ │ │ │ │ ├── Edit.vue │ │ │ │ └── Partials/ │ │ │ │ ├── DeleteUserForm.vue │ │ │ │ ├── UpdatePasswordForm.vue │ │ │ │ └── UpdateProfileInformationForm.vue │ │ │ └── admin/ │ │ │ ├── Dashboard.vue │ │ │ ├── ServerInfo.vue │ │ │ ├── courses/ │ │ │ │ ├── CourseStudent.vue │ │ │ │ ├── CreateCourse.vue │ │ │ │ ├── Index.vue │ │ │ │ └── Sections.vue │ │ │ ├── exams/ │ │ │ │ ├── Create.vue │ │ │ │ ├── CreateQuestion.vue │ │ │ │ ├── Edit.vue │ │ │ │ ├── Index.vue │ │ │ │ └── Questions.vue │ │ │ ├── roles/ │ │ │ │ ├── Create.vue │ │ │ │ ├── Edit.vue │ │ │ │ └── Index.vue │ │ │ ├── subjects/ │ │ │ │ ├── Create.vue │ │ │ │ ├── Edit.vue │ │ │ │ └── Index.vue │ │ │ ├── topics/ │ │ │ │ ├── Create.vue │ │ │ │ ├── Edit.vue │ │ │ │ └── Index.vue │ │ │ └── users/ │ │ │ ├── Create.vue │ │ │ ├── Edit.vue │ │ │ └── Index.vue │ │ ├── app.ts │ │ ├── bootstrap.ts │ │ ├── types/ │ │ │ ├── forms.d.ts │ │ │ ├── global.d.ts │ │ │ ├── icons.d.ts │ │ │ ├── index.d.ts │ │ │ ├── resources.d.ts │ │ │ ├── vite-env.d.ts │ │ │ └── vuex.d.ts │ │ └── ui.config/ │ │ ├── buttonGroup.ts │ │ └── index.ts │ └── views/ │ ├── app.blade.php │ ├── errors/ │ │ ├── 401.blade.php │ │ ├── 403.blade.php │ │ ├── 500.blade.php │ │ ├── 503.blade.php │ │ └── layout.blade.php │ └── socialite/ │ ├── callback.blade.php │ └── denied.blade.php ├── routes/ │ ├── api.php │ ├── auth.php │ ├── console.php │ └── web.php ├── storage/ │ ├── app/ │ │ └── .gitignore │ ├── framework/ │ │ ├── .gitignore │ │ ├── cache/ │ │ │ └── .gitignore │ │ ├── sessions/ │ │ │ └── .gitignore │ │ ├── testing/ │ │ │ └── .gitignore │ │ └── views/ │ │ └── .gitignore │ └── logs/ │ └── .gitignore ├── tailwind.config.js ├── tests/ │ ├── Feature/ │ │ ├── Auth/ │ │ │ ├── AuthenticationTest.php │ │ │ ├── EmailVerificationTest.php │ │ │ ├── PasswordConfirmationTest.php │ │ │ ├── PasswordResetTest.php │ │ │ ├── PasswordUpdateTest.php │ │ │ └── RegistrationTest.php │ │ ├── ExampleTest.php │ │ ├── Http/ │ │ │ └── Controllers/ │ │ │ └── Admin/ │ │ │ └── UsersControllerTest.php │ │ └── ProfileTest.php │ ├── TestCase.php │ └── Unit/ │ └── ExampleTest.php ├── tsconfig.json └── vite.config.js
SYMBOL INDEX (640 symbols across 168 files)
FILE: app/Actions/CourseWithSections.php
class CourseWithSections (line 10) | class CourseWithSections
method getCourses (line 12) | public static function getCourses(Course $course)
FILE: app/Actions/GetEnrolledCousesAction.php
class GetEnrolledCousesAction (line 8) | class GetEnrolledCousesAction
method getCourses (line 10) | public static function getCourses(User $student, bool $pagination = fa...
FILE: app/Actions/GetInstratorCousesAction.php
class GetInstratorCousesAction (line 8) | class GetInstratorCousesAction
method getCourses (line 10) | public static function getCourses(User $instraotor, bool $pagination =...
FILE: app/Enums/Attributes/Description.php
class Description (line 7) | #[Attribute]
method __construct (line 10) | public function __construct(
FILE: app/Enums/StatusesEnum.php
method localizedList (line 14) | public static function localizedList(): array
FILE: app/Enums/Traits/AsSelectArray.php
type AsSelectArray (line 5) | trait AsSelectArray
method asSelectArray (line 10) | public static function asSelectArray(): array
FILE: app/Enums/Traits/EnumToArray.php
type EnumToArray (line 5) | trait EnumToArray
method names (line 7) | public static function names(): array
method values (line 12) | public static function values(): array
method array (line 17) | public static function array(): array
FILE: app/Enums/Traits/GetsAttributes.php
type GetsAttributes (line 9) | trait GetsAttributes
method getDescription (line 11) | private static function getDescription(self $enum): string
method description (line 23) | public function description(): string
FILE: app/Events/ExamCreated.php
class ExamCreated (line 14) | class ExamCreated implements ShouldBroadcast
method __construct (line 25) | public function __construct(Exam $exam)
method broadcastOn (line 35) | public function broadcastOn()
FILE: app/Exceptions/Handler.php
class Handler (line 13) | class Handler extends ExceptionHandler
method register (line 40) | public function register()
method render (line 58) | public function render($request, Throwable $e)
method sendEmail (line 84) | public function sendEmail(Throwable $exception)
FILE: app/Exceptions/SocialProviderDeniedException.php
class SocialProviderDeniedException (line 7) | class SocialProviderDeniedException extends Exception
method render (line 15) | public function render($request)
FILE: app/Helpers/Functions/core.php
function get_gravatar (line 15) | function get_gravatar( $email, $s = 40, $d = 'mp', $r = 'g', $img = fals...
FILE: app/Http/Controllers/API/FileController.php
class FileController (line 22) | class FileController extends Controller
method index (line 25) | public function index(Request $request)
method show (line 50) | public function show(Request $request, File $file)
method store (line 68) | public function store(Request $request)
method update (line 132) | public function update(Request $request, $id)
method destroy (line 159) | public function destroy(Request $request, $id)
method destroyAll (line 181) | public function destroyAll(Request $request)
method getFilePermissions (line 190) | protected function getFilePermissions(Request $request)
method getDefaultSizes (line 197) | protected function getDefaultSizes() {
method getFileData (line 210) | public function getFileData(UploadedFile $file, $extra)
method getExtension (line 246) | private function getExtension(UploadedFile $file, $mime)
method getTypeFromMime (line 268) | protected function getTypeFromMime($mime)
method createThumbanile (line 291) | public function createThumbanile (File $entry, UploadedFile $file, $si...
method moveFile (line 310) | public function moveFile(file $entry, UploadedFile $file, $public = 'p...
method storePublicUpload (line 329) | public function storePublicUpload(File $entry, UploadedFile $file, $fi...
method storeLocalUpload (line 338) | public function storeLocalUpload(File $entry, UploadedFile $file, $fil...
FILE: app/Http/Controllers/API/MyCourseController.php
class MyCourseController (line 10) | class MyCourseController extends Controller
method index (line 17) | public function index(Request $request)
method show (line 37) | public function show(Request $request, Course $course)
FILE: app/Http/Controllers/API/SectionableController.php
class SectionableController (line 12) | class SectionableController extends Controller
method lessons (line 14) | public function lessons(Request $request, Course $course)
method hasVisibility (line 43) | protected function hasVisibility (Course $course) {
FILE: app/Http/Controllers/API/TakeExamController.php
class TakeExamController (line 14) | class TakeExamController extends Controller
method show (line 16) | public function show(Request $request, Exam $exam)
method start (line 50) | public function start (Request $request, Exam $exam)
method answer (line 97) | public function answer(Request $request, Exam $exam)
method complete (line 126) | public function complete(Request $request, Exam $exam)
method obtain_mark (line 154) | private function obtain_mark(Exam $exam)
method userCanTakeExam (line 183) | private function userCanTakeExam(User $user, Exam $exam)
FILE: app/Http/Controllers/Admin/CourseStudentController.php
class CourseStudentController (line 12) | class CourseStudentController extends Controller
method __invoke (line 14) | public function __invoke(Course $course)
FILE: app/Http/Controllers/Admin/CoursesController.php
class CoursesController (line 12) | class CoursesController extends Controller
method __construct (line 14) | public function __construct()
method index (line 21) | public function index(Request $request)
method create (line 45) | public function create()
method store (line 53) | public function store(Request $request)
method edit (line 68) | public function edit(Course $course)
method update (line 76) | public function update(Request $request, course $course)
method destroy (line 90) | public function destroy(course $course)
FILE: app/Http/Controllers/Admin/DashboardController.php
class DashboardController (line 11) | class DashboardController extends Controller
method __invoke (line 20) | public function __invoke(Request $request)
FILE: app/Http/Controllers/Admin/ExamController.php
class ExamController (line 14) | class ExamController extends Controller
method __construct (line 16) | public function __construct()
method index (line 25) | public function index(Request $request)
method create (line 54) | public function create()
method store (line 64) | public function store(ExamRequest $request)
method edit (line 89) | public function edit(Exam $exam)
method update (line 101) | public function update(ExamRequest $request, Exam $exam)
method destroy (line 123) | public function destroy(Exam $exam)
FILE: app/Http/Controllers/Admin/LessonController.php
class LessonController (line 13) | class LessonController extends Controller
method index (line 20) | public function index(Request $request, Course $course)
method create (line 41) | public function create()
method store (line 53) | public function store(Request $request, Course $course)
method edit (line 88) | public function edit(Course $course, Lesson $lesson)
method update (line 103) | public function update(Request $request, Course $course, Lesson $lesson)
method destroy (line 135) | public function destroy(Course $course, Lesson $lesson)
FILE: app/Http/Controllers/Admin/QuestionController.php
class QuestionController (line 13) | class QuestionController extends Controller
method index (line 20) | public function index(Exam $exam)
method create (line 38) | public function create(Exam $exam)
method store (line 50) | public function store(Request $request, Exam $exam)
method edit (line 72) | public function edit(Exam $exam, Question $question)
method update (line 87) | public function update(Request $request, Exam $exam, Question $question)
method destroy (line 102) | public function destroy(Exam $exam, Question $question)
FILE: app/Http/Controllers/Admin/RolesController.php
class RolesController (line 13) | class RolesController extends Controller
method __construct (line 15) | public function __construct()
method index (line 22) | public function index()
method create (line 38) | public function create()
method store (line 48) | public function store(Request $request)
method show (line 69) | public function show(User $user)
method edit (line 77) | public function edit(Role $role)
method update (line 88) | public function update(Request $request, Role $role)
method destroy (line 106) | public function destroy(Role $role)
FILE: app/Http/Controllers/Admin/SectionController.php
class SectionController (line 15) | class SectionController extends Controller
method index (line 22) | public function index(Course $course, Request $request)
method store (line 43) | public function store(Course $course, Request $request)
method update (line 57) | public function update(Course $course, Section $section, Request $requ...
method destroy (line 72) | public function destroy(Course $course, Section $section)
method attachExam (line 79) | public function attachExam (Request $request, Section $section) {
method attachLession (line 86) | public function attachLession (Request $request, Section $section) {
FILE: app/Http/Controllers/Admin/ServerInfoController.php
class ServerInfoController (line 10) | class ServerInfoController extends Controller
method __construct (line 12) | public function __construct()
method index (line 24) | public function index(Request $request)
FILE: app/Http/Controllers/Admin/SubjectController.php
class SubjectController (line 13) | class SubjectController extends Controller
method __construct (line 15) | public function __construct()
method index (line 24) | public function index(Request $request)
method create (line 54) | public function create()
method store (line 67) | public function store(Request $request)
method edit (line 93) | public function edit(Subject $subject)
method update (line 111) | public function update(Request $request, Subject $subject)
method destroy (line 146) | public function destroy(Subject $subject)
FILE: app/Http/Controllers/Admin/TopicsController.php
class TopicsController (line 13) | class TopicsController extends Controller
method __construct (line 15) | public function __construct()
method index (line 23) | public function index(Request $request)
method create (line 50) | public function create()
method store (line 58) | public function store(TopicRequest $request)
method edit (line 69) | public function edit(Topic $topic)
method update (line 81) | public function update(TopicRequest $request, Topic $topic)
method destroy (line 93) | public function destroy(Topic $topic)
method bulkDelete (line 100) | public function bulkDelete(Request $request)
FILE: app/Http/Controllers/Admin/UsersController.php
class UsersController (line 14) | class UsersController extends Controller
method __construct (line 16) | public function __construct()
method index (line 23) | public function index(Request $request)
method create (line 49) | public function create()
method store (line 57) | public function store(UserRequest $request)
method show (line 79) | public function show(User $user)
method edit (line 87) | public function edit(User $user)
method update (line 95) | public function update(UserRequest $request, User $user)
method syncRoles (line 121) | public function syncRoles(Request $request, User $user)
method bulkDelete (line 138) | public function bulkDelete(Request $request)
method bulkSyncRoles (line 158) | public function bulkSyncRoles(Request $request)
method destroy (line 179) | public function destroy(User $user)
FILE: app/Http/Controllers/Auth/AuthenticatedSessionController.php
class AuthenticatedSessionController (line 14) | class AuthenticatedSessionController extends Controller
method create (line 19) | public function create(): Response
method store (line 30) | public function store(LoginRequest $request): RedirectResponse
method destroy (line 42) | public function destroy(Request $request): RedirectResponse
FILE: app/Http/Controllers/Auth/ConfirmablePasswordController.php
class ConfirmablePasswordController (line 13) | class ConfirmablePasswordController extends Controller
method show (line 18) | public function show(): Response
method store (line 26) | public function store(Request $request): RedirectResponse
FILE: app/Http/Controllers/Auth/EmailVerificationNotificationController.php
class EmailVerificationNotificationController (line 9) | class EmailVerificationNotificationController extends Controller
method store (line 14) | public function store(Request $request): RedirectResponse
FILE: app/Http/Controllers/Auth/EmailVerificationPromptController.php
class EmailVerificationPromptController (line 11) | class EmailVerificationPromptController extends Controller
method __invoke (line 16) | public function __invoke(Request $request): RedirectResponse|Response
FILE: app/Http/Controllers/Auth/NewPasswordController.php
class NewPasswordController (line 17) | class NewPasswordController extends Controller
method create (line 22) | public function create(Request $request): Response
method store (line 35) | public function store(Request $request): RedirectResponse
FILE: app/Http/Controllers/Auth/PasswordController.php
class PasswordController (line 11) | class PasswordController extends Controller
method update (line 16) | public function update(Request $request): RedirectResponse
FILE: app/Http/Controllers/Auth/PasswordResetLinkController.php
class PasswordResetLinkController (line 13) | class PasswordResetLinkController extends Controller
method create (line 18) | public function create(): Response
method store (line 30) | public function store(Request $request): RedirectResponse
FILE: app/Http/Controllers/Auth/RegisteredUserController.php
class RegisteredUserController (line 16) | class RegisteredUserController extends Controller
method create (line 21) | public function create(): Response
method store (line 31) | public function store(Request $request): RedirectResponse
FILE: app/Http/Controllers/Auth/SocialiteController.php
class SocialiteController (line 19) | class SocialiteController extends Controller
method __construct (line 26) | public function __construct()
method guard (line 37) | public function guard($guard = 'web')
method loginsEnabled (line 48) | public function loginsEnabled(Request $request)
method getSocialRedirect (line 62) | public function getSocialRedirect(Request $request, string $provider)
method handleSocialCallback (line 140) | public function handleSocialCallback(Request $request, string $provider)
method twitterUserAuthenticationUrl (line 181) | public function twitterUserAuthenticationUrl($state = null)
method twitterUserAuthentication (line 209) | public function twitterUserAuthentication(Request $request)
method revokeSocialProvider (line 239) | public function revokeSocialProvider(SocialiteProvider $provider, Requ...
FILE: app/Http/Controllers/Auth/VerifyEmailController.php
class VerifyEmailController (line 10) | class VerifyEmailController extends Controller
method __invoke (line 15) | public function __invoke(EmailVerificationRequest $request): RedirectR...
FILE: app/Http/Controllers/Controller.php
class Controller (line 9) | abstract class Controller extends BaseController
FILE: app/Http/Controllers/CourseController.php
class CourseController (line 12) | class CourseController extends Controller
method show (line 21) | public function show(Request $request, Course $course)
method subscribe (line 31) | public function subscribe(Request $request, Course $course)
FILE: app/Http/Controllers/DownloadController.php
class DownloadController (line 9) | class DownloadController extends Controller
method __construct (line 27) | public function __construct(Request $request, File $file, DownloadResp...
method download (line 35) | public function download(Request $request)
FILE: app/Http/Controllers/HomeController.php
class HomeController (line 12) | class HomeController extends Controller
method __invoke (line 19) | public function __invoke(Request $request)
FILE: app/Http/Controllers/InstructorController.php
class InstructorController (line 10) | class InstructorController extends Controller
method courses (line 19) | public function courses(Request $request)
FILE: app/Http/Controllers/LearningController.php
class LearningController (line 19) | class LearningController extends Controller
method myCourses (line 28) | public function myCourses(Request $request)
method startCourse (line 38) | public function startCourse(Course $course)
method singleResource (line 61) | public function singleResource(Course $course, $type, $slug)
FILE: app/Http/Controllers/ProfileController.php
class ProfileController (line 14) | class ProfileController extends Controller
method edit (line 19) | public function edit(Request $request): Response
method update (line 30) | public function update(ProfileUpdateRequest $request): RedirectResponse
method destroy (line 46) | public function destroy(Request $request): RedirectResponse
FILE: app/Http/Controllers/UploadController.php
class UploadController (line 8) | class UploadController extends Controller
method __invoke (line 13) | public function __invoke(FileContentResponseCreator $fileResponse, $id)
FILE: app/Http/Middleware/HandleInertiaRequests.php
class HandleInertiaRequests (line 8) | class HandleInertiaRequests extends Middleware
method version (line 20) | public function version(Request $request): string|null
method share (line 30) | public function share(Request $request): array
FILE: app/Http/Requests/Admin/StoreCoursesRequest.php
class StoreCoursesRequest (line 6) | class StoreCoursesRequest extends FormRequest
method authorize (line 13) | public function authorize()
method rules (line 23) | public function rules()
FILE: app/Http/Requests/Admin/UpdateCoursesRequest.php
class UpdateCoursesRequest (line 6) | class UpdateCoursesRequest extends FormRequest
method authorize (line 13) | public function authorize()
method rules (line 23) | public function rules()
FILE: app/Http/Requests/Admin/UserRequest.php
class UserRequest (line 7) | class UserRequest extends FormRequest
method authorize (line 12) | public function authorize(): bool
method rules (line 22) | public function rules(): array
FILE: app/Http/Requests/Auth/LoginRequest.php
class LoginRequest (line 12) | class LoginRequest extends FormRequest
method authorize (line 17) | public function authorize(): bool
method rules (line 27) | public function rules(): array
method authenticate (line 40) | public function authenticate(): void
method ensureIsNotRateLimited (line 60) | public function ensureIsNotRateLimited(): void
method throttleKey (line 81) | public function throttleKey(): string
FILE: app/Http/Requests/ExamRequest.php
class ExamRequest (line 7) | class ExamRequest extends FormRequest
method authorize (line 14) | public function authorize()
method rules (line 24) | public function rules()
FILE: app/Http/Requests/ProfileUpdateRequest.php
class ProfileUpdateRequest (line 9) | class ProfileUpdateRequest extends FormRequest
method rules (line 16) | public function rules(): array
FILE: app/Http/Requests/QuestionRequest.php
class QuestionRequest (line 7) | class QuestionRequest extends FormRequest
method authorize (line 14) | public function authorize()
method rules (line 24) | public function rules()
FILE: app/Http/Requests/SettingRequest.php
class SettingRequest (line 7) | class SettingRequest extends FormRequest
method authorize (line 14) | public function authorize()
method rules (line 24) | public function rules()
FILE: app/Http/Requests/SubjectRequest.php
class SubjectRequest (line 7) | class SubjectRequest extends FormRequest
method authorize (line 14) | public function authorize()
method rules (line 24) | public function rules()
FILE: app/Http/Requests/TopicRequest.php
class TopicRequest (line 7) | class TopicRequest extends FormRequest
method authorize (line 14) | public function authorize()
method rules (line 24) | public function rules()
FILE: app/Http/Resources/CourseResource.php
class CourseResource (line 9) | class CourseResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/CourseStudentsResource.php
class CourseStudentsResource (line 9) | class CourseStudentsResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/ExamResource.php
class ExamResource (line 9) | class ExamResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/FileResource.php
class FileResource (line 9) | class FileResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/LessonResource.php
class LessonResource (line 9) | class LessonResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/QuestionResource.php
class QuestionResource (line 9) | class QuestionResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/ResultResource.php
class ResultResource (line 9) | class ResultResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/RoleResource.php
class RoleResource (line 9) | class RoleResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/SectionResource.php
class SectionResource (line 12) | class SectionResource extends JsonResource
method toArray (line 19) | public function toArray(Request $request): array
FILE: app/Http/Resources/SubjectResource.php
class SubjectResource (line 9) | class SubjectResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/TopicResource.php
class TopicResource (line 9) | class TopicResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Http/Resources/UserResource.php
class UserResource (line 9) | class UserResource extends JsonResource
method toArray (line 16) | public function toArray(Request $request): array
FILE: app/Jobs/ResizedImage.php
class ResizedImage (line 15) | class ResizedImage implements ShouldQueue
method __construct (line 29) | public function __construct(File $file)
method handle (line 37) | public function handle()
FILE: app/Jobs/UploadToCloud.php
class UploadToCloud (line 14) | class UploadToCloud implements ShouldQueue
method __construct (line 27) | public function __construct(File $file)
method handle (line 35) | public function handle()
FILE: app/Models/Course.php
class Course (line 43) | class Course extends Model
method getRatingAttribute (line 94) | public function getRatingAttribute()
method getPermalinkAttribute (line 99) | public function getPermalinkAttribute()
method setPriceAttribute (line 107) | public function setPriceAttribute($input)
method scopeOfTeacher (line 116) | public function scopeOfTeacher($query)
method teachers (line 129) | public function teachers()
method students (line 134) | public function students()
method sections (line 139) | public function sections()
method lessons (line 144) | public function lessons()
method publishedLessons (line 149) | public function publishedLessons()
method exams (line 154) | public function exams()
method topics (line 159) | public function topics()
method subjects (line 164) | public function subjects()
method thumbnail (line 171) | public function thumbnail()
FILE: app/Models/Exam.php
class Exam (line 37) | class Exam extends Model
method subjects (line 65) | public function subjects()
method courses (line 70) | public function courses()
method questions (line 75) | public function questions()
method topics (line 79) | public function topics()
method results (line 84) | public function results()
method examiner (line 89) | public function examiner()
method calculateTotalMark (line 94) | public static function calculateTotalMark($marks)
method sectionable (line 103) | public function sectionable()
FILE: app/Models/File.php
class File (line 39) | class File extends Model
method boot (line 93) | public static function boot()
method getSizesAttribute (line 110) | public function getSizesAttribute()
method children (line 136) | public function children()
method parent (line 144) | public function parent()
method uploader (line 149) | public function uploader()
method setPermission (line 163) | public function setPermission($permission, $value)
method getPermission (line 173) | public function getPermission($permission = null)
method hasPermission (line 187) | public function hasPermission($permission)
method setImageSize (line 192) | public function setImageSize($size)
method getImageSizes (line 201) | public function getImageSizes()
method updatePublicPaths (line 206) | public function updatePublicPaths($driver = null)
method getStoragePath (line 220) | public function getStoragePath($prefix = null)
method setImageSizes (line 230) | public function setImageSizes(array $sizes)
FILE: app/Models/Lesson.php
class Lesson (line 38) | class Lesson extends Model
method getTypeAttribute (line 92) | public function getTypeAttribute($value)
method setTypeAttribute (line 101) | public function setTypeAttribute($value)
method getStatusAttribute (line 113) | public function getStatusAttribute($value)
method setStatusAttribute (line 122) | public function setStatusAttribute($value)
method getObjectAttribute (line 134) | public function getObjectAttribute($value)
method scopePublished (line 144) | public function scopePublished($query)
method courses (line 154) | public function courses()
method students (line 159) | public function students()
method sectionable (line 164) | public function sectionable()
method sections (line 169) | public function sections()
method objectFile (line 174) | public function objectFile()
method setLessonObject (line 190) | public function setLessonObject(File $file = null)
FILE: app/Models/Question.php
class Question (line 32) | class Question extends Model
method getQtypeAttribute (line 65) | public function getQtypeAttribute($value)
method setQtypeAttribute (line 74) | public function setQtypeAttribute($value)
method topics (line 85) | public function topics()
method exam (line 90) | public function exam()
method setAnswerAttribute (line 95) | public function setAnswerAttribute($value)
FILE: app/Models/Result.php
class Result (line 27) | class Result extends Model
method exam (line 38) | public function exam()
method examinee (line 43) | public function examinee()
method calculateMark (line 48) | public static function calculateMark($answer)
FILE: app/Models/Role.php
class Role (line 17) | class Role extends ModelsRole
method appRoles (line 22) | public static function appRoles(): Collection
method modifiable (line 27) | public function modifiable(): bool
FILE: app/Models/Section.php
class Section (line 22) | class Section extends Model
method sectionables (line 34) | public function sectionables()
method lessons (line 40) | public function lessons()
method exams (line 45) | public function exams()
FILE: app/Models/Sectionable.php
class Sectionable (line 23) | class Sectionable extends Model
method sectionable (line 34) | public function sectionable()
method section (line 39) | public function section()
FILE: app/Models/Setting.php
class Setting (line 14) | class Setting extends Model
FILE: app/Models/SocialiteProvider.php
class SocialiteProvider (line 9) | class SocialiteProvider extends Model
method user (line 82) | public function user()
FILE: app/Models/Subject.php
class Subject (line 25) | class Subject extends Model
method getImageUrlAttribute (line 39) | public function getImageUrlAttribute(): ?string
method courses (line 50) | public function courses()
method exams (line 58) | public function exams()
method children (line 66) | public function children()
FILE: app/Models/Topic.php
class Topic (line 22) | class Topic extends Model
method courses (line 37) | public function courses()
method exams (line 45) | public function exams()
FILE: app/Models/Traits/FileStorage.php
type FileStorage (line 12) | trait FileStorage
method storeUpload (line 20) | public function storeUpload(UploadedFile $file, $public = 'public', $d...
method storePublicUpload (line 39) | public function storePublicUpload(UploadedFile $file, $file_name = null)
method storeLocalUpload (line 48) | public function storeLocalUpload(UploadedFile $file, $file_name = null)
FILE: app/Models/Traits/Fileable.php
type Fileable (line 7) | trait Fileable
method files (line 9) | public function files()
FILE: app/Models/Traits/HashesId.php
type HashesId (line 8) | trait HashesId
method getHashAttribute (line 10) | public function getHashAttribute()
method scopeWhereHash (line 15) | public function scopeWhereHash(Builder $query, $value)
method decodeHash (line 22) | public function decodeHash($hash)
FILE: app/Models/Traits/Topicable.php
type Topicable (line 7) | trait Topicable
method topics (line 12) | public function topics()
FILE: app/Models/User.php
class User (line 39) | class User extends Authenticatable
method casts (line 74) | protected function casts(): array
method getFullNameAttribute (line 86) | public function getFullNameAttribute()
method getAvatarAttribute (line 91) | public function getAvatarAttribute($value)
method results (line 107) | public function results()
method instructCourses (line 112) | public function instructCourses()
method enrolledCourses (line 117) | public function enrolledCourses()
method enrolledLessons (line 122) | public function enrolledLessons()
method get_gravatar (line 129) | protected function get_gravatar($email, $s = 40, $d = 'mp', $r = 'g', ...
method isSuperAdmin (line 144) | public function isSuperAdmin(): bool
method isAdmin (line 149) | public function isAdmin(): bool
FILE: app/Observers/FileObserver.php
class FileObserver (line 8) | class FileObserver
method created (line 15) | public function created(File $file)
method updated (line 26) | public function updated(File $file)
method deleting (line 35) | public function deleting(File $file)
method deleted (line 46) | public function deleted(File $file)
method restored (line 55) | public function restored(File $file)
method forceDeleted (line 64) | public function forceDeleted(File $file)
FILE: app/Pivots/StudentCasting.php
class StudentCasting (line 7) | class StudentCasting extends MorphPivot
FILE: app/Policies/CoursePolicy.php
class CoursePolicy (line 10) | class CoursePolicy
method before (line 14) | public function before(User $user)
method viewAny (line 24) | public function viewAny(User $user): bool
method view (line 32) | public function view(User $user, Course $model): bool
method create (line 40) | public function create(User $user): bool
method update (line 48) | public function update(User $user, Course $model): bool
method delete (line 56) | public function delete(User $user, Course $model): bool
method restore (line 64) | public function restore(User $user, Course $model): bool
method forceDelete (line 72) | public function forceDelete(User $user, Course $model): bool
FILE: app/Policies/ExamPolicy.php
class ExamPolicy (line 10) | class ExamPolicy
method before (line 14) | public function before(User $user)
method viewAny (line 24) | public function viewAny(User $user): bool
method view (line 32) | public function view(User $user, Exam $model): bool
method create (line 40) | public function create(User $user): bool
method update (line 48) | public function update(User $user, Exam $model): bool
method delete (line 56) | public function delete(User $user, Exam $model): bool
method restore (line 64) | public function restore(User $user, Exam $model): bool
method forceDelete (line 72) | public function forceDelete(User $user, Exam $model): bool
FILE: app/Policies/RolePolicy.php
class RolePolicy (line 10) | class RolePolicy
method before (line 14) | public function before(User $user)
method viewAny (line 24) | public function viewAny(User $user): bool
method view (line 32) | public function view(User $user, Role $model): bool
method create (line 40) | public function create(User $user): bool
method update (line 48) | public function update(User $user, Role $model): bool
method delete (line 56) | public function delete(User $user, Role $model): bool
method restore (line 64) | public function restore(User $user, Role $model): bool
method forceDelete (line 72) | public function forceDelete(User $user, Role $model): bool
FILE: app/Policies/SubjectPolicy.php
class SubjectPolicy (line 10) | class SubjectPolicy
method before (line 14) | public function before(User $user)
method viewAny (line 24) | public function viewAny(User $user): bool
method view (line 32) | public function view(User $user, Subject $model): bool
method create (line 40) | public function create(User $user): bool
method update (line 48) | public function update(User $user, Subject $model): bool
method delete (line 56) | public function delete(User $user, Subject $model): bool
method restore (line 64) | public function restore(User $user, Subject $model): bool
method forceDelete (line 72) | public function forceDelete(User $user, Subject $model): bool
FILE: app/Policies/TopicPolicy.php
class TopicPolicy (line 10) | class TopicPolicy
method before (line 14) | public function before(User $user)
method viewAny (line 24) | public function viewAny(User $user): bool
method view (line 32) | public function view(User $user, Topic $model): bool
method create (line 40) | public function create(User $user): bool
method update (line 48) | public function update(User $user, Topic $model): bool
method delete (line 56) | public function delete(User $user, Topic $model): bool
method restore (line 64) | public function restore(User $user, Topic $model): bool
method forceDelete (line 72) | public function forceDelete(User $user, Topic $model): bool
FILE: app/Policies/UserPolicy.php
class UserPolicy (line 9) | class UserPolicy
method before (line 13) | public function before(User $user)
method viewAny (line 23) | public function viewAny(User $user): bool
method view (line 31) | public function view(User $user, User $model): bool
method create (line 39) | public function create(User $user): bool
method update (line 47) | public function update(User $user, User $model): bool
method delete (line 55) | public function delete(User $user, User $model): bool
method restore (line 63) | public function restore(User $user, User $model): bool
method forceDelete (line 71) | public function forceDelete(User $user, User $model): bool
FILE: app/Providers/AppServiceProvider.php
class AppServiceProvider (line 8) | class AppServiceProvider extends ServiceProvider
method register (line 13) | public function register(): void
method boot (line 21) | public function boot(): void
FILE: app/Response/AudioVideoResponse.php
class AudioVideoResponse (line 8) | class AudioVideoResponse
method create (line 17) | public function create(File $upload)
FILE: app/Response/DownloadResponse.php
class DownloadResponse (line 12) | class DownloadResponse
method __construct (line 18) | public function __construct(File $file)
method singleDownload (line 31) | public function singleDownload($id)
method folderDownload (line 52) | public function folderDownload($upload)
method fileRecussive (line 69) | public function fileRecussive($file, $folderName = '')
method multipleDownload (line 85) | public function multipleDownload($ids)
FILE: app/Response/FileBuilder.php
class FileBuilder (line 9) | class FileBuilder
method getFileData (line 17) | public function getFileData(UploadedFile $file, $extra)
FILE: app/Response/FileContentResponseCreator.php
class FileContentResponseCreator (line 9) | class FileContentResponseCreator
method __construct (line 31) | public function __construct(ImageResponse $imageResponse, AudioVideoRe...
method create (line 44) | public function create(File $upload)
method createBasicResponse (line 68) | private function createBasicResponse(File $upload)
method getTypeFromModel (line 80) | private function getTypeFromModel(File $fileModel)
method shouldStream (line 96) | private function shouldStream($mime, $type)
FILE: app/Response/ImageResponse.php
class ImageResponse (line 9) | class ImageResponse
method create (line 19) | public function create(File $upload)
FILE: app/Traits/AppSettingsTrait.php
type AppSettingsTrait (line 8) | trait AppSettingsTrait
method processSettingForAdditionalAppChanges (line 16) | public function processSettingForAdditionalAppChanges(Setting $setting)
method setEnv (line 223) | public function setEnv(string $key, $value, $configed = null)
FILE: app/Traits/SocialiteProvidersTrait.php
type SocialiteProvidersTrait (line 21) | trait SocialiteProvidersTrait
method __construct (line 26) | public function __construct()
method setupProviders (line 34) | protected function setupProviders()
method setProviderSettings (line 44) | protected function setProviderSettings()
method setProviderConfigs (line 151) | protected function setProviderConfigs()
method setAppProvidersConfigs (line 403) | protected function setAppProvidersConfigs()
method loginsList (line 413) | protected function loginsList()
method findOrCreateUser (line 469) | protected function findOrCreateUser(string $provider, $user, string $s...
method updateOrCreateUser (line 546) | protected function updateOrCreateUser(string $provider, $sUser, $exist...
method addSocialiteProviderToUser (line 623) | protected function addSocialiteProviderToUser(User $user, $data): Soci...
method generateTempId (line 652) | protected function generateTempId($depth = 40)
method cacheStatePutKeyInUrl (line 665) | protected function cacheStatePutKeyInUrl($url = null, $state = null)
method tempStoreStateInCache (line 681) | protected function tempStoreStateInCache($tempId, $state, $seconds = 60)
FILE: database/factories/CourseFactory.php
class CourseFactory (line 11) | class CourseFactory extends Factory
method definition (line 18) | public function definition()
FILE: database/factories/ExamFactory.php
class ExamFactory (line 11) | class ExamFactory extends Factory
method definition (line 18) | public function definition()
FILE: database/factories/LessonFactory.php
class LessonFactory (line 11) | class LessonFactory extends Factory
method definition (line 18) | public function definition()
FILE: database/factories/QuestionFactory.php
class QuestionFactory (line 11) | class QuestionFactory extends Factory
method definition (line 18) | public function definition()
FILE: database/factories/SectionFactory.php
class SectionFactory (line 10) | class SectionFactory extends Factory
method definition (line 17) | public function definition()
FILE: database/factories/SubjectFactory.php
class SubjectFactory (line 10) | class SubjectFactory extends Factory
method definition (line 17) | public function definition()
FILE: database/factories/TopicFactory.php
class TopicFactory (line 10) | class TopicFactory extends Factory
method definition (line 17) | public function definition()
FILE: database/factories/UserFactory.php
class UserFactory (line 12) | class UserFactory extends Factory
method definition (line 24) | public function definition(): array
method unverified (line 42) | public function unverified(): static
method banned (line 49) | public function banned(): static
FILE: database/migrations/0001_01_01_000000_create_users_table.php
method up (line 12) | public function up(): void
method down (line 49) | public function down(): void
FILE: database/migrations/0001_01_01_000001_create_cache_table.php
method up (line 12) | public function up(): void
method down (line 30) | public function down(): void
FILE: database/migrations/0001_01_01_000002_create_jobs_table.php
method up (line 12) | public function up(): void
method down (line 51) | public function down(): void
FILE: database/migrations/2024_05_07_000001_create_personal_access_tokens_table.php
method up (line 14) | public function up()
method down (line 32) | public function down()
FILE: database/migrations/2024_05_07_054845_create_files_table.php
method up (line 14) | public function up()
method down (line 49) | public function down()
FILE: database/migrations/2024_05_07_054954_create_fileables_table.php
method up (line 14) | public function up()
method down (line 32) | public function down()
FILE: database/migrations/2024_05_07_092254_create_settings_table.php
method up (line 12) | public function up(): void
method down (line 25) | public function down(): void
FILE: database/migrations/2024_05_07_112940_create_permission_tables.php
method up (line 12) | public function up(): void
method down (line 124) | public function down(): void
FILE: database/migrations/2024_05_07_142204_create_sections_table.php
method up (line 14) | public function up()
method down (line 30) | public function down()
FILE: database/migrations/2024_05_07_145026_create_subjects_table.php
method up (line 14) | public function up()
method down (line 31) | public function down()
FILE: database/migrations/2024_05_07_152004_create_sectionables_table.php
method up (line 14) | public function up()
method down (line 31) | public function down()
FILE: database/migrations/2024_05_07_153027_create_exams_table.php
method up (line 14) | public function up()
method down (line 44) | public function down()
FILE: database/migrations/2024_05_07_153507_create_questions_table.php
method up (line 14) | public function up()
method down (line 42) | public function down()
FILE: database/migrations/2024_05_07_170835_create_topics_table.php
method up (line 14) | public function up()
method down (line 29) | public function down()
FILE: database/migrations/2024_05_07_180360_create_topicables_table.php
method up (line 14) | public function up()
method down (line 33) | public function down()
FILE: database/migrations/2024_05_07_190045_create_results_table.php
method up (line 14) | public function up()
method down (line 33) | public function down()
FILE: database/migrations/2024_05_07_191956_create_courses_table.php
method up (line 14) | public function up()
method down (line 47) | public function down()
FILE: database/migrations/2024_05_07_193251_create_lessons_table.php
method up (line 14) | public function up()
method down (line 43) | public function down()
FILE: database/migrations/2024_05_07_195152_create_subjectables_table.php
method up (line 14) | public function up()
method down (line 33) | public function down()
FILE: database/migrations/2024_05_07_200921_create_course_students_table.php
method up (line 14) | public function up()
method down (line 32) | public function down()
FILE: database/migrations/2024_05_07_201001_create_course_teachers_table.php
method up (line 14) | public function up()
method down (line 29) | public function down()
FILE: database/migrations/2024_05_07_203101_create_lesson_student_table.php
method up (line 14) | public function up()
method down (line 31) | public function down()
FILE: database/migrations/2024_07_23_104822_store_last_learning.php
method up (line 12) | public function up(): void
method down (line 22) | public function down(): void
FILE: database/migrations/2024_08_13_073632_create_socialite_providers_table.php
method up (line 14) | public function up()
method down (line 35) | public function down()
FILE: database/migrations/2026_04_25_000001_add_icon_and_image_to_subjects_table.php
method up (line 9) | public function up(): void
method down (line 17) | public function down(): void
FILE: database/seeders/CourseSeed.php
class CourseSeed (line 14) | class CourseSeed extends Seeder
method run (line 21) | public function run()
FILE: database/seeders/DatabaseSeeder.php
class DatabaseSeeder (line 9) | class DatabaseSeeder extends Seeder
method run (line 16) | public function run()
FILE: database/seeders/RoleSeed.php
class RoleSeed (line 11) | class RoleSeed extends Seeder
method run (line 18) | public function run()
FILE: database/seeders/SubjectSeed.php
class SubjectSeed (line 11) | class SubjectSeed extends Seeder
method generateImage (line 41) | private function generateImage(): string
method run (line 66) | public function run(): void
FILE: database/seeders/TopicSeed.php
class TopicSeed (line 8) | class TopicSeed extends Seeder
method run (line 15) | public function run()
FILE: database/seeders/UserSeed.php
class UserSeed (line 9) | class UserSeed extends Seeder
method run (line 16) | public function run()
FILE: resources/js/Composables/analytics.js
function track (line 4) | function track(
FILE: resources/js/Composables/common.js
function parseDisplayDate (line 5) | function parseDisplayDate(date) {
function capitalizeFirstLetter (line 10) | function capitalizeFirstLetter(str) {
function greeting (line 22) | function greeting() {
function providerIcon (line 36) | function providerIcon(provider = null) {
FILE: resources/js/Composables/useAuth.ts
function useAuth (line 4) | function useAuth() {
FILE: resources/js/Composables/useButtonGroup.ts
type ButtonGroupProps (line 5) | type ButtonGroupProps = {
type ButtonGroupContext (line 13) | type ButtonGroupContext = {
function useProvideButtonGroup (line 23) | function useProvideButtonGroup (buttonGroupProps: ButtonGroupProps) {
function useInjectButtonGroup (line 42) | function useInjectButtonGroup ({ ui, props }: { ui: any, props: any }) {
FILE: resources/js/Composables/useFormGroup.ts
type InputProps (line 6) | type InputProps = {
function emitFormEvent (line 34) | function emitFormEvent (type: FormEventType, path: string) {
function emitFormBlur (line 40) | function emitFormBlur () {
function emitFormChange (line 45) | function emitFormChange () {
FILE: resources/js/Composables/useSidebarState.ts
function toggleSidebar (line 9) | function toggleSidebar() {
function toggleFullScreenSidebar (line 15) | function toggleFullScreenSidebar() {
FILE: resources/js/Composables/utils.ts
function mergeConfig (line 36) | function mergeConfig<T> (strategy: Strategy, ...configs: any): T {
function hexToRgb (line 44) | function hexToRgb (hex: string) {
function getSlotsChildren (line 57) | function getSlotsChildren (slots: any) {
function looseToNumber (line 80) | function looseToNumber (val: any): any {
function omit (line 85) | function omit<T extends Record<string, any>, K extends keyof T> (
function get (line 98) | function get (object: Record<string, any>, path: (string | number)[] | s...
function useId (line 119) | function useId(prefix?: string, length: number = 10): string {
function slugify (line 130) | function slugify (string: string): string {
FILE: resources/js/app.ts
method setup (line 14) | setup({ el, App, props, plugin }) {
FILE: resources/js/types/forms.d.ts
type FormError (line 3) | interface FormError<T extends string = string> {
type FormErrorWithId (line 8) | interface FormErrorWithId extends FormError {
type Form (line 12) | interface Form<T> {
type FormSubmitEvent (line 22) | type FormSubmitEvent<T> = SubmitEvent & { data: T }
type FormErrorEvent (line 23) | type FormErrorEvent = SubmitEvent & { errors: FormErrorWithId[] }
type FormEventType (line 25) | type FormEventType = 'blur' | 'input' | 'change' | 'submit'
type FormEvent (line 27) | interface FormEvent {
type InjectedFormGroupValue (line 32) | interface InjectedFormGroupValue {
type Sizes (line 40) | type Sizes = '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
type InputColor (line 41) | type InputColor = 'white' | 'gray' | 'red';
type InputVariant (line 42) | type InputVariant = 'outline' | 'none';
FILE: resources/js/types/global.d.ts
type Window (line 7) | interface Window {
type ComponentCustomProperties (line 15) | interface ComponentCustomProperties {
type PageProps (line 21) | interface PageProps extends InertiaPageProps, AppPageProps {}
FILE: resources/js/types/icons.d.ts
type CustomIconName (line 2) | type CustomIconName = "LoadingIcon";
type HeroIconName (line 4) | type HeroIconName = keyof typeof solid
type IconName (line 6) | type IconName = HeroIconName | CustomIconName;
FILE: resources/js/types/index.d.ts
type Strategy (line 6) | type Strategy = 'merge' | 'override'
type PageProps (line 8) | type PageProps<T extends Record<string, unknown> = Record<string, unknow...
FILE: resources/js/types/resources.d.ts
type User (line 1) | interface User {
type Student (line 19) | interface Student {
type Role (line 28) | interface Role {
type Topic (line 35) | interface Topic {
type Section (line 46) | interface Section {
type Result (line 56) | interface Result {
type QuestionOption (line 67) | interface QuestionOption {
type Question (line 72) | interface Question {
type Lesson (line 88) | interface Lesson {
type File (line 105) | interface File {
type Subject (line 120) | interface Subject {
type Exam (line 139) | interface Exam {
type Course (line 161) | interface Course {
type LinkType (line 192) | interface LinkType {
type JsonResponse (line 199) | interface JsonResponse<T> {
type PaginationLink (line 211) | interface PaginationLink {
type LaravelPagination (line 217) | interface LaravelPagination {
FILE: tests/Feature/Auth/AuthenticationTest.php
class AuthenticationTest (line 9) | class AuthenticationTest extends TestCase
method test_login_screen_can_be_rendered (line 13) | public function test_login_screen_can_be_rendered(): void
method test_users_can_authenticate_using_the_login_screen (line 20) | public function test_users_can_authenticate_using_the_login_screen(): ...
method test_users_can_not_authenticate_with_invalid_password (line 33) | public function test_users_can_not_authenticate_with_invalid_password(...
method test_users_can_logout (line 45) | public function test_users_can_logout(): void
FILE: tests/Feature/Auth/EmailVerificationTest.php
class EmailVerificationTest (line 12) | class EmailVerificationTest extends TestCase
method test_email_verification_screen_can_be_rendered (line 16) | public function test_email_verification_screen_can_be_rendered(): void
method test_email_can_be_verified (line 25) | public function test_email_can_be_verified(): void
method test_email_is_not_verified_with_invalid_hash (line 44) | public function test_email_is_not_verified_with_invalid_hash(): void
FILE: tests/Feature/Auth/PasswordConfirmationTest.php
class PasswordConfirmationTest (line 9) | class PasswordConfirmationTest extends TestCase
method test_confirm_password_screen_can_be_rendered (line 13) | public function test_confirm_password_screen_can_be_rendered(): void
method test_password_can_be_confirmed (line 22) | public function test_password_can_be_confirmed(): void
method test_password_is_not_confirmed_with_invalid_password (line 34) | public function test_password_is_not_confirmed_with_invalid_password()...
FILE: tests/Feature/Auth/PasswordResetTest.php
class PasswordResetTest (line 11) | class PasswordResetTest extends TestCase
method test_reset_password_link_screen_can_be_rendered (line 15) | public function test_reset_password_link_screen_can_be_rendered(): void
method test_reset_password_link_can_be_requested (line 22) | public function test_reset_password_link_can_be_requested(): void
method test_reset_password_screen_can_be_rendered (line 33) | public function test_reset_password_screen_can_be_rendered(): void
method test_password_can_be_reset_with_valid_token (line 50) | public function test_password_can_be_reset_with_valid_token(): void
FILE: tests/Feature/Auth/PasswordUpdateTest.php
class PasswordUpdateTest (line 10) | class PasswordUpdateTest extends TestCase
method test_password_can_be_updated (line 14) | public function test_password_can_be_updated(): void
method test_correct_password_must_be_provided_to_update_password (line 34) | public function test_correct_password_must_be_provided_to_update_passw...
FILE: tests/Feature/Auth/RegistrationTest.php
class RegistrationTest (line 8) | class RegistrationTest extends TestCase
method test_registration_screen_can_be_rendered (line 12) | public function test_registration_screen_can_be_rendered(): void
method test_new_users_can_register (line 19) | public function test_new_users_can_register(): void
FILE: tests/Feature/ExampleTest.php
class ExampleTest (line 8) | class ExampleTest extends TestCase
method test_the_application_returns_a_successful_response (line 13) | public function test_the_application_returns_a_successful_response(): ...
FILE: tests/Feature/Http/Controllers/Admin/UsersControllerTest.php
class UsersControllerTest (line 9) | class UsersControllerTest extends TestCase
method test_example (line 14) | public function test_example(): void
FILE: tests/Feature/ProfileTest.php
class ProfileTest (line 9) | class ProfileTest extends TestCase
method test_profile_page_is_displayed (line 13) | public function test_profile_page_is_displayed(): void
method test_profile_information_can_be_updated (line 24) | public function test_profile_information_can_be_updated(): void
method test_email_verification_status_is_unchanged_when_the_email_address_is_unchanged (line 46) | public function test_email_verification_status_is_unchanged_when_the_e...
method test_user_can_delete_their_account (line 64) | public function test_user_can_delete_their_account(): void
method test_correct_password_must_be_provided_to_delete_account (line 82) | public function test_correct_password_must_be_provided_to_delete_accou...
FILE: tests/TestCase.php
class TestCase (line 7) | abstract class TestCase extends BaseTestCase
FILE: tests/Unit/ExampleTest.php
class ExampleTest (line 7) | class ExampleTest extends TestCase
method test_that_true_is_true (line 12) | public function test_that_true_is_true(): void
Condensed preview — 328 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (944K chars).
[
{
"path": ".dockerignore",
"chars": 417,
"preview": "# Git\n.git\n.gitignore\n.gitattributes\n\n# Environment\n.env\n.env.*\n!.env.example\n\n# IDE\n.idea\n.vscode\n*.sublime*\n\n# OS\n.DS_"
},
{
"path": ".editorconfig",
"chars": 258,
"preview": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 4\nindent_style = space\ninsert_final_newline = true\ntrim_"
},
{
"path": ".gitattributes",
"chars": 186,
"preview": "* text=auto eol=lf\n\n*.blade.php diff=html\n*.css diff=css\n*.html diff=html\n*.md diff=markdown\n*.php diff=php\n\n/.github ex"
},
{
"path": ".github/workflows/laravel.yml",
"chars": 1270,
"preview": "name: Laravel\n\non:\n push:\n branches: [ \"main\" ]\n pull_request:\n branches: [ \"main\" ]\n\njobs:\n laravel-tests:\n\n "
},
{
"path": ".gitignore",
"chars": 278,
"preview": "/.phpunit.cache\n/node_modules\n/public/build\n/public/hot\n/public/storage\n/storage/*.key\n/vendor\n.env\n.env.backup\n.env.pro"
},
{
"path": ".styleci.yml",
"chars": 120,
"preview": "php:\n preset: laravel\n disabled:\n - no_unused_imports\n finder:\n not-name:\n - index.php\njs: true\ncss: true\n"
},
{
"path": "CHANGELOG.md",
"chars": 2775,
"preview": "# Release Notes\n\n## [Unreleased](https://github.com/laravel/laravel/compare/v11.0.7...11.x)\n\n## [v11.0.7](https://github"
},
{
"path": "DOCKER.md",
"chars": 4974,
"preview": "# Docker Setup for Examinee Application\n\n## Quick Start\n\n### 1. Build and start the containers\n```bash\ndocker compose up"
},
{
"path": "Dockerfile",
"chars": 1118,
"preview": "FROM php:8.3-fpm\n\n# Set working directory\nWORKDIR /var/www/html\n\n# Install system dependencies\nRUN apt-get update && apt"
},
{
"path": "Makefile",
"chars": 5065,
"preview": ".PHONY: help build up down restart logs shell composer artisan migrate fresh test clean\n\n# Colors for output\nBLUE=\\033[0"
},
{
"path": "README.md",
"chars": 1577,
"preview": "# examinee on Online exam system\n“examinee” is a platform for Schools, Colleges, Institute & Coaching Centers. With the "
},
{
"path": "app/Actions/CourseWithSections.php",
"chars": 1246,
"preview": "<?php\nnamespace App\\Actions;\n\nuse App\\Http\\Resources\\CourseResource;\nuse App\\Models\\Course;\nuse App\\Models\\Section;\nuse "
},
{
"path": "app/Actions/GetEnrolledCousesAction.php",
"chars": 443,
"preview": "<?php\nnamespace App\\Actions;\n\nuse App\\Models\\User;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Paginatio"
},
{
"path": "app/Actions/GetInstratorCousesAction.php",
"chars": 453,
"preview": "<?php\nnamespace App\\Actions;\n\nuse App\\Models\\User;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Paginatio"
},
{
"path": "app/Enums/Attributes/Description.php",
"chars": 199,
"preview": "<?php\n\nnamespace App\\Domain\\Common\\Enums\\Attributes;\n\nuse Attribute;\n\n#[Attribute]\nclass Description\n{\n public functi"
},
{
"path": "app/Enums/PermissionsEnum.php",
"chars": 61,
"preview": "<?php\n\nnamespace App\\Enums;\n\nenum PermissionsEnum\n{\n //\n}\n"
},
{
"path": "app/Enums/StatusesEnum.php",
"chars": 426,
"preview": "<?php\n\nnamespace App\\Domain\\Common\\Enums;\n\nuse App\\Domain\\Common\\Enums\\Traits\\EnumToArray;\n\nenum StatusesEnum: string\n{\n"
},
{
"path": "app/Enums/Traits/AsSelectArray.php",
"chars": 515,
"preview": "<?php\n\nnamespace App\\Domain\\Common\\Enums\\Traits;\n\ntrait AsSelectArray\n{\n /**\n * @return array<string,string>\n "
},
{
"path": "app/Enums/Traits/EnumToArray.php",
"chars": 403,
"preview": "<?php\n\nnamespace App\\Domain\\Common\\Enums\\Traits;\n\ntrait EnumToArray\n{\n public static function names(): array\n {\n "
},
{
"path": "app/Enums/Traits/GetsAttributes.php",
"chars": 666,
"preview": "<?php\n\nnamespace App\\Domain\\Common\\Enums\\Traits;\n\nuse App\\Domain\\Common\\Enums\\Attributes\\Description;\nuse Illuminate\\Sup"
},
{
"path": "app/Events/ExamCreated.php",
"chars": 887,
"preview": "<?php\n\nnamespace App\\Events;\n\nuse App\\Models\\Exam;\nuse Illuminate\\Broadcasting\\Channel;\nuse Illuminate\\Queue\\SerializesM"
},
{
"path": "app/Exceptions/Handler.php",
"chars": 2699,
"preview": "<?php\n\nnamespace App\\Exceptions;\n\nuse App\\Mail\\ExceptionOccured;\nuse Illuminate\\Foundation\\Exceptions\\Handler as Excepti"
},
{
"path": "app/Exceptions/SocialProviderDeniedException.php",
"chars": 382,
"preview": "<?php\n\nnamespace App\\Exceptions;\n\nuse Exception;\n\nclass SocialProviderDeniedException extends Exception\n{\n /**\n *"
},
{
"path": "app/Helpers/Functions/core.php",
"chars": 1086,
"preview": "<?php\n\n/**\n * Get either a Gravatar URL or complete image tag for a specified email address.\n *\n * @param string $email "
},
{
"path": "app/Http/Controllers/API/FileController.php",
"chars": 10037,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\API;\n\nuse App\\Models\\File;\nuse App\\Http\\Controllers\\Controller;\nuse App\\Jobs\\Uploa"
},
{
"path": "app/Http/Controllers/API/MyCourseController.php",
"chars": 1051,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\API;\n\nuse App\\Models\\Course;\nuse Illuminate\\Http\\Request;\nuse App\\Http\\Controllers"
},
{
"path": "app/Http/Controllers/API/SectionableController.php",
"chars": 1376,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\API;\n\nuse App\\Models\\Course;\nuse App\\Models\\Sectionable;\nuse Illuminate\\Http\\Reque"
},
{
"path": "app/Http/Controllers/API/TakeExamController.php",
"chars": 6461,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\API;\n\nuse App\\Models\\Exam;\nuse App\\Models\\User;\nuse App\\Models\\Result;\nuse Carbon\\"
},
{
"path": "app/Http/Controllers/Admin/CourseStudentController.php",
"chars": 594,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\nuse Inertia\\Inertia;\nuse App\\Models\\Course;\nuse Illuminate\\Http\\Request;\nu"
},
{
"path": "app/Http/Controllers/Admin/CoursesController.php",
"chars": 2371,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\n\nuse Inertia\\Inertia;\nuse Illuminate\\Http\\Request;\nuse App\\Http\\Controller"
},
{
"path": "app/Http/Controllers/Admin/DashboardController.php",
"chars": 477,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\nuse Inertia\\Inertia;\nuse App\\Models\\Subject;\nuse Illuminate\\Http\\Request;\n"
},
{
"path": "app/Http/Controllers/Admin/ExamController.php",
"chars": 3387,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\nuse App\\Models\\Exam;\nuse Inertia\\Inertia;\nuse Illuminate\\Http\\Request;\nuse"
},
{
"path": "app/Http/Controllers/Admin/LessonController.php",
"chars": 3597,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\nuse Inertia\\Inertia;\nuse App\\Models\\Course;\nuse App\\Models\\Lesson;\nuse Ill"
},
{
"path": "app/Http/Controllers/Admin/QuestionController.php",
"chars": 3028,
"preview": "<?php\nnamespace App\\Http\\Controllers\\Admin;\n\nuse App\\Models\\Exam;\nuse Inertia\\Inertia;\nuse App\\Models\\Question;\nuse App\\"
},
{
"path": "app/Http/Controllers/Admin/RolesController.php",
"chars": 3072,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\nuse App\\Models\\Role;\nuse App\\Models\\User;\nuse Inertia\\Inertia;\nuse Illumin"
},
{
"path": "app/Http/Controllers/Admin/SectionController.php",
"chars": 2584,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\nuse App\\Models\\Exam;\nuse Inertia\\Inertia;\nuse App\\Models\\Course;\nuse App\\M"
},
{
"path": "app/Http/Controllers/Admin/ServerInfoController.php",
"chars": 789,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\nuse Inertia\\Inertia;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resp"
},
{
"path": "app/Http/Controllers/Admin/SubjectController.php",
"chars": 4645,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\nuse Inertia\\Inertia;\nuse App\\Models\\Subject;\nuse Illuminate\\Support\\Str;\nu"
},
{
"path": "app/Http/Controllers/Admin/TopicsController.php",
"chars": 2679,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\n\nuse Inertia\\Inertia;\nuse App\\Models\\Topic;\nuse Illuminate\\Http\\Request;\nu"
},
{
"path": "app/Http/Controllers/Admin/UsersController.php",
"chars": 5039,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Admin;\n\nuse App\\Models\\User;\nuse App\\Models\\Role;\nuse Inertia\\Inertia;\nuse App\\Htt"
},
{
"path": "app/Http/Controllers/Auth/AuthenticatedSessionController.php",
"chars": 1236,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse App\\Http\\Requests\\Auth\\LoginReques"
},
{
"path": "app/Http/Controllers/Auth/ConfirmablePasswordController.php",
"chars": 1061,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Http\\RedirectResponse;\n"
},
{
"path": "app/Http/Controllers/Auth/EmailVerificationNotificationController.php",
"chars": 636,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Http\\RedirectResponse;\n"
},
{
"path": "app/Http/Controllers/Auth/EmailVerificationPromptController.php",
"chars": 634,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Http\\RedirectResponse;\n"
},
{
"path": "app/Http/Controllers/Auth/NewPasswordController.php",
"chars": 2315,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Auth\\Events\\PasswordRes"
},
{
"path": "app/Http/Controllers/Auth/PasswordController.php",
"chars": 734,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Http\\RedirectResponse;\n"
},
{
"path": "app/Http/Controllers/Auth/PasswordResetLinkController.php",
"chars": 1423,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Http\\RedirectResponse;\n"
},
{
"path": "app/Http/Controllers/Auth/RegisteredUserController.php",
"chars": 1346,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse App\\Models\\User;\nuse Illuminate\\Au"
},
{
"path": "app/Http/Controllers/Auth/SocialiteController.php",
"chars": 7774,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse Abraham\\TwitterOAuth\\TwitterOAuth;\nuse App\\Exceptions\\SocialProviderDen"
},
{
"path": "app/Http/Controllers/Auth/VerifyEmailController.php",
"chars": 812,
"preview": "<?php\n\nnamespace App\\Http\\Controllers\\Auth;\n\nuse App\\Http\\Controllers\\Controller;\nuse Illuminate\\Auth\\Events\\Verified;\nu"
},
{
"path": "app/Http/Controllers/Controller.php",
"chars": 308,
"preview": "<?php\n\nnamespace App\\Http\\Controllers;\n\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Foundat"
},
{
"path": "app/Http/Controllers/CourseController.php",
"chars": 1115,
"preview": "<?php\n\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Http\\Resources\\CourseResource;\nuse App\\Models\\Course;\nuse Auth;\nuse Ill"
},
{
"path": "app/Http/Controllers/DownloadController.php",
"chars": 917,
"preview": "<?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Models\\File;\nuse Illuminate\\Http\\Request;\nuse App\\Response\\DownloadRespo"
},
{
"path": "app/Http/Controllers/HomeController.php",
"chars": 989,
"preview": "<?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Http\\Resources\\CourseResource;\nuse App\\Http\\Resources\\SubjectResource;\nu"
},
{
"path": "app/Http/Controllers/InstructorController.php",
"chars": 826,
"preview": "<?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Actions\\GetInstratorCousesAction;\nuse App\\Models\\User;\nuse Inertia\\Inert"
},
{
"path": "app/Http/Controllers/LearningController.php",
"chars": 2118,
"preview": "<?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Actions\\CourseWithSections;\nuse Auth;\nuse Inertia\\Inertia;\nuse App\\Model"
},
{
"path": "app/Http/Controllers/ProfileController.php",
"chars": 1518,
"preview": "<?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Http\\Requests\\ProfileUpdateRequest;\nuse Illuminate\\Contracts\\Auth\\MustVe"
},
{
"path": "app/Http/Controllers/UploadController.php",
"chars": 402,
"preview": "<?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Models\\File;\nuse App\\Response\\FileContentResponseCreator;\n\nclass UploadC"
},
{
"path": "app/Http/Middleware/HandleInertiaRequests.php",
"chars": 1000,
"preview": "<?php\n\nnamespace App\\Http\\Middleware;\n\nuse Illuminate\\Http\\Request;\nuse Inertia\\Middleware;\n\nclass HandleInertiaRequests"
},
{
"path": "app/Http/Requests/Admin/StoreCoursesRequest.php",
"chars": 634,
"preview": "<?php\nnamespace App\\Http\\Requests\\Admin;\n\nuse Illuminate\\Foundation\\Http\\FormRequest;\n\nclass StoreCoursesRequest extends"
},
{
"path": "app/Http/Requests/Admin/UpdateCoursesRequest.php",
"chars": 648,
"preview": "<?php\nnamespace App\\Http\\Requests\\Admin;\n\nuse Illuminate\\Foundation\\Http\\FormRequest;\n\nclass UpdateCoursesRequest extend"
},
{
"path": "app/Http/Requests/Admin/UserRequest.php",
"chars": 553,
"preview": "<?php\n\nnamespace App\\Http\\Requests\\Admin;\n\nuse Illuminate\\Foundation\\Http\\FormRequest;\n\nclass UserRequest extends FormRe"
},
{
"path": "app/Http/Requests/Auth/LoginRequest.php",
"chars": 2216,
"preview": "<?php\n\nnamespace App\\Http\\Requests\\Auth;\n\nuse Illuminate\\Auth\\Events\\Lockout;\nuse Illuminate\\Foundation\\Http\\FormRequest"
},
{
"path": "app/Http/Requests/ExamRequest.php",
"chars": 517,
"preview": "<?php\n\nnamespace App\\Http\\Requests;\n\nuse Illuminate\\Foundation\\Http\\FormRequest;\n\nclass ExamRequest extends FormRequest\n"
},
{
"path": "app/Http/Requests/ProfileUpdateRequest.php",
"chars": 615,
"preview": "<?php\n\nnamespace App\\Http\\Requests;\n\nuse App\\Models\\User;\nuse Illuminate\\Foundation\\Http\\FormRequest;\nuse Illuminate\\Val"
},
{
"path": "app/Http/Requests/QuestionRequest.php",
"chars": 511,
"preview": "<?php\n\nnamespace App\\Http\\Requests;\n\nuse Illuminate\\Foundation\\Http\\FormRequest;\n\nclass QuestionRequest extends FormRequ"
},
{
"path": "app/Http/Requests/SettingRequest.php",
"chars": 541,
"preview": "<?php\n\nnamespace App\\Http\\Requests;\n\nuse Illuminate\\Foundation\\Http\\FormRequest;\n\nclass SettingRequest extends FormReque"
},
{
"path": "app/Http/Requests/SubjectRequest.php",
"chars": 506,
"preview": "<?php\n\nnamespace App\\Http\\Requests;\n\nuse Illuminate\\Foundation\\Http\\FormRequest;\n\nclass SubjectRequest extends FormReque"
},
{
"path": "app/Http/Requests/TopicRequest.php",
"chars": 504,
"preview": "<?php\n\nnamespace App\\Http\\Requests;\n\nuse Illuminate\\Foundation\\Http\\FormRequest;\n\nclass TopicRequest extends FormRequest"
},
{
"path": "app/Http/Resources/CourseResource.php",
"chars": 1942,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/CourseStudentsResource.php",
"chars": 644,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/ExamResource.php",
"chars": 1767,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/FileResource.php",
"chars": 842,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/LessonResource.php",
"chars": 1369,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/QuestionResource.php",
"chars": 987,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/ResultResource.php",
"chars": 838,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/RoleResource.php",
"chars": 682,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/SectionResource.php",
"chars": 1276,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse App\\Models\\Lesson;\nuse Illuminate\\Http\\Request;\nuse App\\Http\\Resources\\ExamRes"
},
{
"path": "app/Http/Resources/SubjectResource.php",
"chars": 1285,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/TopicResource.php",
"chars": 934,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Http/Resources/UserResource.php",
"chars": 1318,
"preview": "<?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\n/**"
},
{
"path": "app/Jobs/ResizedImage.php",
"chars": 2893,
"preview": "<?php\n\nnamespace App\\Jobs;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Queue\\In"
},
{
"path": "app/Jobs/UploadToCloud.php",
"chars": 1522,
"preview": "<?php\n\nnamespace App\\Jobs;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Queue\\In"
},
{
"path": "app/Models/Course.php",
"chars": 4793,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse App\\Models\\Exam;\nuse Illuminate\\Support\\Carbon;\nuse App\\Models\\Traits\\Fileable;\nuse Il"
},
{
"path": "app/Models/Exam.php",
"chars": 2455,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse App\\Models\\User;\nuse App\\Models\\Course;\nuse App\\Models\\Result;\nuse App\\Models\\Subject;"
},
{
"path": "app/Models/File.php",
"chars": 6123,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse App\\Models\\User;\nuse App\\Jobs\\ResizedImage;\nuse Illuminate\\Support\\Carbon;\nuse App\\Mod"
},
{
"path": "app/Models/Lesson.php",
"chars": 5196,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse Auth;\nuse App\\Models\\File;\nuse Illuminate\\Support\\Carbon;\nuse App\\Models\\Traits\\Fileab"
},
{
"path": "app/Models/Question.php",
"chars": 2389,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse App\\Models\\Exam;\nuse App\\Models\\Topic;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\D"
},
{
"path": "app/Models/Result.php",
"chars": 1584,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse App\\Models\\Exam;\nuse App\\Models\\User;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Da"
},
{
"path": "app/Models/Role.php",
"chars": 652,
"preview": "<?php\nnamespace App\\Models;\n\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Spatie\\Permission\\Mod"
},
{
"path": "app/Models/Section.php",
"chars": 1191,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Data"
},
{
"path": "app/Models/Sectionable.php",
"chars": 898,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Data"
},
{
"path": "app/Models/Setting.php",
"chars": 256,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\n/**\n * @property int $id\n * @property int $resour"
},
{
"path": "app/Models/SocialiteProvider.php",
"chars": 1836,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse App\\Models\\User;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate"
},
{
"path": "app/Models/Subject.php",
"chars": 1592,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse App\\Models\\Exam;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Storage"
},
{
"path": "app/Models/Topic.php",
"chars": 1043,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse Carbon\\Carbon;\nuse App\\Models\\Exam;\nuse App\\Models\\Course;\nuse Illuminate\\Database\\Elo"
},
{
"path": "app/Models/Traits/FileStorage.php",
"chars": 1160,
"preview": "<?php\n\nnamespace App\\Models\\Traits;\n\n\nuse Intervention\\Image\\Facades\\Image;\nuse Illuminate\\Support\\Facades\\Storage;\nuse "
},
{
"path": "app/Models/Traits/Fileable.php",
"chars": 178,
"preview": "<?php\n\nnamespace App\\Models\\Traits;\n\nuse App\\Models\\File;\n\ntrait Fileable\n{\n public function files()\n {\n re"
},
{
"path": "app/Models/Traits/HashesId.php",
"chars": 609,
"preview": "<?php\n\nnamespace App\\Models\\Traits;\n\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Database\\Eloquent\\Builder;\n\ntrait Hashes"
},
{
"path": "app/Models/Traits/Topicable.php",
"chars": 261,
"preview": "<?php\n\nnamespace App\\Models\\Traits;\n\nuse App\\Models\\Topic;\n\ntrait Topicable\n{\n /**\n * Return polymorphic relation"
},
{
"path": "app/Models/User.php",
"chars": 4215,
"preview": "<?php\n\nnamespace App\\Models;\n\nuse Carbon\\Carbon;\nuse App\\Models\\Result;\nuse App\\Pivots\\StudentCasting;\nuse Laravel\\Sanct"
},
{
"path": "app/Observers/FileObserver.php",
"chars": 1159,
"preview": "<?php\n\nnamespace App\\Observers;\n\nuse App\\Models\\File;\nuse Illuminate\\Support\\Facades\\Auth;\n\nclass FileObserver\n{\n /**"
},
{
"path": "app/Pivots/StudentCasting.php",
"chars": 254,
"preview": "<?php\n\nnamespace App\\Pivots;\n\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphPivot;\n\nclass StudentCasting extends Morph"
},
{
"path": "app/Policies/CoursePolicy.php",
"chars": 1486,
"preview": "<?php\n\nnamespace App\\Policies;\n\nuse App\\Models\\Course;\nuse App\\Models\\User;\nuse Illuminate\\Auth\\Access\\HandlesAuthorizat"
},
{
"path": "app/Policies/ExamPolicy.php",
"chars": 1472,
"preview": "<?php\n\nnamespace App\\Policies;\n\nuse App\\Models\\Exam;\nuse App\\Models\\User;\nuse Illuminate\\Auth\\Access\\HandlesAuthorizatio"
},
{
"path": "app/Policies/RolePolicy.php",
"chars": 1472,
"preview": "<?php\n\nnamespace App\\Policies;\n\nuse App\\Models\\Role;\nuse App\\Models\\User;\nuse Illuminate\\Auth\\Access\\HandlesAuthorizatio"
},
{
"path": "app/Policies/SubjectPolicy.php",
"chars": 1493,
"preview": "<?php\n\nnamespace App\\Policies;\n\nuse App\\Models\\Subject;\nuse App\\Models\\User;\nuse Illuminate\\Auth\\Access\\HandlesAuthoriza"
},
{
"path": "app/Policies/TopicPolicy.php",
"chars": 1479,
"preview": "<?php\n\nnamespace App\\Policies;\n\nuse App\\Models\\Topic;\nuse App\\Models\\User;\nuse Illuminate\\Auth\\Access\\HandlesAuthorizati"
},
{
"path": "app/Policies/UserPolicy.php",
"chars": 1451,
"preview": "<?php\n\nnamespace App\\Policies;\n\nuse App\\Models\\User;\nuse Illuminate\\Auth\\Access\\HandlesAuthorization;\nuse Illuminate\\Aut"
},
{
"path": "app/Providers/AppServiceProvider.php",
"chars": 451,
"preview": "<?php\n\nnamespace App\\Providers;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Support\\ServiceProvider"
},
{
"path": "app/Response/AudioVideoResponse.php",
"chars": 1826,
"preview": "<?php\n\nnamespace App\\Response;\n\nuse Storage;\nuse App\\Models\\File;\n\nclass AudioVideoResponse\n{\n /**\n * Stream spec"
},
{
"path": "app/Response/DownloadResponse.php",
"chars": 2826,
"preview": "<?php\n\nnamespace App\\Response;\n\nuse Response;\nuse App\\Models\\File;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Fa"
},
{
"path": "app/Response/FileBuilder.php",
"chars": 1497,
"preview": "<?php\nnamespace App\\Response;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Http\\UploadedFile;"
},
{
"path": "app/Response/FileContentResponseCreator.php",
"chars": 2404,
"preview": "<?php\n\nnamespace App\\Response;\n\nuse App\\Models\\File;\nuse Illuminate\\Support\\Facades\\Storage;\nuse Illuminate\\Support\\Faca"
},
{
"path": "app/Response/ImageResponse.php",
"chars": 537,
"preview": "<?php\n\nnamespace App\\Response;\n\nuse Storage;\nuse App\\Models\\File;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nclass "
},
{
"path": "app/Traits/AppSettingsTrait.php",
"chars": 11892,
"preview": "<?php\n\nnamespace App\\Traits;\n\nuse App\\Models\\Setting;\nuse Illuminate\\Support\\Facades\\Artisan;\n\ntrait AppSettingsTrait\n{\n"
},
{
"path": "app/Traits/SocialiteProvidersTrait.php",
"chars": 32773,
"preview": "<?php\n\nnamespace App\\Traits;\n\nuse Carbon\\Carbon;\nuse App\\Models\\User;\nuse App\\Models\\Setting;\nuse Illuminate\\Support\\Str"
},
{
"path": "artisan",
"chars": 350,
"preview": "#!/usr/bin/env php\n<?php\n\nuse Symfony\\Component\\Console\\Input\\ArgvInput;\n\ndefine('LARAVEL_START', microtime(true));\n\n// "
},
{
"path": "bootstrap/app.php",
"chars": 705,
"preview": "<?php\n\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Configuration\\Exceptions;\nuse Illuminate\\Foundat"
},
{
"path": "bootstrap/cache/.gitignore",
"chars": 14,
"preview": "*\n!.gitignore\n"
},
{
"path": "bootstrap/providers.php",
"chars": 64,
"preview": "<?php\n\nreturn [\n App\\Providers\\AppServiceProvider::class,\n];\n"
},
{
"path": "composer.json",
"chars": 2442,
"preview": "{\n \"name\": \"laravel/laravel\",\n \"type\": \"project\",\n \"description\": \"The skeleton application for the Laravel fra"
},
{
"path": "config/app.php",
"chars": 4284,
"preview": "<?php\n\nreturn [\n\n /*\n |--------------------------------------------------------------------------\n | Applicatio"
},
{
"path": "config/auth.php",
"chars": 4029,
"preview": "<?php\n\nreturn [\n\n /*\n |--------------------------------------------------------------------------\n | Authentica"
},
{
"path": "config/cache.php",
"chars": 3420,
"preview": "<?php\n\nuse Illuminate\\Support\\Str;\n\nreturn [\n\n /*\n |--------------------------------------------------------------"
},
{
"path": "config/database.php",
"chars": 6091,
"preview": "<?php\n\nuse Illuminate\\Support\\Str;\n\nreturn [\n\n /*\n |--------------------------------------------------------------"
},
{
"path": "config/filesystems.php",
"chars": 2370,
"preview": "<?php\n\nreturn [\n\n /*\n |--------------------------------------------------------------------------\n | Default Fi"
},
{
"path": "config/logging.php",
"chars": 4310,
"preview": "<?php\n\nuse Monolog\\Handler\\NullHandler;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Handler\\SyslogUdpHandler;\nuse Mon"
},
{
"path": "config/mail.php",
"chars": 3395,
"preview": "<?php\n\nreturn [\n\n /*\n |--------------------------------------------------------------------------\n | Default Ma"
},
{
"path": "config/permission.php",
"chars": 6511,
"preview": "<?php\n\nreturn [\n\n 'models' => [\n\n /*\n * When using the \"HasPermissions\" trait from this package, we ne"
},
{
"path": "config/queue.php",
"chars": 3824,
"preview": "<?php\n\nreturn [\n\n /*\n |--------------------------------------------------------------------------\n | Default Qu"
},
{
"path": "config/services.php",
"chars": 10262,
"preview": "<?php\n\nreturn [\n\n /*\n |--------------------------------------------------------------------------\n | Third Part"
},
{
"path": "config/session.php",
"chars": 7852,
"preview": "<?php\n\nuse Illuminate\\Support\\Str;\n\nreturn [\n\n /*\n |--------------------------------------------------------------"
},
{
"path": "database/.gitignore",
"chars": 10,
"preview": "*.sqlite*\n"
},
{
"path": "database/factories/CourseFactory.php",
"chars": 817,
"preview": "<?php\n\nnamespace Database\\Factories;\n\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\n\n/"
},
{
"path": "database/factories/ExamFactory.php",
"chars": 754,
"preview": "<?php\n\nnamespace Database\\Factories;\n\nuse App\\Models\\Exam;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\n\n/**\n * @"
},
{
"path": "database/factories/LessonFactory.php",
"chars": 858,
"preview": "<?php\n\nnamespace Database\\Factories;\n\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\n\n/"
},
{
"path": "database/factories/QuestionFactory.php",
"chars": 1395,
"preview": "<?php\n\nnamespace Database\\Factories;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\n\n/**\n * @ex"
},
{
"path": "database/factories/SectionFactory.php",
"chars": 573,
"preview": "<?php\n\nnamespace Database\\Factories;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\n\n/**\n * @extends \\Illuminate\\D"
},
{
"path": "database/factories/SubjectFactory.php",
"chars": 478,
"preview": "<?php\n\nnamespace Database\\Factories;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\n\n/**\n * @extends \\Illuminate\\D"
},
{
"path": "database/factories/TopicFactory.php",
"chars": 503,
"preview": "<?php\n\nnamespace Database\\Factories;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\n\n/**\n * @extends \\Illuminate\\D"
},
{
"path": "database/factories/UserFactory.php",
"chars": 1502,
"preview": "<?php\n\nnamespace Database\\Factories;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Support\\Facades"
},
{
"path": "database/migrations/0001_01_01_000000_create_users_table.php",
"chars": 1774,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fa"
},
{
"path": "database/migrations/0001_01_01_000001_create_cache_table.php",
"chars": 849,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fa"
},
{
"path": "database/migrations/0001_01_01_000002_create_jobs_table.php",
"chars": 1812,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fa"
},
{
"path": "database/migrations/2024_05_07_000001_create_personal_access_tokens_table.php",
"chars": 840,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fa"
},
{
"path": "database/migrations/2024_05_07_054845_create_files_table.php",
"chars": 1530,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_054954_create_fileables_table.php",
"chars": 756,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_092254_create_settings_table.php",
"chars": 611,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fa"
},
{
"path": "database/migrations/2024_05_07_112940_create_permission_tables.php",
"chars": 6372,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_142204_create_sections_table.php",
"chars": 715,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_145026_create_subjects_table.php",
"chars": 755,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_152004_create_sectionables_table.php",
"chars": 779,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_153027_create_exams_table.php",
"chars": 1481,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_153507_create_questions_table.php",
"chars": 1348,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_170835_create_topics_table.php",
"chars": 661,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_180360_create_topicables_table.php",
"chars": 779,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_190045_create_results_table.php",
"chars": 836,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_191956_create_courses_table.php",
"chars": 1417,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_193251_create_lessons_table.php",
"chars": 1447,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_195152_create_subjectables_table.php",
"chars": 780,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_200921_create_course_students_table.php",
"chars": 991,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_201001_create_course_teachers_table.php",
"chars": 829,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_05_07_203101_create_lesson_student_table.php",
"chars": 924,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/migrations/2024_07_23_104822_store_last_learning.php",
"chars": 515,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fa"
},
{
"path": "database/migrations/2024_08_13_073632_create_socialite_providers_table.php",
"chars": 1016,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fa"
},
{
"path": "database/migrations/2026_04_25_000001_add_icon_and_image_to_subjects_table.php",
"chars": 601,
"preview": "<?php\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migratio"
},
{
"path": "database/seeders/CourseSeed.php",
"chars": 1951,
"preview": "<?php\n\nnamespace Database\\Seeders;\n\nuse App\\Models\\Exam;\nuse App\\Models\\Course;\nuse App\\Models\\Lesson;\nuse App\\Models\\Se"
},
{
"path": "database/seeders/DatabaseSeeder.php",
"chars": 904,
"preview": "<?php\n\nnamespace Database\\Seeders;\n\nuse Illuminate\\Database\\Seeder;\n// use Illuminate\\Database\\Console\\Seeds\\WithoutMode"
},
{
"path": "database/seeders/RoleSeed.php",
"chars": 2061,
"preview": "<?php\n\nnamespace Database\\Seeders;\n\nuse App\\Models\\User;\nuse Illuminate\\Database\\Seeder;\nuse Illuminate\\Support\\Facades\\"
},
{
"path": "database/seeders/SubjectSeed.php",
"chars": 8566,
"preview": "<?php\n\nnamespace Database\\Seeders;\n\nuse App\\Models\\Subject;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Facades\\D"
},
{
"path": "database/seeders/TopicSeed.php",
"chars": 285,
"preview": "<?php\n\nnamespace Database\\Seeders;\n\nuse Illuminate\\Database\\Seeder;\nuse App\\Models\\Topic;\n\nclass TopicSeed extends Seede"
},
{
"path": "database/seeders/UserSeed.php",
"chars": 1908,
"preview": "<?php\n\nnamespace Database\\Seeders;\n\nuse App\\Models\\User;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Database\\Seeder;\n\ncl"
},
{
"path": "docker/nginx/default.conf",
"chars": 1280,
"preview": "server {\n listen 80;\n server_name localhost;\n root /var/www/html/public;\n index index.php index.html;\n\n #"
},
{
"path": "docker/php/local.ini",
"chars": 120,
"preview": "upload_max_filesize=50M\npost_max_size=50M\nmemory_limit=512M\nmax_execution_time=300\nmax_input_time=300\ndate.timezone=UTC\n"
},
{
"path": "docker-compose.yml",
"chars": 2595,
"preview": "version: '3.8'\n\nservices:\n # PHP-FPM Service\n app:\n build:\n context: .\n dockerfile: Dockerfile\n contai"
},
{
"path": "package.json",
"chars": 1148,
"preview": "{\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"vue-tsc && vite b"
},
{
"path": "phpstan.neon",
"chars": 298,
"preview": "includes:\n - vendor/larastan/larastan/extension.neon\n\nparameters:\n\n paths:\n - app/\n\n # Level 9 is the hi"
},
{
"path": "phpunit.xml",
"chars": 1191,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:noNam"
},
{
"path": "postcss.config.js",
"chars": 93,
"preview": "export default {\n plugins: {\n tailwindcss: {},\n autoprefixer: {},\n },\n};\n"
},
{
"path": "public/.htaccess",
"chars": 603,
"preview": "<IfModule mod_rewrite.c>\n <IfModule mod_negotiation.c>\n Options -MultiViews -Indexes\n </IfModule>\n\n Rewr"
},
{
"path": "public/index.php",
"chars": 468,
"preview": "<?php\n\nuse Illuminate\\Http\\Request;\n\ndefine('LARAVEL_START', microtime(true));\n\n// Determine if the application is in ma"
},
{
"path": "public/robots.txt",
"chars": 24,
"preview": "User-agent: *\nDisallow:\n"
},
{
"path": "resources/css/app.css",
"chars": 59,
"preview": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"
},
{
"path": "resources/js/Components/ApplicationLogo.vue",
"chars": 3083,
"preview": "<template>\n <svg viewBox=\"0 0 316 316\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M305.8 81.125"
},
{
"path": "resources/js/Components/Breadcrumb.vue",
"chars": 3688,
"preview": "<template>\n <nav :class=\"ui.wrapper\" aria-label=\"Breadcrumb\">\n <Link :href=\"route('admin.dashboard')\" :class=\""
},
{
"path": "resources/js/Components/Button.vue",
"chars": 8750,
"preview": "<template>\n <component\n :is=\"is\"\n :disabled=\"disabled || loading\"\n :class=\"buttonClass\"\n "
},
{
"path": "resources/js/Components/Card.vue",
"chars": 2349,
"preview": "<template>\n <component\n :is=\"$attrs.onSubmit ? 'form' : as\"\n :class=\"cardClass\"\n v-bind=\"attrs\"\n >\n"
},
{
"path": "resources/js/Components/Checkbox.vue",
"chars": 639,
"preview": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst emit = defineEmits(['update:checked']);\n\nconst props = d"
},
{
"path": "resources/js/Components/CircleSvg.vue",
"chars": 925,
"preview": "<template>\n <svg\n :width=\"w\"\n :height=\"h\"\n :viewBox=\"viewBox\"\n xmlns=\"http://www.w3.org/2000/svg\"\n :stro"
},
{
"path": "resources/js/Components/Datatable/Table.vue",
"chars": 16332,
"preview": "<template>\n <div :class=\"ui.wrapper\" v-bind=\"attrs\">\n <table :class=\"[ui.base, ui.divide]\">\n <slot "
},
{
"path": "resources/js/Components/Dropdown.vue",
"chars": 2173,
"preview": "<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, ref } from 'vue';\n\nconst props = withDefaults(\n d"
},
{
"path": "resources/js/Components/DropdownLink.vue",
"chars": 442,
"preview": "<script setup lang=\"ts\">\nimport { Link } from '@inertiajs/vue3';\n\ndefineProps<{\n href: string;\n}>();\n</script>\n\n<temp"
},
{
"path": "resources/js/Components/Form/Checkbox.vue",
"chars": 1458,
"preview": "<template>\n <div :class=\"ui.wrapper\">\n <input \n v-bind=\"attrs\" \n :id=\"labelId\" \n "
},
{
"path": "resources/js/Components/Form/HeroiconPicker.vue",
"chars": 5302,
"preview": "<template>\n <div class=\"relative\" ref=\"container\">\n <!-- Trigger button -->\n <button\n type=\"button\"\n @c"
},
{
"path": "resources/js/Components/Form/Input.vue",
"chars": 15869,
"preview": "<template>\n <div :class=\"type === 'hidden' ? 'hidden' : ui.wrapper\">\n <input\n :id=\"inputId\"\n "
},
{
"path": "resources/js/Components/Form/Label.vue",
"chars": 4934,
"preview": "<template>\n <div :class=\"ui.wrapper\" v-bind=\"attrs\">\n <div :class=\"ui.inner\">\n <div v-if=\"label || $slots"
},
{
"path": "resources/js/Components/Form/Listbox.examplevue",
"chars": 20978,
"preview": "<template>\n <component\n :is=\"searchable ? 'HCombobox' : 'HListbox'\"\n v-slot=\"{ open }\"\n :by=\"by\"\n :name=\"na"
},
{
"path": "resources/js/Components/Form/Select.vue",
"chars": 16402,
"preview": "<template>\n <div :class=\"ui.wrapper\">\n <select\n :id=\"inputId\"\n :name=\"name\"\n "
},
{
"path": "resources/js/Components/Icon.vue",
"chars": 628,
"preview": "<template>\n <component :is=\"component\" v-bind=\"attrs\"/>\n</template>\n\n<script lang=\"ts\" setup>\nimport { Component, use"
}
]
// ... and 128 more files (download for full content)
About this extraction
This page contains the full source code of the mshossain110/examinee GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 328 files (862.0 KB), approximately 211.2k tokens, and a symbol index with 640 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.