Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Lara Reserve Laravel Package

shayanys/lara-reserve

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require shayanys/lara-reserve
    php artisan migrate
    

    Run migrations to create the reserves table.

  2. Basic Setup:

    • For reservable models (e.g., Book, Room):
      use ShayanYS\LaraReserve\Interfaces\ReservableInterface;
      use ShayanYS\LaraReserve\Traits\Reservable;
      
      class Book extends Model implements ReservableInterface
      {
          use Reservable;
      }
      
    • For customer models (e.g., User):
      use ShayanYS\LaraReserve\Interfaces\CustomerInterface;
      use ShayanYS\LaraReserve\Traits\Customer;
      
      class User extends Authenticatable implements CustomerInterface
      {
          use Customer;
      }
      
  3. First Use Case: Reserve a Book for a User:

    $book = Book::find(1);
    $user = User::find(1);
    $reservation = $book->reserve($user, now()->addDays(3));
    

    Check reservations:

    $book->reservations; // Collection of Reserve models
    

Implementation Patterns

Core Workflows

  1. Reserving Items:

    // Basic reservation
    $reservation = $reservable->reserve($customer, $endAt);
    
    // With custom data (e.g., notes, status)
    $reservation = $reservable->reserve($customer, $endAt, [
        'notes' => 'For research',
        'status' => 'pending',
    ]);
    
  2. Checking Availability:

    // Check if a model is available for a date range
    if ($reservable->isAvailable($startAt, $endAt)) {
        // Proceed with reservation
    }
    
  3. Canceling Reservations:

    $reservation->cancel(); // Soft-deletes the reserve record
    
  4. Querying Reservations:

    // Get all reservations for a model
    $reservations = $reservable->reservations;
    
    // Filter active reservations
    $activeReservations = $reservable->reservations()->active()->get();
    
  5. Customer-Specific Queries:

    // Get all reservations made by a customer
    $user->reservations;
    
    // Get all reservables reserved by a customer
    $user->reservables;
    

Integration Tips

  • Validation: Use Laravel's validation to ensure end_at is after start_at:

    $validator = Validator::make($request->all(), [
        'end_at' => 'required|after:start_at',
    ]);
    
  • Events: Listen for reservation events (e.g., Reserved, Cancelled) to trigger notifications or updates:

    // In EventServiceProvider
    protected $listen = [
        \ShayanYS\LaraReserve\Events\Reserved::class => [
            \App\Listeners\SendReservationConfirmation::class,
        ],
    ];
    
  • Policies: Restrict reservation actions using Laravel's authorization:

    // app/Policies/BookPolicy.php
    public function reserve(User $user, Book $book)
    {
        return $user->canReserve($book);
    }
    
  • API Resources: Transform reservation data for APIs:

    // app/Http/Resources/ReservationResource.php
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'reservable_type' => $this->reservable_type,
            'reservable_id' => $this->reservable_id,
            'customer_id' => $this->customer_id,
            'start_at' => $this->start_at,
            'end_at' => $this->end_at,
            'status' => $this->status,
        ];
    }
    

Gotchas and Tips

Pitfalls

  1. Overlapping Reservations:

    • The package does not automatically prevent overlapping reservations. Always validate date ranges manually:
      if (!$reservable->isAvailable($startAt, $endAt)) {
          throw new \Exception('Item already reserved for this period.');
      }
      
  2. Soft Deletes:

    • Cancelled reservations are soft-deleted by default. If you need hard deletes, override the cancel() method:
      public function cancel()
      {
          $this->delete(); // Hard delete
      }
      
  3. Morph Map Conflicts:

    • If your reservable_type or customer_type clashes with Laravel's default morph maps, explicitly define them:
      class Book extends Model implements ReservableInterface
      {
          protected $morphClass = Book::class;
      }
      
  4. Time Zone Issues:

    • Ensure start_at and end_at timestamps are in the correct time zone. Use Carbon for consistency:
      $startAt = Carbon::parse($request->start_at)->setTimezone('UTC');
      

Debugging

  • Query Logs: Enable Laravel's query logging to debug reservation queries:

    DB::enableQueryLog();
    $reservations = $reservable->reservations;
    dd(DB::getQueryLog());
    
  • Model Events: Use model events to trace reservation lifecycle:

    $reservable->reservations()->created(function ($reserve) {
        Log::info('New reservation created:', $reserve->toArray());
    });
    

Extension Points

  1. Custom Reserve Model: Extend the Reserve model to add fields:

    php artisan make:model ReserveExtension -m
    

    Then update the migration and model.

  2. Custom Statuses: Add custom statuses to the reserves table:

    // Migration
    $table->string('status')->default('active');
    
    // Usage
    $reservation = $reservable->reserve($customer, $endAt, [
        'status' => 'pending_approval',
    ]);
    
  3. Reservation Rules: Override the isAvailable method to enforce custom rules (e.g., max reservations per customer):

    public function isAvailable($startAt, $endAt)
    {
        $overlap = $this->reservations()
            ->where('customer_id', $this->customer->id)
            ->where(function ($query) use ($startAt, $endAt) {
                $query->where(function ($q) use ($startAt, $endAt) {
                    $q->where('start_at', '<', $endAt)
                      ->where('end_at', '>', $startAt);
                });
            })->exists();
    
        return !$overlap && parent::isAvailable($startAt, $endAt);
    }
    
  4. API Endpoints: Create dedicated API routes for reservations:

    Route::post('/reservables/{reservable}/reserve', [ReservationController::class, 'store']);
    Route::delete('/reservations/{reservation}/cancel', [ReservationController::class, 'cancel']);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle