All skills
asyrafhussin avatar

/laravel-best-practices

@ef59186

Laravel 13 conventions and best practices. Use when creating controllers, models, migrations, validation, services, or structuring Laravel applications. Triggers on tasks involving Laravel architecture, Eloquent, database, API development, or PHP patterns.

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/laravel-best-practices

This session only. Nothing lands on disk.

rulesvalidation-conditional-rules.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Conditional Validation Rules

Impact: HIGH (Dynamic validation based on input)

Apply validation rules conditionally based on input values or other conditions.

Bad Example

// Manual conditional logic in controller
class PaymentController extends Controller
{
    public function store(Request $request)
    {
        $rules = [
            'amount' => 'required|numeric|min:1',
            'payment_method' => 'required|in:card,bank,paypal',
        ];

        // Messy conditional rules
        if ($request->payment_method === 'card') {
            $rules['card_number'] = 'required|string|size:16';
            $rules['card_expiry'] = 'required|date_format:m/y';
            $rules['card_cvv'] = 'required|string|size:3';
        }

        if ($request->payment_method === 'bank') {
            $rules['bank_account'] = 'required|string';
            $rules['routing_number'] = 'required|string|size:9';
        }

        if ($request->payment_method === 'paypal') {
            $rules['paypal_email'] = 'required|email';
        }

        if ($request->save_for_later) {
            $rules['nickname'] = 'required|string|max:50';
        }

        $validated = $request->validate($rules);

        // ...
    }
}

Good Example

// Form Request with conditional rules
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class ProcessPaymentRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'amount' => ['required', 'numeric', 'min:1'],
            'payment_method' => ['required', Rule::in(['card', 'bank', 'paypal'])],

            // Conditional with required_if
            'card_number' => ['required_if:payment_method,card', 'nullable', 'digits:16'],
            'card_expiry' => ['required_if:payment_method,card', 'nullable', 'date_format:m/y'],
            'card_cvv' => ['required_if:payment_method,card', 'nullable', 'digits:3'],

            'bank_account' => ['required_if:payment_method,bank', 'nullable', 'string'],
            'routing_number' => ['required_if:payment_method,bank', 'nullable', 'digits:9'],

            'paypal_email' => ['required_if:payment_method,paypal', 'nullable', 'email'],

            // Required when another field is truthy
            'save_for_later' => ['boolean'],
            'nickname' => ['required_if:save_for_later,true', 'nullable', 'string', 'max:50'],
        ];
    }
}
// Using Rule::when() for complex conditions
class StoreOrderRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'type' => ['required', Rule::in(['standard', 'express', 'scheduled'])],
            'items' => ['required', 'array', 'min:1'],

            // When type is 'scheduled', require delivery date
            'delivery_date' => [
                Rule::when(
                    $this->type === 'scheduled',
                    ['required', 'date', 'after:today'],
                    ['nullable', 'date']
                ),
            ],

            // Complex condition with closure
            'express_fee_accepted' => [
                Rule::when(
                    fn () => $this->type === 'express' && $this->total > 100,
                    ['required', 'accepted'],
                ),
            ],

            // Exclude when condition is true
            'coupon_code' => [
                Rule::excludeIf($this->type === 'express'),
                'nullable',
                'string',
                'exists:coupons,code',
            ],
        ];
    }
}
// Sometimes for dynamic conditions
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;

class ProfileRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'email'],
            'newsletter' => ['boolean'],
        ];
    }

    public function withValidator(Validator $validator): void
    {
        $validator->sometimes('phone', 'required|string', function ($input) {
            return $input->newsletter === true;
        });
    }
}
// Conditional rules in controller (when needed)
class RegistrationController extends Controller
{
    public function store(Request $request)
    {
        $validated = $request->validate([
            'account_type' => ['required', Rule::in(['personal', 'business'])],
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'email', 'unique:users'],

            // Business account requires additional fields; prohibited for personal
            'company_name' => [
                'required_if:account_type,business',
                'nullable',
                'string',
                Rule::prohibitedIf($request->account_type === 'personal'),
            ],
            'tax_id' => ['required_if:account_type,business', 'nullable', 'string'],
        ]);
    }
}
// Multiple conditions
class ComplexFormRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'has_children' => ['boolean'],
            'children_count' => [
                'required_if:has_children,true',
                'nullable',
                'integer',
                'min:1',
                'max:20',
            ],

            // Required unless another field has a value
            'emergency_contact' => ['required_unless:has_spouse,true'],

            // Required without another field
            'mobile_phone' => ['required_without:home_phone'],
            'home_phone' => ['required_without:mobile_phone'],

            // Required with all of these fields
            'delivery_notes' => ['required_with_all:street,city,zip'],

            // Exclude if null or missing
            'metadata' => ['exclude_if:type,basic', 'array'],
        ];
    }
}

Why

  • Clean code: No manual if/else for building rules
  • Declarative: Rules clearly state their conditions
  • Built-in support: Laravel provides many conditional rules
  • Flexible: Complex conditions supported with closures
  • Maintainable: Conditions live with their rules
  • Testable: Conditional logic tested through form requests

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill is a comprehensive guide to Laravel 13 best practices, providing safe and standard architectural, database, and security patterns for PHP development. No malicious behavior or security risks were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    1/37 files flagged

  • ZeroLeaks5mo

    2 findings · Score: 80/100

Signed by skilld at ef59186. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 7 months ago
Other metadata
metadata
{
  "author": "Laravel Community",
  "version": "2.1.0",
  "laravelVersion": "13.x",
  "phpVersion": "8.3+"
}

README badge

README badge for asyrafhussin/agent-skills/laravel-best-practices