Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions laravel/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
APP_NAME="Laravel Quiz App"
APP_ENV=local
APP_KEY=base64:MHMyGZ7hZG8z4V5j6F3qW1pL8n2R4s9X0yB7cE6dA=
APP_DEBUG=true
APP_URL=http://localhost:3000

DB_CONNECTION=sqlite
DB_DATABASE=/tmp/templates-fork/laravel/database.sqlite
33 changes: 33 additions & 0 deletions laravel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Laravel Quiz App Template

A basic quiz application built with Laravel for Codesphere workspaces.

## Features

- Create and manage quizzes
- Add multiple-choice questions to each quiz
- Take quizzes and see your score
- SQLite database (no external DB required)

## Deployment on Codesphere

1. Fork this template
2. In Codesphere, create a new workspace from your fork
3. Set up the CI pipeline (it will auto-run on Codesphere)
4. Click "Run" stage to start the dev server
5. Click "Open deployment" to access the app

## Local Development

```bash
composer install
touch database/database.sqlite
php artisan migrate
php artisan serve --host=0.0.0.0 --port=3000
```

## Tech Stack

- PHP 8.1+
- Laravel 10
- SQLite (file-based, no setup required)
8 changes: 8 additions & 0 deletions laravel/app/Http/Controllers/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace App\Http\Controllers;

class Controller
{
//
}
30 changes: 30 additions & 0 deletions laravel/app/Http/Controllers/QuestionController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace App\Http\Controllers;

use App\Models\Quiz;
use App\Models\Question;
use Illuminate\Http\Request;

class QuestionController extends Controller
{
public function store(Request $request)
{
$validated = $request->validate([
'quiz_id' => 'required|exists:quizzes,id',
'question_text' => 'required|string',
'options' => 'required|array|min:2',
'correct_answer' => 'required|string',
]);

Question::create($validated);
return redirect()->route('quizzes.show', $validated['quiz_id'])->with('success', 'Question added!');
}

public function destroy(Question $question)
{
$quiz_id = $question->quiz_id;
$question->delete();
return redirect()->route('quizzes.show', $quiz_id)->with('success', 'Question deleted!');
}
}
55 changes: 55 additions & 0 deletions laravel/app/Http/Controllers/QuizController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace App\Http\Controllers;

use App\Models\Quiz;
use Illuminate\Http\Request;

class QuizController extends Controller
{
public function index()
{
$quizzes = Quiz::withCount('questions')->latest()->paginate(10);
return view('quizzes.index', compact('quizzes'));
}

public function create()
{
return view('quizzes.create');
}

public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string',
]);

Quiz::create($validated);
return redirect()->route('quizzes.index')->with('success', 'Quiz created!');
}

public function show(Quiz $quiz)
{
$quiz->load('questions');
return view('quizzes.show', compact('quiz'));
}

public function take(Request $request, Quiz $quiz)
{
$answers = $request->except(['_token']);
$quiz->load('questions');

$score = 0;
$total = $quiz->questions->count();

foreach ($quiz->questions as $question) {
if (isset($answers['question_' . $question->id]) &&
$answers['question_' . $question->id] === $question->correct_answer) {
$score++;
}
}

return view('quizzes.result', compact('quiz', 'score', 'total'));
}
}
19 changes: 19 additions & 0 deletions laravel/app/Models/Question.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Question extends Model
{
protected $fillable = ['quiz_id', 'question_text', 'options', 'correct_answer'];

protected $casts = [
'options' => 'array',
];

public function quiz()
{
return $this->belongsTo(Quiz::class);
}
}
15 changes: 15 additions & 0 deletions laravel/app/Models/Quiz.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Quiz extends Model
{
protected $fillable = ['title', 'description'];

public function questions()
{
return $this->hasMany(Question::class);
}
}
18 changes: 18 additions & 0 deletions laravel/app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
//
}

public function boot(): void
{
//
}
}
19 changes: 19 additions & 0 deletions laravel/artisan
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env php
<?php

define('LARAVEL_START', microtime(true));

require __DIR__.'/vendor/autoload.php';

$app = require_once __DIR__.'/bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);

$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);

$kernel->terminate($input, $status);

exit($status);
18 changes: 18 additions & 0 deletions laravel/bootstrap/app.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
14 changes: 14 additions & 0 deletions laravel/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
prepare:
steps:
- name: "Install dependencies"
command: "composer install --no-interaction"

test:
steps:
- name: "Run migrations"
command: "php artisan migrate --force 2>&1 || true"

run:
steps:
- name: "Start Laravel dev server"
command: "php artisan serve --host=0.0.0.0 --port=3000"
51 changes: 51 additions & 0 deletions laravel/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "codesphere/laravel-quiz-app",
"description": "Laravel Quiz App Template for Codesphere",
"type": "project",
"require": {
"php": "^8.1",
"laravel/framework": "^10.0",
"guzzlehttp/guzzle": "^7.2"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
"laravel/sail": "^1.18",
"mockery/mockery": "^1.4.4",
"nunomaduro/collision": "^7.0",
"phpunit/phpunit": "^10.1"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
]
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true,
"allow-plugins": {
"pestphp/pest-plugin": true,
"php-http/discovery": true
}
},
"minimum-stability": "stable",
"prefer-stable": true
}
41 changes: 41 additions & 0 deletions laravel/config/app.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

return [
'name' => env('APP_NAME', 'Laravel Quiz App'),
'env' => env('APP_ENV', 'production'),
'debug' => (bool) env('APP_DEBUG', false),
'url' => env('APP_URL', 'http://localhost'),
'timezone' => 'UTC',
'locale' => 'en',
'fallback_locale' => 'en',
'faker_locale' => 'en_US',
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
'maintenance' => ['driver' => 'file'],
'providers' => [
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
App\Providers\AppServiceProvider::class,
],
'aliases' => Illuminate\Support\Facades\Facade::defaultAliases()->toArray(),
];
18 changes: 18 additions & 0 deletions laravel/config/database.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

return [
'default' => 'sqlite',
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => database_path('database.sqlite'),
'prefix' => '',
'foreign_key_constraints' => true,
],
],
'migrations' => [
'table' => 'migrations',
'update_date_on_publish' => true,
],
];
Loading