### Install Project Dependencies Source: https://github.com/erikgall/motive-sdk/blob/main/CONTRIBUTING.md Installs all necessary PHP dependencies for the Motive SDK using Composer. This command should be run after cloning the repository. ```bash composer install ``` -------------------------------- ### Install and Configure Motive ELD Laravel SDK Source: https://context7.com/erikgall/motive-sdk/llms.txt Instructions for installing the Motive ELD Laravel SDK via Composer, publishing its configuration file, and setting up environment variables for API credentials and settings. ```bash // Install via Composer // composer require erikgall/motive-sdk // Publish configuration // php artisan vendor:publish --tag=motive-config // .env configuration // MOTIVE_API_KEY=your-api-key // MOTIVE_CLIENT_ID=your-client-id // MOTIVE_CLIENT_SECRET=your-client-secret // MOTIVE_REDIRECT_URI=https://your-app.com/motive/callback // MOTIVE_WEBHOOK_SECRET=your-webhook-secret // MOTIVE_TIMEZONE=America/Chicago // MOTIVE_METRIC_UNITS=false ``` ```php return [ 'default' => env('MOTIVE_CONNECTION', 'default'), 'connections' => [ 'default' => [ 'auth_driver' => env('MOTIVE_AUTH_DRIVER', 'api_key'), 'api_key' => env('MOTIVE_API_KEY'), 'oauth' => [ 'client_id' => env('MOTIVE_CLIENT_ID'), 'client_secret' => env('MOTIVE_CLIENT_SECRET'), 'redirect_uri' => env('MOTIVE_REDIRECT_URI'), ], 'base_url' => env('MOTIVE_BASE_URL', 'https://api.gomotive.com'), 'timeout' => 30, 'retry' => ['times' => 3, 'sleep' => 100], ], ], 'webhooks' => [ 'secret' => env('MOTIVE_WEBHOOK_SECRET'), 'tolerance' => 300, ], ]; ``` -------------------------------- ### Making Raw API Requests (PHP) Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Provides examples of making raw HTTP requests (GET and POST) to custom endpoints using the Motive SDK. It also demonstrates how to access the response data, status, and headers. ```php // Make a raw GET request $response = Motive::get('/v1/custom_endpoint', [ 'param' => 'value', ]); // Make a raw POST request $response = Motive::post('/v1/custom_endpoint', [ 'field' => 'value', ]); // Access response data $data = $response->json(); $status = $response->status(); $headers = $response->headers(); ``` -------------------------------- ### Install Motive ELD Laravel SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Installs the Motive ELD Laravel SDK using Composer and publishes the configuration file. Requires PHP 8.2+ and Laravel 11+. ```bash composer require erikgall/motive-sdk php artisan vendor:publish --tag=motive-config ``` -------------------------------- ### PHPUnit Unit Test Example Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md An example of a PHPUnit unit test demonstrating the TDD principle. This test focuses on parsing a driver log response correctly without external dependencies, adhering to the 'Red → Green → Refactor' workflow. ```php use PHPUnit\Framework\Attributes\Test; use Tests\TestCase; class SamsaraClientTest extends TestCase { #[Test] public function it_parses_driver_log_response_correctly(): void { $client = new SamsaraClient('test-api-key'); $response = ['driver_id' => '123', 'status' => 'ON_DUTY']; $result = $client->parseDriverLog($response); $this->assertEquals('123', $result->driverId); $this->assertEquals(DriverStatus::ON_DUTY, $result->status); } } ``` -------------------------------- ### PHP Method Naming Conventions Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Provides examples of recommended naming conventions for PHP methods, categorized by their purpose (boolean checkers, getters, setters, actions). This promotes consistency and clarity in the codebase. ```php // Boolean Checkers public function isConnected(): bool public function hasValidCredentials(): bool public function canFetchLogs(): bool // Getters public function getDriverLogs(): array public function getHosData(): HosData // Setters (fluent) public function setApiKey(string $apiKey): self public function setTimeout(int $seconds): self // Actions public function connect(): void public function fetchLogs(): LogCollection public function syncData(): bool ``` -------------------------------- ### Example Resource Class in PHP Source: https://github.com/erikgall/motive-sdk/blob/main/CONTRIBUTING.md Illustrates a Resource class in PHP, extending a base `Resource` class and utilizing traits for CRUD operations. It defines API versioning, base path, DTO class, and resource key. ```php Http::response(['data' => [...]], 200) ]); $service = app(EldService::class); $logs = $service->fetchDriverLogs('driver-123'); $this->assertNotEmpty($logs); Http::assertSent(function ($request) { return $request->url() === 'https://api.samsara.com/v1/driver-logs/driver-123'; }); } } ``` -------------------------------- ### Configure and Use Motive SDK Multi-Tenancy Features Source: https://context7.com/erikgall/motive-sdk/llms.txt This example demonstrates how to configure multiple API connections in Laravel's config file and use context modifiers like switching connections, setting API keys dynamically, specifying timezones, using metric units, and setting user IDs for audit trails. ```php use Motive\Facades\Motive; // Configure multiple connections in config/motive.php // 'connections' => [ // 'default' => ['api_key' => env('MOTIVE_API_KEY')], // 'company-a' => ['api_key' => env('MOTIVE_COMPANY_A_API_KEY')], // 'company-b' => ['api_key' => env('MOTIVE_COMPANY_B_API_KEY')], // ] // Switch connections $vehiclesA = Motive::connection('company-a')->vehicles()->list(); $vehiclesB = Motive::connection('company-b')->vehicles()->list(); // Dynamic API key at runtime $vehicles = Motive::withApiKey($tenant->motive_api_key) ->vehicles() ->list(); // Set timezone for datetime values $logs = Motive::withTimezone('America/Chicago') ->hosLogs() ->list(); // Use metric units (kilometers, liters) $vehicles = Motive::withMetricUnits() ->vehicles() ->list(); // Set user ID for audit trails $dispatch = Motive::withUserId($currentUser->id) ->dispatches() ->create([...]); // Chain multiple modifiers $vehicles = Motive::connection('company-a') ->withTimezone('America/Los_Angeles') ->withMetricUnits() ->withUserId($user->id) ->vehicles() ->list(); ``` -------------------------------- ### Create a New Vehicle with Motive SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Provides an example of creating a new vehicle record by passing an array of vehicle details to the `create` method of the Motive SDK. ```php $vehicle = Motive::vehicles()->create([ 'number' => 'TRUCK-042', 'make' => 'Freightliner', 'model' => 'Cascadia', 'year' => 2024, 'vin' => '1FUJGLDR5CLBP8834', 'license_plate_number' => 'ABC1234', 'license_plate_state' => 'TX', ]); echo "Created vehicle #{$vehicle->id}"; ``` -------------------------------- ### Get and Download Inspection Report PDF with PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Fetches a specific inspection report by its ID and downloads its signed PDF version, saving it to a local file. Requires the report ID. ```php $report = Motive::inspectionReports()->find($reportId); // Download the signed PDF $pdf = Motive::inspectionReports()->downloadPdf($reportId); file_put_contents('inspection-report.pdf', $pdf); ``` -------------------------------- ### Effective Code Commenting Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Provides examples of effective code comments for clarifying complex logic, such as converting timestamps, managing API rate limits, and mapping status codes. It advises against commenting obvious code, writing lengthy comments, or leaving commented-out code. ```php // Convert API timestamp to Carbon instance $timestamp = Carbon::createFromTimestamp($data['timestamp']); // API rate limit: 100 requests per minute $this->rateLimiter->throttle(100, 60); // Map API status codes to internal enum values return match ($apiStatus) { ... }; ``` -------------------------------- ### Example Data Transfer Object (DTO) in PHP Source: https://github.com/erikgall/motive-sdk/blob/main/CONTRIBUTING.md Demonstrates the structure of a Data Transfer Object (DTO) in PHP, extending a base class and utilizing Laravel Fluent for property casting and defaults. Includes PHPDoc annotations for type hinting and IDE support. ```php * * @property int $id * @property string $name * @property SomeStatus $status * @property CarbonImmutable|null $createdAt */ class Example extends DataTransferObject { protected array $casts = [ 'id' => 'int', 'status' => SomeStatus::class, 'createdAt' => CarbonImmutable::class, ]; protected array $defaults = [ 'active' => true, ]; } ``` -------------------------------- ### Manage Webhooks with Motive SDK (PHP) Source: https://context7.com/erikgall/motive-sdk/llms.txt This snippet demonstrates how to register, list, retrieve logs for, test, update, and delete webhooks using the Motive SDK. It includes examples of event subscriptions and secret management. Requires the Motive SDK for PHP. ```php use Motive\Facades\Motive; use Motive\Enums\WebhookEvent; // Register a webhook $webhook = Motive::webhooks()->create([ 'url' => 'https://your-app.com/webhooks/motive', 'events' => [ WebhookEvent::VehicleLocationUpdated->value, // 'vehicle.location_updated' WebhookEvent::DriverHosViolation->value, // 'driver.hos_violation' WebhookEvent::DispatchUpdated->value, // 'dispatch.updated' WebhookEvent::GeofenceEntered->value, // 'geofence.entered' ], 'secret' => 'your-webhook-secret', ]); // List all webhooks $webhooks = Motive::webhooks()->list(); foreach ($webhooks as $webhook) { echo "{$webhook->url}: " . implode(', ', $webhook->events) . "\n"; } // Get webhook delivery logs $logs = Motive::webhooks()->logs($webhookId); foreach ($logs as $log) { echo "{$log->event}: {$log->status} at {$log->sentAt}\n"; } // Test a webhook $tested = Motive::webhooks()->test($webhookId); // Returns bool // Update and delete $webhook = Motive::webhooks()->update($webhookId, ['url' => 'https://new-url.com/webhooks']); $deleted = Motive::webhooks()->delete($webhookId); ``` -------------------------------- ### Handle Motive API Errors with Typed Exceptions Source: https://context7.com/erikgall/motive-sdk/llms.txt This example shows how to use try-catch blocks to handle various exceptions thrown by the Motive SDK. It covers specific exceptions like AuthenticationException, ValidationException, and RateLimitException, as well as a general MotiveException. ```php use Motive\Facades\Motive; use Motive\Exceptions\MotiveException; use Motive\Exceptions\AuthenticationException; use Motive\Exceptions\AuthorizationException; use Motive\Exceptions\ValidationException; use Motive\Exceptions\NotFoundException; use Motive\Exceptions\RateLimitException; use Motive\Exceptions\ServerException; try { $vehicle = Motive::vehicles()->create([ 'number' => 'TRUCK-001', 'make' => 'Freightliner', ]); } catch (NotFoundException $e) { // Resource not found (404) echo "Not found: {$e->getMessage()}\n"; } catch (AuthenticationException $e) { // Invalid API key or expired token (401) echo "Auth failed: {$e->getMessage()}\n"; } catch (AuthorizationException $e) { // Insufficient permissions (403) echo "Forbidden: {$e->getMessage()}\n"; } catch (ValidationException $e) { // Invalid request data (422) foreach ($e->errors() as $field => $messages) { echo "{$field}: " . implode(', ', $messages) . "\n"; } } catch (RateLimitException $e) { // Too many requests (429) $retryAfter = $e->retryAfter(); // Seconds to wait echo "Rate limited. Retry after: {$retryAfter} seconds\n"; } catch (ServerException $e) { // Server error (5xx) echo "Server error: {$e->getMessage()}\n"; } catch (MotiveException $e) { // Any other Motive API error $statusCode = $e->getCode(); $response = $e->getResponse(); // Response object $body = $e->getResponseBody(); // Decoded JSON array echo "Error ({$statusCode}): {$e->getMessage()}\n"; } ``` -------------------------------- ### Code Formatting with Pint Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Shows the command to run Pint for code formatting before committing changes. It highlights key formatting rules such as aligning array arrows, using snake case for test methods, sorting imports, and avoiding unused imports. ```bash vendor/bin/pint --dirty ``` -------------------------------- ### Get HOS Violations with Motive SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Fetches Hours of Service (HOS) violations for specified drivers within a date range. Provides details on violation type, start time, and duration. Requires the Motive SDK. ```php $violations = Motive::hosViolations()->list([ 'driver_ids' => [123], 'start_date' => now()->subDays(30)->toDateString(), ]); foreach ($violations as $violation) { echo $violation->type; // e.g., "11_hour", "14_hour", "30_minute_break" echo $violation->startTime->format('Y-m-d H:i'); echo $violation->duration . ' minutes'; } ``` -------------------------------- ### PHP Early Return vs. Else Statement Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Demonstrates the preferred use of early returns in PHP for cleaner control flow, avoiding unnecessary else statements. This improves readability and maintainability. ```php // GOOD if (! $condition) { return; } // Continue with main logic // BAD - Don't do this if ($condition) { // logic } else { return; } ``` -------------------------------- ### Clone Motive SDK Repository Source: https://github.com/erikgall/motive-sdk/blob/main/CONTRIBUTING.md Clones the Motive SDK repository to your local machine. This is the first step in setting up the development environment. ```bash git clone https://github.com/your-username/motive-sdk.git cd motive-sdk ``` -------------------------------- ### PHP Constructor Property Promotion Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Demonstrates the use of PHP 8+ constructor property promotion for concise class constructors. This feature reduces boilerplate code by declaring and initializing properties directly in the constructor signature. ```php public function __construct( public string $apiKey, protected HttpClient $httpClient, protected ?int $timeout = 30 ) {} ``` -------------------------------- ### Get Current Vehicle Location Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Retrieves the current location data for a specified vehicle, including latitude, longitude, speed, bearing, and timestamp. ```php $location = Motive::vehicles()->currentLocation(123); echo "Lat: {$location->latitude}, Lng: {$location->longitude}"; echo "Speed: {$location->speed} mph"; echo "Heading: {$location->bearing}"; echo "Updated: {$location->locatedAt->diffForHumans()}"; ``` -------------------------------- ### Get Vehicle Location History Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Fetches a history of location data for a vehicle within a specified date range. Allows iteration through location records, accessing timestamp and coordinates. ```php $locations = Motive::vehicles()->locations(123, [ 'start_date' => now()->subDays(7)->toDateString(), 'end_date' => now()->toDateString(), ]); foreach ($locations as $location) { echo "{$location->locatedAt}: ({$location->latitude}, {$location->longitude})"; } ``` -------------------------------- ### PHP Parameter Type Hinting Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Highlights the requirement for using type hints for all parameters in PHP methods. This improves code reliability and makes method signatures more informative. ```php public function setTimeout(int $seconds): self public function fetchLogs(string $driverId, Carbon $startDate): LogCollection ``` -------------------------------- ### Get HOS Availability for Multiple Drivers with Motive SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Retrieves Hours of Service (HOS) availability for multiple drivers simultaneously. Useful for dashboard overviews. Requires the Motive SDK. ```php $availabilities = Motive::hosAvailability()->list([ 'driver_ids' => [123, 456, 789], ]); foreach ($availabilities as $availability) { echo "{$availability->driver->firstName}: {$availability->driveTimeRemaining} min remaining"; } ``` -------------------------------- ### Adding Macro Extensions to Resources (PHP) Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Explains how to extend resource classes with custom macros, such as adding a 'findByLicensePlate' method to the VehiclesResource. This allows for more concise and reusable API interactions. ```php // In a service provider use Motive\Resources\VehiclesResource; VehiclesResource::macro('findByLicensePlate', function (string $plate) { return $this->list(['license_plate_number' => $plate])->first(); }); // Usage $vehicle = Motive::vehicles()->findByLicensePlate('ABC1234'); ``` -------------------------------- ### Get HOS Availability with Motive SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Fetches Hours of Service (HOS) availability for a single driver, including remaining drive, shift, and cycle times, and required breaks. Requires the Motive SDK. ```php $availability = Motive::hosAvailability()->forDriver(123); echo "Drive time remaining: {$availability->driveTimeRemaining} minutes"; echo "Shift time remaining: {$availability->shiftTimeRemaining} minutes"; echo "Cycle time remaining: {$availability->cycleTimeRemaining} minutes"; echo "Break time required in: {$availability->breakTimeRequired} minutes"; // Check if driver can drive if ($availability->driveTimeRemaining > 0 && $availability->shiftTimeRemaining > 0) { echo "Driver is available to drive"; } ``` -------------------------------- ### PHP PHPDoc Array Shape Definitions Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Provides examples of PHPDoc annotations for defining array shapes, including generic collections and specific structures. This enhances type clarity for array data. ```php /** * @return array */ /** * @return Collection */ /** * @return array{driver_id: string, status: string, logs: array} */ ``` -------------------------------- ### Configure Multi-Connection for Multi-Tenancy in PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Shows how to configure multiple Motive API connections within the `config/motive.php` file. This is essential for multi-tenant applications, allowing different API keys or credentials to be managed for distinct clients or companies. ```php // config/motive.php return [ 'default' => 'default', 'connections' => [ 'default' => [ 'auth_driver' => 'api_key', 'api_key' => env('MOTIVE_API_KEY'), ], 'company-a' => [ 'auth_driver' => 'api_key', 'api_key' => env('MOTIVE_COMPANY_A_API_KEY'), ], 'company-b' => [ 'auth_driver' => 'api_key', 'api_key' => env('MOTIVE_COMPANY_B_API_KEY'), ], ], ]; ``` -------------------------------- ### PHP Class-Level PHPDoc Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Shows the standard format for PHPDoc blocks at the class level, including a concise description and author information. This is crucial for code documentation and understanding. ```php /** * Samsara ELD API client. * * @author Your Name */ class SamsaraClient ``` -------------------------------- ### Get HOS Logs with Motive SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Retrieves Hours of Service (HOS) logs for specified drivers within a date range. Supports filtering by duty status. Requires the Motive SDK and Motive Enums. ```php use Motive\Enums\DutyStatus; $logs = Motive::hosLogs()->list([ 'driver_ids' => [123, 456], 'start_date' => now()->subDays(7)->toDateString(), 'end_date' => now()->toDateString(), ]); foreach ($logs as $log) { echo $log->driver->firstName . ' ' . $log->driver->lastName; echo $log->status->value; // DutyStatus enum echo $log->startTime->format('Y-m-d H:i:s'); echo $log->duration . ' minutes'; echo $log->location; } // Filter by duty status $drivingLogs = Motive::hosLogs()->list([ 'driver_ids' => [123], 'duty_status' => DutyStatus::Driving->value, ]); ``` -------------------------------- ### Run Static Analysis with PHPStan Source: https://github.com/erikgall/motive-sdk/blob/main/CONTRIBUTING.md Performs static analysis on the codebase using PHPStan at level 8. This helps identify potential bugs and type errors. ```bash ./bin/phpstan analyse ``` -------------------------------- ### PHP Class Naming Conventions Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Outlines standard naming conventions for PHP classes within the SDK, including clients, DTOs, exceptions, and resources. Adhering to these conventions improves project organization and understanding. ```php // Clients: {Provider}Client (e.g., SamsaraClient) // DTOs: {Domain}Data (e.g., HosData, DriverLogData) // Exceptions: {Domain}Exception (e.g., ApiConnectionException) // Resources: {Entity}Resource (e.g., DriverResource) ``` -------------------------------- ### PHPDoc for Class Documentation in PHP Source: https://github.com/erikgall/motive-sdk/blob/main/CONTRIBUTING.md Shows how to write PHPDoc comments for class-level documentation in PHP, including author tags, property type hints, and descriptions. This enhances code readability and maintainability. ```php * * @property int $id * @property string $name */ class MyClass { // Class properties and methods } ``` -------------------------------- ### Create/Edit HOS Log Entry with Motive SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Creates a new Hours of Service (HOS) log entry or edits an existing one. Supports setting status, start time, location, and annotations. Requires the Motive SDK and Motive Enums. ```php // Create a new log entry $log = Motive::hosLogs()->create([ 'driver_id' => 123, 'status' => DutyStatus::OnDuty->value, 'start_time' => now()->toIso8601String(), 'location' => 'Dallas, TX', 'notes' => 'Pre-trip inspection', ]); // Edit an existing entry (with annotation) $log = Motive::hosLogs()->update($log->id, [ 'status' => DutyStatus::Driving->value, 'annotation' => 'Corrected status from On Duty to Driving', ]); ``` -------------------------------- ### Run PHPUnit Tests Source: https://github.com/erikgall/motive-sdk/blob/main/CONTRIBUTING.md Executes the full test suite for the Motive SDK using PHPUnit. This verifies that the project is set up correctly and all tests are passing. ```bash ./vendor/bin/phpunit ``` -------------------------------- ### Utilize SDK Enums for Type Safety (PHP) Source: https://context7.com/erikgall/motive-sdk/llms.txt Showcases the use of strongly-typed enums provided by the SDK for status values and event types. This ensures type safety across the application when interacting with the Motive API. Examples include DutyStatus, VehicleStatus, DispatchStatus, and WebhookEvent enums. ```php use Motive\Enums\DutyStatus; use Motive\Enums\VehicleStatus; use Motive\Enums\DispatchStatus; use Motive\Enums\WebhookEvent; // Duty Status values DutyStatus::Driving; // 'driving' DutyStatus::OffDuty; // 'off_duty' DutyStatus::OnDuty; // 'on_duty' DutyStatus::SleeperBerth; // 'sleeper_berth' DutyStatus::YardMove; // 'yard_move' DutyStatus::PersonalConveyance; // 'personal_conveyance' // Webhook Event types WebhookEvent::VehicleCreated; // 'vehicle.created' WebhookEvent::VehicleUpdated; // 'vehicle.updated' WebhookEvent::VehicleLocationUpdated; // 'vehicle.location_updated' WebhookEvent::DriverCreated; // 'driver.created' WebhookEvent::DriverHosStatusChanged; // 'driver.hos_status_changed' WebhookEvent::DriverHosViolation; // 'driver.hos_violation' WebhookEvent::DispatchCreated; // 'dispatch.created' WebhookEvent::DispatchUpdated; // 'dispatch.updated' WebhookEvent::GeofenceEntered; // 'geofence.entered' WebhookEvent::GeofenceExited; // 'geofence.exited' WebhookEvent::InspectionSubmitted; // 'inspection.submitted' WebhookEvent::FaultCodeDetected; // 'fault_code.detected' // Using enum values in API calls $logs = Motive::hosLogs()->list([ 'duty_status' => DutyStatus::Driving->value, ]); ``` -------------------------------- ### Implement Custom Token Store with PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Demonstrates how to create a custom token store by implementing the TokenStore contract. This allows for persistent storage of access and refresh tokens, typically in a database, to manage authentication with the Motive API. ```php use Motive\Contracts\TokenStore; class DatabaseTokenStore implements TokenStore { public function __construct( protected User $user ) {} public function getAccessToken(): ?string { return $this->user->motive_access_token; } public function getRefreshToken(): ?string { return $this->user->motive_refresh_token; } public function getExpiresAt(): ?CarbonInterface { return $this->user->motive_token_expires_at; } public function store(string $accessToken, string $refreshToken, CarbonInterface $expiresAt): void { $this->user->update([ 'motive_access_token' => $accessToken, 'motive_refresh_token' => $refreshToken, 'motive_token_expires_at' => $expiresAt, ]); } } // Usage Motive::withTokenStore(new DatabaseTokenStore($user))->vehicles()->list(); ``` -------------------------------- ### Use OAuth Tokens for API Requests with Motive SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Demonstrates how to make API requests using stored OAuth access tokens. By providing the access token, refresh token, and expiration time, the SDK can authenticate requests on behalf of the user. This example shows listing vehicles. ```php // With stored tokens Motive::withOAuth( accessToken: $user->motive_access_token, refreshToken: $user->motive_refresh_token, expiresAt: $user->motive_token_expires_at, )->vehicles()->list(); ``` -------------------------------- ### Create a New Asset with PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Creates a new asset, such as a trailer or container, by providing its details. Requires parameters like name, asset type, make, model, year, VIN, and license plate information. ```php $asset = Motive::assets()->create([ 'name' => 'TRAILER-001', 'asset_type' => 'trailer', 'make' => 'Great Dane', 'model' => 'Everest', 'year' => 2023, 'vin' => '1GRAA0622DB500001', 'license_plate_number' => 'TRL1234', 'license_plate_state' => 'TX', ]); ``` -------------------------------- ### Create a User with Motive SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Creates a new user in the Motive system. Supports specifying user details and driver-specific information. Requires the Motive SDK. ```php $user = Motive::users()->create([ 'first_name' => 'John', 'last_name' => 'Doe', 'email' => 'john.doe@example.com', 'phone' => '555-123-4567', 'role' => 'driver', 'driver' => [ 'license_number' => 'DL123456', 'license_state' => 'TX', ], ]); ``` -------------------------------- ### Get Driver Scorecard with Motive SDK Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Fetches a driver's scorecard, providing an overview of their performance metrics. Includes an overall score and scores for specific behaviors like harsh braking and speeding, along with total miles driven. Requires driver ID and a date range. ```php $scorecard = Motive::scorecard()->forDriver(123, [ 'start_date' => now()->subDays(30)->toDateString(), 'end_date' => now()->toDateString(), ]); echo "Overall Score: {$scorecard->overallScore}"; echo "Harsh Braking: {$scorecard->harshBrakingScore}"; echo "Speeding: {$scorecard->speedingScore}"; echo "Miles Driven: {$scorecard->totalMiles}"; ``` -------------------------------- ### Use Different Motive API Connections in PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Illustrates how to switch between different configured Motive API connections at runtime. This enables your application to interact with different tenants or environments by specifying the desired connection alias. ```php // Use default connection $vehicles = Motive::vehicles()->list(); // Use specific connection $vehiclesA = Motive::connection('company-a')->vehicles()->list(); $vehiclesB = Motive::connection('company-b')->vehicles()->list(); ``` -------------------------------- ### Download a Document with PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Downloads a specific document by its ID and saves its content to a local file. Requires the document ID. ```php $content = Motive::documents()->download($document->id); file_put_contents('downloaded-document.pdf', $content); ``` -------------------------------- ### PHP Explicit Nullable and Union Types Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Illustrates the use of explicit nullable types (e.g., `?string`) and union types (e.g., `string|int`) in PHP. These features improve type safety and expressiveness. ```php public function getLastSync(): ?Carbon protected ?string $authToken = null; public function find(string|int $driverId): ?Driver ``` -------------------------------- ### Format Code with Laravel Pint Source: https://github.com/erikgall/motive-sdk/blob/main/CONTRIBUTING.md Applies code style formatting to the entire project using Laravel Pint. This command ensures code consistency across the SDK. ```bash ./vendor/bin/pint ``` -------------------------------- ### List Geofences with PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Retrieves a list of geofences and iterates through them, displaying their name, type, and radius (for circular geofences). ```php $geofences = Motive::geofences()->list(); foreach ($geofences as $geofence) { echo $geofence->name; echo $geofence->type; // 'circle', 'polygon' echo "Radius: {$geofence->radius} meters"; } ``` -------------------------------- ### Dynamic Authentication with Motive API in PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Demonstrates dynamic authentication methods for the Motive API, allowing you to set API keys or OAuth tokens on-the-fly. This is useful for scenarios where authentication details are not statically configured but determined at runtime, such as per-tenant. ```php // Dynamically set API key at runtime $vehicles = Motive::withApiKey($tenant->motive_api_key) ->vehicles() ->list(); // Or with OAuth tokens $vehicles = Motive::withOAuth($tenant->access_token, $tenant->refresh_token) ->vehicles() ->list(); ``` -------------------------------- ### PHP PHPDoc Property Type Annotation Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Demonstrates how to use PHPDoc to specify the type of a property, particularly for arrays with defined structures. This improves code readability and maintainability. ```php /** * The API endpoints configuration. * * @var array */ protected array $endpoints; ``` -------------------------------- ### PHP Match Expression for Value Returns Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Shows how to use PHP 8+ match expressions for concise and readable conditional value assignments. This is preferred over traditional switch statements for simple value mapping. ```php $status = match ($eldResponse['status']) { 'ON_DUTY' => DriverStatus::ON_DUTY, 'OFF_DUTY' => DriverStatus::OFF_DUTY, 'DRIVING' => DriverStatus::DRIVING, default => DriverStatus::UNKNOWN, }; ``` -------------------------------- ### Fake Motive Client for Testing in PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Demonstrates how to use `Motive::fake()` to mock the Motive client for unit testing. This allows you to simulate API responses, assert that specific requests were made, and verify the behavior of your code without making actual HTTP calls. ```php use Motive\Facades\Motive; use Motive\Data\Vehicle; public function test_it_syncs_vehicles(): void { Motive::fake([ 'vehicles' => [ Vehicle::factory()->make(['number' => 'TRUCK-001']), Vehicle::factory()->make(['number' => 'TRUCK-002']), ], ]); $this->artisan('sync:vehicles'); Motive::assertRequested('vehicles.list'); Motive::assertRequestCount(1); $this->assertDatabaseHas('vehicles', ['number' => 'TRUCK-001']); $this->assertDatabaseHas('vehicles', ['number' => 'TRUCK-002']); } ``` -------------------------------- ### Manage Fleet Users and Drivers with Motive SDK (PHP) Source: https://context7.com/erikgall/motive-sdk/llms.txt This snippet demonstrates how to manage fleet users and drivers using the Motive SDK in PHP. It covers listing, filtering, finding, creating, updating, deactivating, and reactivating users. It also shows how to access and manage driver-specific data like license information. ```php use Motive\Facades\Motive; // List all users $users = Motive::users()->list(); foreach ($users as $user) { echo "{$user->firstName} {$user->lastName} - {$user->email} ({$user->role})\n"; } // Filter by role $drivers = Motive::users()->list(['role' => 'driver']); // Find a user with driver data $user = Motive::users()->find(456); if ($user->driver) { echo "Driver License: {$user->driver->licenseNumber} ({$user->driver->licenseState})\n"; } // Create a new driver $user = Motive::users()->create([ 'first_name' => 'John', 'last_name' => 'Doe', 'email' => 'john.doe@example.com', 'phone' => '555-123-4567', 'role' => 'driver', 'driver' => [ 'license_number' => 'DL123456', 'license_state' => 'TX', ], ]); // Update user $user = Motive::users()->update(456, ['phone' => '555-987-6543']); // Deactivate and reactivate Motive::users()->deactivate(456); // Returns bool Motive::users()->reactivate(456); // Returns bool ``` -------------------------------- ### Manage Assets with Motive SDK (PHP) Source: https://context7.com/erikgall/motive-sdk/llms.txt This snippet demonstrates how to manage assets (trailers, containers, etc.) using the Motive SDK. It covers listing, creating, assigning to vehicles, updating, and deleting assets. Requires the Motive SDK for PHP. ```php use Motive\Facades\Motive; // List all assets $assets = Motive::assets()->list(); foreach ($assets as $asset) { echo "{$asset->name} ({$asset->assetType}): {$asset->status->value}\n"; } // Create an asset $asset = Motive::assets()->create([ 'name' => 'TRAILER-001', 'asset_type' => 'trailer', 'make' => 'Great Dane', 'model' => 'Everest', 'year' => 2023, 'vin' => '1GRAA0622DB500001', 'license_plate_number' => 'TRL1234', 'license_plate_state' => 'TX', ]); // Assign asset to a vehicle $assigned = Motive::assets()->assignToVehicle($asset->id, $vehicleId); // Returns bool // Unassign asset from vehicle $unassigned = Motive::assets()->unassignFromVehicle($asset->id); // Returns bool // Update and delete $asset = Motive::assets()->update($asset->id, ['name' => 'TRAILER-001-UPDATED']); $deleted = Motive::assets()->delete($asset->id); ``` -------------------------------- ### Manage Dispatches with Motive SDK (PHP) Source: https://context7.com/erikgall/motive-sdk/llms.txt This snippet demonstrates how to manage dispatches, including load assignments and delivery tracking, using the Motive SDK in PHP. It covers listing dispatches by status, creating new dispatches, updating their status, finding specific dispatches, and deleting them. ```php use Motive\Facades\Motive; use Motive\Enums\DispatchStatus; // List dispatches by status $dispatches = Motive::dispatches()->list([ 'status' => DispatchStatus::InProgress->value, ]); foreach ($dispatches as $dispatch) { echo "#{$dispatch->externalId}: {$dispatch->status->value}\n"; echo "Driver: {$dispatch->driver->firstName} {$dispatch->driver->lastName}\n"; foreach ($dispatch->stops as $stop) { echo " - {$stop->type}: {$stop->address}\n"; } } // Get dispatches by status (alternative method) $activeDispatches = Motive::dispatches()->byStatus('in_progress'); // Create a dispatch $dispatch = Motive::dispatches()->create([ 'external_id' => 'ORDER-12345', 'driver_id' => 123, 'vehicle_id' => 456, 'notes' => 'Handle with care - fragile items', ]); // Update dispatch status $dispatch = Motive::dispatches()->update($dispatch->id, [ 'status' => DispatchStatus::Completed->value, ]); // Find and delete $dispatch = Motive::dispatches()->find($dispatchId); $deleted = Motive::dispatches()->delete($dispatchId); ``` -------------------------------- ### PHP Guard Clause for Validation Source: https://github.com/erikgall/motive-sdk/blob/main/CLAUDE.md Illustrates the use of guard clauses in PHP for input validation and early exit. This pattern ensures that preconditions are met before proceeding with the main logic, enhancing robustness. ```php if (! $this->client->isAuthenticated()) { throw new AuthenticationException('ELD API client not authenticated'); } return $this->client->request($endpoint); ``` -------------------------------- ### List Documents with PHP Source: https://github.com/erikgall/motive-sdk/blob/main/README.md Retrieves a list of documents, filterable by driver ID and status. It then iterates through the documents, displaying their name, type, and status. ```php $documents = Motive::documents()->list([ 'driver_id' => 123, 'status' => 'pending', ]); foreach ($documents as $document) { echo $document->name; echo $document->type; echo $document->status->value; } ```