developing-with-laravel
Laravel framework patterns for PHP applications including Eloquent ORM, migrations, routing, queues, and Blade templates. Use when building Laravel applications or working with Laravel projects.
What this skill does
# Laravel Skill - Quick Reference
Laravel framework patterns for modern PHP applications. For PHP language fundamentals, see the PHP skill. For advanced patterns, see [REFERENCE.md](./REFERENCE.md).
---
## Table of Contents
1. [Project Structure](#project-structure)
2. [Routing & Controllers](#routing--controllers)
3. [Eloquent ORM](#eloquent-orm)
4. [Validation](#validation)
5. [Middleware](#middleware)
6. [Authentication](#authentication)
7. [Artisan CLI](#artisan-cli)
8. [Queues & Jobs](#queues--jobs)
9. [Events & Listeners](#events--listeners)
10. [Testing](#testing)
11. [Service Providers](#service-providers)
12. [Task Scheduling](#task-scheduling)
---
## Project Structure
```
app/
├── Console/Commands/ # Artisan commands
├── Http/
│ ├── Controllers/ # Request handlers
│ ├── Middleware/ # Request/response filters
│ └── Requests/ # Form validation
├── Jobs/ # Queueable jobs
├── Models/ # Eloquent models
├── Providers/ # Service providers
└── Services/ # Business logic
config/ # Configuration files
database/
├── factories/ # Model factories
├── migrations/ # Database migrations
└── seeders/ # Database seeders
routes/
├── api.php # API routes
└── web.php # Web routes
tests/
├── Feature/ # Integration tests
└── Unit/ # Unit tests
```
---
## Routing & Controllers
### Route Definitions
```php
// Basic routes
Route::get('/users', [UserController::class, 'index']);
Route::post('/users', [UserController::class, 'store']);
// Resource routes (all CRUD)
Route::resource('posts', PostController::class);
Route::apiResource('comments', CommentController::class);
// Route groups with middleware
Route::prefix('api/v1')->middleware(['auth:sanctum'])->group(function () {
Route::get('/profile', [ProfileController::class, 'show']);
});
```
### Controllers
```php
class UserController extends Controller
{
public function index()
{
return UserResource::collection(
User::with(['profile', 'roles'])->paginate(20)
);
}
public function store(StoreUserRequest $request)
{
return new UserResource(User::create($request->validated()));
}
public function show(User $user) // Route model binding
{
return new UserResource($user->load('profile'));
}
}
```
---
## Eloquent ORM
### Model Definition
```php
class Post extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = ['title', 'slug', 'content', 'status', 'author_id'];
protected $casts = ['status' => PostStatus::class, 'published_at' => 'datetime'];
protected $with = ['author']; // Always eager load
// Relationships
public function author(): BelongsTo
{
return $this->belongsTo(User::class, 'author_id');
}
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class)->withTimestamps();
}
// Scopes
public function scopePublished(Builder $query): void
{
$query->where('status', PostStatus::Published)
->where('published_at', '<=', now());
}
// Accessors (Laravel 9+)
protected function excerpt(): Attribute
{
return Attribute::make(
get: fn () => Str::limit(strip_tags($this->content), 150),
);
}
}
```
### Relationships Quick Reference
| Method | Relationship | Example |
|--------|--------------|---------|
| `hasOne` | 1:1 | User has one Profile |
| `belongsTo` | 1:1 inverse | Profile belongs to User |
| `hasMany` | 1:n | User has many Posts |
| `belongsToMany` | n:n | Post has many Tags |
| `morphMany` | 1:n polymorphic | Post has many Comments |
> **Advanced**: For hasOneThrough, hasManyThrough, polymorphic relationships, see [REFERENCE.md](./REFERENCE.md#2-eloquent-advanced-patterns)
### Query Builder
```php
// Filtering
$posts = Post::where('status', 'published')
->whereHas('tags', fn($q) => $q->where('name', 'laravel'))
->with(['author', 'comments'])
->latest('published_at')
->paginate(10);
// Aggregates
$count = Post::where('status', 'published')->count();
$avg = Order::avg('total');
// Chunking for large datasets
Post::chunk(100, fn($posts) => $posts->each->process());
```
### Transactions
```php
// Closure-based (auto commit/rollback)
$order = DB::transaction(function () use ($data) {
$order = Order::create($data['order']);
foreach ($data['items'] as $item) {
$order->items()->create($item);
}
return $order;
});
```
---
## Validation
### Form Requests
```php
class StorePostRequest extends FormRequest
{
public function authorize(): bool
{
return $this->user()->can('create', Post::class);
}
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255'],
'slug' => ['required', Rule::unique('posts')->ignore($this->post)],
'content' => ['required', 'string', 'min:100'],
'status' => ['required', Rule::enum(PostStatus::class)],
'category_id' => ['required', 'exists:categories,id'],
'tags' => ['array'],
'tags.*' => ['exists:tags,id'],
];
}
public function messages(): array
{
return ['title.required' => 'A post title is required.'];
}
}
```
### Common Validation Rules
| Rule | Description |
|------|-------------|
| `required` | Must be present and not empty |
| `nullable` | Can be null |
| `string`, `integer`, `boolean` | Type validation |
| `email` | Valid email format |
| `unique:table,column` | Unique in database |
| `exists:table,column` | Must exist in database |
| `in:a,b,c` | Must be one of values |
| `min:n`, `max:n` | Size constraints |
> **Advanced**: For custom validation rules and complex conditional validation, see [REFERENCE.md](./REFERENCE.md#4-validation-advanced)
---
## Middleware
```php
class EnsureUserIsActive
{
public function handle(Request $request, Closure $next): Response
{
if (!$request->user()?->isActive()) {
return response()->json(['message' => 'Account inactive.'], 403);
}
return $next($request);
}
}
// With parameters
class CheckRole
{
public function handle(Request $request, Closure $next, string ...$roles): Response
{
if (!$request->user()?->hasAnyRole($roles)) {
abort(403);
}
return $next($request);
}
}
// Usage: Route::middleware('role:admin,moderator')
```
> **Advanced**: For tenant-scoping middleware and session management, see [REFERENCE.md](./REFERENCE.md#7-multi-tenancy-patterns)
---
## Authentication
### Sanctum (API Tokens)
```php
// Login and issue token
public function login(LoginRequest $request)
{
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['Invalid credentials.'],
]);
}
$user->tokens()->delete(); // Revoke existing
$token = $user->createToken('api-token', ['read', 'write'])->plainTextToken;
return response()->json(['user' => new UserResource($user), 'token' => $token]);
}
// Protected routes
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', fn(Request $request) => $request->user());
});
```
> **Advanced**: For Passport OAuth, spatie/permission RBAC, see [REFERENCE.md](./REFERENCE.md#8-authentication-advanced)
---
## Artisan CLI
### Custom Command
```php
class ProcessContacts extends Command
{
protected $signature = 'contacts:process
{--status=active : Filter by status}
{--limit=100 : Maximum to process}
{--dry-run : Simulate without changes}';
protected Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.