Skip to content

Rule Types

Braden Keith edited this page Sep 20, 2025 · 1 revision

Rule Types

Comprehensive guide to all available rule types.

months_of_year

Matches specific months of the year.

Configuration

[
    'months' => [1, 7, 12], // January, July, December
]

Parameters

  • months (array): ISO month numbers (1-12)

Examples

// Summer months only
$pool->availabilityRules()->create([
    'type' => 'months_of_year',
    'config' => ['months' => [6, 7, 8]], // June, July, August
    'effect' => Effect::Allow,
    'priority' => 10,
]);

// Holiday shopping season
$store->availabilityRules()->create([
    'type' => 'months_of_year',
    'config' => ['months' => [11, 12]], // November, December
    'effect' => Effect::Allow,
    'priority' => 10,
]);

weekdays

Matches specific days of the week.

Configuration

[
    'days' => [1, 2, 3, 4, 5], // Monday to Friday
]

Parameters

  • days (array): ISO weekday numbers (1=Monday, 7=Sunday)

Examples

// Business days
$office->availabilityRules()->create([
    'type' => 'weekdays',
    'config' => ['days' => [1, 2, 3, 4, 5]], // Mon-Fri
    'effect' => Effect::Allow,
    'priority' => 10,
]);

// Weekend only
$venue->availabilityRules()->create([
    'type' => 'weekdays',
    'config' => ['days' => [6, 7]], // Sat-Sun
    'effect' => Effect::Allow,
    'priority' => 10,
]);

date_range

Matches dates within a specific range.

Configuration

[
    'from' => '05-01',      // Start date
    'to' => '08-31',        // End date
    'kind' => 'yearly',     // Range type
]

Parameters

  • from (string): Start date (format depends on kind)
  • to (string): End date
  • kind (string): 'yearly' or 'absolute'

Yearly Ranges

Uses MM-DD format, repeats every year:

// Summer season (repeats annually)
$facility->availabilityRules()->create([
    'type' => 'date_range',
    'config' => [
        'from' => '06-01',
        'to' => '09-15',
        'kind' => 'yearly',
    ],
    'effect' => Effect::Allow,
    'priority' => 10,
]);

// Year-end holidays (wraps around year boundary)
$office->availabilityRules()->create([
    'type' => 'date_range',
    'config' => [
        'from' => '12-20',
        'to' => '01-05',
        'kind' => 'yearly',
    ],
    'effect' => Effect::Deny,
    'priority' => 20,
]);

Absolute Ranges

Uses Y-m-d format, specific date range:

// Special event period
$venue->availabilityRules()->create([
    'type' => 'date_range',
    'config' => [
        'from' => '2025-07-01',
        'to' => '2025-07-31',
        'kind' => 'absolute',
    ],
    'effect' => Effect::Allow,
    'priority' => 10,
]);

time_of_day

Matches specific times during any day.

Configuration

[
    'from' => '09:00',      // Start time
    'to' => '17:00',        // End time
]

Parameters

  • from (string): Start time (HH:MM or HH:MM:SS)
  • to (string): End time (inclusive)

Examples

// Business hours
$office->availabilityRules()->create([
    'type' => 'time_of_day',
    'config' => ['from' => '09:00', 'to' => '17:00'],
    'effect' => Effect::Allow,
    'priority' => 20,
]);

// Overnight hours (wraps midnight)
$service->availabilityRules()->create([
    'type' => 'time_of_day',
    'config' => ['from' => '22:00', 'to' => '06:00'],
    'effect' => Effect::Allow,
    'priority' => 20,
]);

// Precise timing with seconds
$system->availabilityRules()->create([
    'type' => 'time_of_day',
    'config' => ['from' => '00:00:00', 'to' => '23:59:59'],
    'effect' => Effect::Allow,
    'priority' => 10,
]);

Special Cases

  • When from equals to, the rule matches all times (always true)
  • Times wrap around midnight automatically

blackout_date

Blocks specific calendar dates.

Configuration

[
    'dates' => ['2025-12-25', '2025-01-01'],
]

Parameters

  • dates (array): Array of dates in Y-m-d format

Examples

// Company holidays
$office->availabilityRules()->create([
    'type' => 'blackout_date',
    'config' => [
        'dates' => [
            '2025-01-01', // New Year's Day
            '2025-07-04', // Independence Day
            '2025-12-25', // Christmas
        ],
    ],
    'effect' => Effect::Deny,
    'priority' => 50, // High priority to override other rules
]);

// Maintenance dates
$system->availabilityRules()->create([
    'type' => 'blackout_date',
    'config' => [
        'dates' => ['2025-03-15', '2025-06-15', '2025-09-15', '2025-12-15'],
    ],
    'effect' => Effect::Deny,
    'priority' => 100,
]);

rrule

RFC 5545 recurrence rules for complex patterns.

Configuration

[
    'rrule' => 'FREQ=WEEKLY;BYDAY=MO,WE,FR',
    'tz' => 'America/New_York', // Optional timezone
]

Supported Features

  • FREQ: DAILY, WEEKLY, MONTHLY, YEARLY
  • BYDAY: MO, TU, WE, TH, FR, SA, SU
  • BYMONTH: 1-12
  • BYMONTHDAY: 1-31
  • BYHOUR, BYMINUTE, BYSECOND: Time constraints
  • INTERVAL: Frequency interval (requires DTSTART)

Examples

// Every Monday, Wednesday, Friday
$class->availabilityRules()->create([
    'type' => 'rrule',
    'config' => [
        'rrule' => 'FREQ=WEEKLY;BYDAY=MO,WE,FR',
    ],
    'effect' => Effect::Allow,
    'priority' => 10,
]);

// First Monday of each month
$meeting->availabilityRules()->create([
    'type' => 'rrule',
    'config' => [
        'rrule' => 'FREQ=MONTHLY;BYDAY=1MO',
    ],
    'effect' => Effect::Allow,
    'priority' => 10,
]);

// Every 2 weeks starting from a date
$appointment->availabilityRules()->create([
    'type' => 'rrule',
    'config' => [
        'rrule' => 'FREQ=WEEKLY;INTERVAL=2;DTSTART=20250101T090000Z',
    ],
    'effect' => Effect::Allow,
    'priority' => 10,
]);

// Complex: Every weekday at 9 AM and 2 PM
$broadcast->availabilityRules()->create([
    'type' => 'rrule',
    'config' => [
        'rrule' => 'FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;BYHOUR=9,14',
    ],
    'effect' => Effect::Allow,
    'priority' => 10,
]);

inventory_gate

Dynamic availability based on inventory or capacity.

Configuration

[
    'min' => 1, // Minimum required inventory
]

Parameters

  • min (integer): Minimum inventory/capacity required

Setting Up the Resolver

First, configure an inventory resolver:

// In a service provider or config
config(['availability.inventory_gate.resolver' => function (
    AvailabilitySubject $subject,
    CarbonInterface $moment,
    array $ruleConfig
) {
    // Return current inventory count
    return $subject->getInventoryAt($moment);
    
    // Or return boolean directly
    return $subject->hasStock();
}]);

Examples

// Require at least 1 item in stock
$product->availabilityRules()->create([
    'type' => 'inventory_gate',
    'config' => ['min' => 1],
    'effect' => Effect::Allow,
    'priority' => 30,
]);

// Require minimum capacity
$venue->availabilityRules()->create([
    'type' => 'inventory_gate',
    'config' => ['min' => 10], // Need at least 10 seats
    'effect' => Effect::Allow,
    'priority' => 40,
]);

Per-Model Resolvers

Different resolvers for different model types:

config(['availability.inventory_gate.resolvers' => [
    Product::class => function($subject, $moment, $config) {
        return $subject->stock_quantity;
    },
    Room::class => function($subject, $moment, $config) {
        return $subject->getAvailableCapacityAt($moment);
    },
]]);

Combining Rule Types

Business Hours with Holidays

// Base schedule
$office->availabilityRules()->createMany([
    // Weekdays
    ['type' => 'weekdays', 'config' => ['days' => [1,2,3,4,5]], 
     'effect' => Effect::Allow, 'priority' => 10],
    
    // Business hours
    ['type' => 'time_of_day', 'config' => ['from' => '09:00', 'to' => '17:00'],
     'effect' => Effect::Allow, 'priority' => 20],
    
    // Holiday blackouts (overrides above)
    ['type' => 'blackout_date', 
     'config' => ['dates' => ['2025-12-25', '2025-01-01']],
     'effect' => Effect::Deny, 'priority' => 30],
]);

Seasonal Hours

// Summer hours (June-August)
$pool->availabilityRules()->createMany([
    // Summer months
    ['type' => 'months_of_year', 'config' => ['months' => [6,7,8]],
     'effect' => Effect::Allow, 'priority' => 10],
    
    // Extended hours in summer
    ['type' => 'time_of_day', 'config' => ['from' => '06:00', 'to' => '22:00'],
     'effect' => Effect::Allow, 'priority' => 20],
]);

// Winter hours (Sept-May)
$pool->availabilityRules()->createMany([
    // Winter months
    ['type' => 'months_of_year', 'config' => ['months' => [9,10,11,12,1,2,3,4,5]],
     'effect' => Effect::Allow, 'priority' => 30],
    
    // Reduced hours in winter
    ['type' => 'time_of_day', 'config' => ['from' => '08:00', 'to' => '18:00'],
     'effect' => Effect::Allow, 'priority' => 40],
]);

Next Steps

Getting Started

Installation
Set up the package in your Laravel app

Quick Start
Get running in 5 minutes

Basic Usage
Common patterns and examples


Core Concepts

How It Works
Understanding the evaluation engine

Rule Types
Available rule types and configurations

Priority System
How rule priority affects evaluation


Advanced Topics

Inventory Gates
Dynamic availability based on stock

Custom Evaluators
Build your own rule types

Complex Scenarios
Real-world implementation patterns

Performance Tips
Optimization strategies


API Reference

Configuration
Package configuration options

Models & Traits
Available models and traits

Testing
Testing your availability rules

Clone this wiki locally