1. Go to this page and download the library: Download dancycodes/flashhalt library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
dancycodes / flashhalt example snippets
// routes/web.php - You have to define every single endpoint
Route::get('/tasks', [TaskController::class, 'index']);
Route::post('/tasks', [TaskController::class, 'store']);
Route::patch('/tasks/{task}/complete', [TaskController::class, 'markComplete']);
Route::delete('/tasks/{task}', [TaskController::class, 'destroy']);
Route::get('/tasks/{task}/edit', [TaskController::class, 'edit']);
Route::patch('/tasks/{task}', [TaskController::class, 'update']);
// And this is just for ONE resource! Multiply by every feature...
// routes/web.php - Completely empty! No routes needed.
public function destroy(Task $task) // Automatic model binding works perfectly
{
$this->authorize('delete', $task); // Authorization works normally
$task->delete();
return ''; // Return empty string to remove the element
}
public function update(Request $request, User $user) // Multiple parameters work fine
{
$user->update($request->validated());
return view('users.profile', compact('user'));
}
// app/Http/Controllers/TaskController.php
namespace App\Http\Controllers;
use App\Models\Task;
use Illuminate\Http\Request;
class TaskController extends Controller
{
public function index()
{
// Load all tasks and return the list view
$tasks = Task::orderBy('created_at', 'desc')->get();
return view('tasks.index', compact('tasks'));
}
public function store(Request $request)
{
// Validate and create a new task
$validated = $request->validate([
'title' => '
// Return empty string to remove the element
return '';
}
}
// config/flashhalt.php
'allowed_controllers' => [
'App\Http\Controllers\*', // Allow all controllers in main namespace
'App\Http\Controllers\Api\*', // Allow API controllers
'UserController', // Allow specific controller by name
'Admin\UserController', // Allow specific namespaced controller
],
class TaskController extends Controller
{
public function __construct()
{
$this->middleware('auth'); // Authentication works normally
}
public function destroy(Task $task)
{
$this->authorize('delete', $task); // Authorization works normally
$task->delete();
return '';
}
}
'security' => [
// Controllers that can be accessed via FlashHALT
'allowed_controllers' => [
'App\Http\Controllers\*',
// Add your additional namespaces here
],
// Methods that are allowed to be called
'method_whitelist' => [
'index', 'show', 'create', 'store', 'edit', 'update', 'destroy',
// Add your custom methods here
],
// Patterns that should never be allowed
'method_pattern_blacklist' => [
'/^_.*/', // Private methods
'/.*[Pp]assword.*/', // Password operations
'/.*[Tt]oken.*/', // Token operations
// Add your patterns here
],
// Enable automatic CSRF protection
'csrf_protection' => true,
// Ensure destructive operations can't be called via GET
'enforce_http_method_semantics' => true,
],
class UserController extends Controller
{
public function show(User $user)
{
// $user is automatically resolved from the request parameter
return view('users.profile', compact('user'));
}
public function update(Request $request, User $user, AuditService $audit)
{
// Multiple parameters and service injection work perfectly
$user->update($request->validated());
$audit->log('user.updated', $user);
return view('users.profile', compact('user'));
}
}
class NotificationController extends Controller
{
public function markAsRead(Notification $notification)
{
$notification->markAsRead();
return response()
->view('notifications.notification', compact('notification'))
->header('HX-Trigger', 'notificationRead') // Trigger client-side events
->header('HX-Push-Url', '/notifications'); // Update browser URL
}
}
class AdminController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('can:access-admin');
$this->middleware('throttle:60,1'); // Rate limiting works normally
}
}
'allowed_controllers' => [
'App\Http\Controllers\*',
'YourNamespace\YourController', // Add this line
],
'method_whitelist' => [
'index', 'show', 'store', 'update', 'destroy',
'yourCustomMethod', // Add your method here
],
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\User;
use App\Models\Task;
class TaskControllerTest extends TestCase
{
/** @test */
public function it_can_load_task_index_via_flashhalt()
{
$response = $this->get('hx/task@index');
$response->assertOk();
$response->assertViewIs('tasks.index');
}
/** @test */
public function it_can_create_tasks_with_csrf_protection()
{
$response = $this->post('hx/task@store', [
'title' => 'Test Task',
'description' => 'Test Description',
'_token' => csrf_token(), // Include CSRF token in tests
]);
$response->assertOk();
$this->assertDatabaseHas('tasks', ['title' => 'Test Task']);
}
/** @test */
public function it_respects_authorization_policies()
{
$user = User::factory()->create();
$task = Task::factory()->create(['user_id' => $user->id]);
$otherUser = User::factory()->create();
$this->actingAs($otherUser);
$response = $this->delete('hx/task@destroy', [
'task' => $task->id,
'_token' => csrf_token(),
]);
$response->assertForbidden(); // Should be blocked by authorization
}
}
// Good: Feature-focused controller
class TaskController extends Controller
{
public function index() { /* list tasks */ }
public function store() { /* create task */ }
public function toggle() { /* toggle completion */ }
public function archive() { /* archive task */ }
public function assignTo() { /* assign to user */ }
}
// Also good: Focused single-purpose controller
class TaskArchiveController extends Controller
{
public function archive() { /* archive logic */ }
public function restore() { /* restore logic */ }
public function purge() { /* permanent deletion */ }
}
public function store(Request $request)
{
$task = Task::create($request->validated());
// Return just the new task HTML, not the full page
return view('tasks.task-item', compact('task'));
}
public function index()
{
$tasks = Task::all();
if (request()->header('HX-Request')) {
// Return partial for HTMX requests
return view('tasks.task-list', compact('tasks'));
}
// Return full page for direct navigation
return view('tasks.index', compact('tasks'));
}