PHPackages                             timjohnbancroft/constructor-laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. timjohnbancroft/constructor-laravel

ActiveLibrary[Search &amp; Filtering](/categories/search)

timjohnbancroft/constructor-laravel
===================================

Laravel integration for Constructor.io - AI-powered search, recommendations, and shopping agents

v1.3.0(4mo ago)07.4k↓90%MITPHPPHP ^8.1

Since Jan 30Pushed 4mo agoCompare

[ Source](https://github.com/timjohnbancroft/constructor-laravel)[ Packagist](https://packagist.org/packages/timjohnbancroft/constructor-laravel)[ Docs](https://github.com/timjohnbancroft/constructor-laravel)[ RSS](/packages/timjohnbancroft-constructor-laravel/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (5)Versions (3)Used By (0)

Constructor.io Laravel Integration
==================================

[](#constructorio-laravel-integration)

[![Latest Version on Packagist](https://camo.githubusercontent.com/8749f33805c406dfb641a1da00a0f7730ac5ec4d85f2e0142ad969745781236a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f74696d6a6f686e62616e63726f66742f636f6e7374727563746f722d6c61726176656c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/timjohnbancroft/constructor-laravel)[![License](https://camo.githubusercontent.com/1f72764121973393765a3a17b1a19ae93d5d58126e8e604cd459a7a9439495da/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f74696d6a6f686e62616e63726f66742f636f6e7374727563746f722d6c61726176656c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/timjohnbancroft/constructor-laravel)

A Laravel package for [Constructor.io](https://constructor.io) - AI-powered product discovery.

Features
--------

[](#features)

- **Product Search** - Full-text search with filters, sorting, pagination
- **Category Browse** - Browse products by category or facet
- **Autocomplete** - Search suggestions and product previews with zero-state support
- **AI Shopping Agent** - Natural language product discovery ("I need a gift for my mom")
- **Product Insights Agent** - AI-powered Q&amp;A on product detail pages
- **Recommendations** - Personalized product recommendations
- **Collections** - Browse curated product collections
- **Catalog Management** - Bulk catalog uploads (CSV, JSONL)
- **Backend Integration** - Automatic forwarding of user context headers and cookies for server-side API calls
- **Laravel Scout** - Full Scout engine integration

Architecture Overview
---------------------

[](#architecture-overview)

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                           Your Laravel Application                          │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   ┌─────────────────────┐    ┌────────────────────────────────────────┐    │
│   │  Constructor Facade │───▶│  ConstructorSandboxSearch              │    │
│   │  (Search/Browse)    │    │  - search(), browse(), autocomplete()  │    │
│   └─────────────────────┘    │  - getRecommendations()                │    │
│                              │  - getBrowseGroups(), getCollections() │    │
│                              └──────────────┬─────────────────────────┘    │
│                                             │                               │
│   ┌─────────────────────┐                   ▼                               │
│   │ ConstructorService  │    ┌────────────────────────────────────────┐    │
│   │ (Catalog Management)│───▶│        ac.cnstrc.com (Search API)      │    │
│   │ - uploadCatalog()   │    └────────────────────────────────────────┘    │
│   │ - getTaskStatus()   │                                                   │
│   └─────────────────────┘                                                   │
│                                                                             │
│   ┌─────────────────────┐    ┌────────────────────────────────────────┐    │
│   │ ConstructorAgent    │───▶│      agent.cnstrc.com (Agent API)      │    │
│   │ Service             │    │  - AI Shopping Agent                   │    │
│   │ - askShoppingAgent()│    │  - Product Insights Agent              │    │
│   │ - askProductQuestion│    └────────────────────────────────────────┘    │
│   └─────────────────────┘                                                   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

```

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10.x, 11.x, or 12.x
- Constructor.io account ([constructor.io](https://constructor.io))

Installation
------------

[](#installation)

### 1. Install via Composer

[](#1-install-via-composer)

```
composer require timjohnbancroft/constructor-laravel
```

### 2. Publish Configuration

[](#2-publish-configuration)

```
php artisan vendor:publish --provider="ConstructorIO\Laravel\ConstructorServiceProvider"
```

### 3. Configure Environment

[](#3-configure-environment)

Add to your `.env` file:

```
CONSTRUCTOR_API_KEY=your-api-key
CONSTRUCTOR_API_TOKEN=your-api-token
CONSTRUCTOR_AGENT_DOMAIN=your-agent-domain  # Optional: for AI Shopping Agent

# Optional: Backend integration (for server-side calls on behalf of browser users)
CONSTRUCTOR_BACKEND_TOKEN=your-backend-token      # Falls back to API_TOKEN if not set
CONSTRUCTOR_CLIENT_IDENTIFIER=cio-be-laravel-your-company  # Auto-generates if not set
```

Get your credentials from the [Constructor.io Dashboard](https://app.constructor.io).

**Credential Types:**

- **API Key** (public): Identifies your index, used for search/browse/autocomplete requests
- **API Token** (secret): Used for authenticated operations like catalog uploads

Quick Start
-----------

[](#quick-start)

### Search Products

[](#search-products)

```
use ConstructorIO\Laravel\Facades\Constructor;

// Basic search
$results = Constructor::search('blue shoes');

// With filters and options
$results = Constructor::search('shoes', [
    'brand' => ['Nike', 'Adidas'],
    'color' => ['blue'],
], [
    'page' => 1,
    'per_page' => 24,
    'sort_by' => 'price',
    'sort_order' => 'ascending',
]);

// Access results
foreach ($results->products as $product) {
    echo $product['name'];
    echo $product['price'];
    echo $product['image_url'];
}

// Pagination
echo "Page {$results->page} of {$results->totalPages()}";
echo "Total: {$results->total} products";
```

### Browse by Category

[](#browse-by-category)

```
use ConstructorIO\Laravel\Facades\Constructor;

// Browse by category
$results = Constructor::browse('group_id', 'mens-clothing');

// Browse by brand
$results = Constructor::browse('brand', 'Nike', [], [
    'page' => 1,
    'per_page' => 24,
]);

// Get category hierarchy
$categories = Constructor::getBrowseGroups([
    'max_items' => 10,
    'max_children' => 5,
    'with_images' => true,
]);
```

### Autocomplete

[](#autocomplete)

```
use ConstructorIO\Laravel\Facades\Constructor;

// Get autocomplete suggestions
$results = Constructor::autocomplete('blu', [
    'sections' => [
        'suggestions' => ['enabled' => true, 'limit' => 5],
        'products' => ['enabled' => true, 'limit' => 6],
    ],
]);

foreach ($results->suggestions as $suggestion) {
    echo $suggestion['term'];
}

// Zero-state (search box focused but empty)
$zeroState = Constructor::getZeroStateData([
    'show_top_categories' => true,
    'show_popular_products' => true,
    'recommendation_pod_id' => 'hp-bestsellers',
]);
```

### Recommendations

[](#recommendations)

```
use ConstructorIO\Laravel\Facades\Constructor;

// Home page recommendations
$recs = Constructor::getRecommendations('home-page-1', [
    'num_results' => 8,
]);

// Product page recommendations (requires item_id)
$similar = Constructor::getItemRecommendations('pdp-similar', 'PRODUCT-123');
```

### Collections

[](#collections)

```
use ConstructorIO\Laravel\Facades\Constructor;

// Get all collections
$collections = Constructor::getCollections(['max_items' => 10]);

// Get collection metadata
$collection = Constructor::getCollection('summer-essentials');

// Browse products in a collection
$results = Constructor::browseCollection('summer-essentials', [], [
    'page' => 1,
    'per_page' => 24,
]);
```

### AI Shopping Agent

[](#ai-shopping-agent)

```
use ConstructorIO\Laravel\Services\ConstructorAgentService;

$agent = app(ConstructorAgentService::class);

// Natural language query
$response = $agent->askShoppingAgent('I need a gift for my mom who likes gardening');

echo $response['message'];
foreach ($response['products'] as $product) {
    echo $product['name'];
}

// Continue conversation
$followUp = $agent->askShoppingAgent(
    'Something under $50',
    $response['thread_id']
);
```

### Product Insights Agent

[](#product-insights-agent)

```
use ConstructorIO\Laravel\Services\ConstructorAgentService;

$agent = app(ConstructorAgentService::class);

// Get suggested questions for a product
$questions = $agent->getProductQuestions('PRODUCT-123');

// Ask a question about a product
$answer = $agent->askProductQuestion(
    question: 'Is this true to size?',
    itemId: 'PRODUCT-123'
);

echo $answer['answer'];
```

### Catalog Management

[](#catalog-management)

```
use ConstructorIO\Laravel\Services\ConstructorService;

$constructor = app(ConstructorService::class);

// Upload catalog file (creates or replaces all items)
$result = $constructor->uploadCatalog(
    storage_path('app/catalog/items.csv'),
    'create_or_replace'
);

// Or patch (update only specified items)
$result = $constructor->uploadCatalog(
    storage_path('app/catalog/updates.csv'),
    'patch'
);

// Wait for completion
$status = $constructor->waitForTaskCompletion($result['task_id']);

if ($status['successful']) {
    echo "Catalog uploaded!";
}
```

### Recipes (If Configured)

[](#recipes-if-configured)

```
use ConstructorIO\Laravel\Facades\Constructor;

// Check if recipes are supported
if (Constructor::supportsRecipes()) {
    // Search recipes
    $results = Constructor::searchRecipes('chicken pasta');

    // Browse recipes by category
    $results = Constructor::browseRecipes('meal_type', 'dinner');

    // Get a single recipe
    $recipe = Constructor::getRecipe('recipe-123');
}
```

Data Transfer Objects (DTOs)
----------------------------

[](#data-transfer-objects-dtos)

All search operations return strongly-typed DTOs with convenient methods.

### SearchResults

[](#searchresults)

Returned by `search()`, `browse()`, and `browseCollection()`.

```
$results = Constructor::search('shoes');

// Properties
$results->products      // array - Product data
$results->total         // int - Total matching results
$results->page          // int - Current page (1-indexed)
$results->perPage       // int - Results per page
$results->facets        // array - Available filters with counts
$results->groups        // array - Category hierarchy (for browse)
$results->metadata      // array - Request ID, result ID, etc.

// Methods
$results->hasMore()        // bool - More pages available?
$results->totalPages()     // int - Calculate total pages
$results->isEmpty()        // bool - No products?
$results->count()          // int - Products on this page
$results->getOffset()      // int - Offset for "Showing X-Y of Z"
$results->nextPageNumber() // int - Next page number or 0
$results->toArray()        // array - For JSON serialization
```

**Facets Structure:**

```
// $results->facets
[
    'brand' => [
        'name' => 'Brand',           // Display name
        'values' => [                 // Value => count
            'Nike' => 45,
            'Adidas' => 32,
        ],
        'type' => 'checkbox_list',   // single_select, checkbox_list, or range
    ],
    'price' => [
        'name' => 'Price',
        'values' => [...],
        'type' => 'range',
        'min' => 25.00,
        'max' => 299.99,
    ],
]
```

### AutocompleteResults

[](#autocompleteresults)

Returned by `autocomplete()` and `getZeroStateData()`.

```
$results = Constructor::autocomplete('blu');

// Properties
$results->suggestions      // array - Search term suggestions
$results->products         // array - Product previews
$results->categories       // array - Category suggestions
$results->trending         // array - Trending searches (zero-state)
$results->popularProducts  // array - Popular products (zero-state)
$results->topCategories    // array - Top categories (zero-state)
$results->metadata         // array - Request metadata

// Methods
$results->hasSuggestions()     // bool
$results->hasProducts()        // bool
$results->hasCategories()      // bool
$results->hasZeroStateData()   // bool
$results->hasTrending()        // bool
$results->hasPopularProducts() // bool
$results->hasTopCategories()   // bool
$results->isEmpty()            // bool
$results->isAutocompleteEmpty() // bool - Ignores zero-state
$results->toArray()            // array
```

### RecommendationResults

[](#recommendationresults)

Returned by `getRecommendations()` and `getItemRecommendations()`.

```
$recs = Constructor::getRecommendations('home-bestsellers');

// Properties
$recs->podId       // string - The pod ID requested
$recs->title       // string - Pod display name
$recs->products    // array - Recommended products
$recs->total       // int - Total recommendations available
$recs->metadata    // array - Request metadata, pod info

// Methods
$recs->isEmpty()           // bool
$recs->hasRecommendations() // bool
$recs->count()             // int - Number of products returned
$recs->toArray()           // array
```

Complete Facade Methods Reference
---------------------------------

[](#complete-facade-methods-reference)

```
use ConstructorIO\Laravel\Facades\Constructor;

// Search & Browse
Constructor::search(string $query, array $filters = [], array $options = []): SearchResults;
Constructor::browse(string $filterName, string $filterValue, array $filters = [], array $options = []): SearchResults;
Constructor::autocomplete(string $query, array $options = []): AutocompleteResults;
Constructor::getZeroStateData(array $options = []): AutocompleteResults;

// Recommendations
Constructor::getRecommendations(string $podId, array $options = []): RecommendationResults;
Constructor::getItemRecommendations(string $podId, string $itemId, array $options = []): RecommendationResults;

// Categories & Groups
Constructor::getBrowseGroups(array $options = []): array;

// Collections
Constructor::getCollections(array $options = []): array;
Constructor::getCollection(string $collectionId): ?array;
Constructor::browseCollection(string $collectionId, array $filters = [], array $options = []): SearchResults;
Constructor::getFirstProductImageFromCollection(string $collectionId): ?string;

// Facets
Constructor::getFacets(string $query, array $filters = []): array;
Constructor::getAvailableFacets(): array;
Constructor::getFacetValuesWithImages(string $facetName, int $maxItems = 10): array;

// Recipes
Constructor::searchRecipes(string $query, array $filters = [], array $options = []): SearchResults;
Constructor::browseRecipes(string $filterName, string $filterValue, array $filters = [], array $options = []): SearchResults;
Constructor::getRecipe(string $recipeId): ?array;

// Feature Detection
Constructor::supportsZeroState(): bool;
Constructor::supportsRecommendations(): bool;
Constructor::supportsBrowseGroups(): bool;
Constructor::supportsCollections(): bool;
Constructor::supportsRecipes(): bool;
Constructor::getProviderName(): string;
```

Search Options Reference
------------------------

[](#search-options-reference)

Options available for `search()` and `browse()`:

```
$options = [
    // Pagination
    'page' => 1,              // Page number (1-indexed)
    'per_page' => 24,         // Results per page (max 100)

    // Sorting
    'sort_by' => 'price',     // Field to sort by
    'sort_order' => 'ascending', // 'ascending' or 'descending'

    // Section
    'section' => 'Products',  // Constructor section name

    // Range Filters
    'range_filters' => [
        'price' => ['min' => 50, 'max' => 200],
    ],

    // User Context (for personalization)
    'user_id' => 'user-123',
    'session_id' => 'session-abc',
];
```

Laravel Scout Integration
-------------------------

[](#laravel-scout-integration)

### Register the Engine

[](#register-the-engine)

The package automatically registers the `constructor` Scout driver. Configure in `config/scout.php`:

```
return [
    'driver' => env('SCOUT_DRIVER', 'constructor'),

    'constructor' => [
        'api_key' => env('CONSTRUCTOR_API_KEY'),
        'api_token' => env('CONSTRUCTOR_API_TOKEN'),
    ],
];
```

### Make Models Searchable

[](#make-models-searchable)

```
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Product extends Model
{
    use Searchable;

    /**
     * Get the Constructor section for this model.
     */
    public function getConstructorSection(): string
    {
        return 'Products';
    }

    /**
     * Get the indexable data array for the model.
     */
    public function toSearchableArray(): array
    {
        return [
            'id' => $this->sku,
            'name' => $this->name,
            'url' => route('products.show', $this),
            'image_url' => $this->image_url,
            'price' => $this->price,
            'brand' => $this->brand,
            'categories' => $this->categories->pluck('name')->toArray(),
        ];
    }
}
```

### Search with Scout

[](#search-with-scout)

```
// Basic search
$products = Product::search('blue shirt')->get();

// With filters
$products = Product::search('shirt')
    ->where('brand', 'Nike')
    ->paginate(24);
```

Configuration Reference
-----------------------

[](#configuration-reference)

### `config/constructor.php`

[](#configconstructorphp)

```
return [
    // API Credentials
    'api_key' => env('CONSTRUCTOR_API_KEY'),
    'api_token' => env('CONSTRUCTOR_API_TOKEN'),

    // API Endpoints
    'search_base_url' => env('CONSTRUCTOR_SEARCH_BASE_URL', 'https://ac.cnstrc.com'),
    'agent_base_url' => env('CONSTRUCTOR_AGENT_BASE_URL', 'https://agent.cnstrc.com'),

    // AI Agent Settings
    'agent_domain' => env('CONSTRUCTOR_AGENT_DOMAIN'),
    'agent_guard' => env('CONSTRUCTOR_AGENT_GUARD', true),
    'agent_num_result_events' => env('CONSTRUCTOR_AGENT_NUM_RESULT_EVENTS', 5),
    'agent_num_results_per_event' => env('CONSTRUCTOR_AGENT_NUM_RESULTS_PER_EVENT', 4),

    // Backend Integration (server-side calls on behalf of browser users)
    'backend_token' => env('CONSTRUCTOR_BACKEND_TOKEN'),       // Falls back to api_token
    'client_identifier' => env('CONSTRUCTOR_CLIENT_IDENTIFIER'), // Auto-generates if null

    // HTTP Client
    'timeout' => env('CONSTRUCTOR_TIMEOUT', 30),
    'retry_times' => env('CONSTRUCTOR_RETRY_TIMES', 2),
    'retry_sleep' => env('CONSTRUCTOR_RETRY_SLEEP', 100),
];
```

Available Services
------------------

[](#available-services)

ServiceDescription`ConstructorSandboxSearch`Search, browse, autocomplete, recommendations, collections`ConstructorAgentService`AI Shopping Agent and Product Insights Agent`ConstructorService`Catalog uploads, task monitoring, admin operations`ConstructorEngine`Laravel Scout engine implementationError Handling
--------------

[](#error-handling)

The package handles errors gracefully:

- **Search errors** return empty `SearchResults` (logged at error level)
- **Recommendation errors** return empty `RecommendationResults` (logged at error level)
- **Agent errors** throw exceptions (for UI error handling)
- **Catalog errors** throw exceptions (for background job handling)

```
// Search - gracefully returns empty on error
$results = Constructor::search('query');
if ($results->isEmpty()) {
    // Handle no results (could be error or just no matches)
}

// Agent - throws on error
try {
    $response = $agent->askShoppingAgent($query);
} catch (\Exception $e) {
    // Handle error: rate limit, auth failure, network error
    Log::error('Shopping Agent error: ' . $e->getMessage());
}
```

Troubleshooting
---------------

[](#troubleshooting)

### "Constructor.io configuration not properly set"

[](#constructorio-configuration-not-properly-set)

Ensure all required environment variables are set:

```
CONSTRUCTOR_API_KEY=your-api-key
CONSTRUCTOR_API_TOKEN=your-api-token
```

### Empty results when products should exist

[](#empty-results-when-products-should-exist)

1. **Check API key**: Verify the API key matches your Constructor index
2. **Check section name**: Default is 'Products', ensure your index uses this
3. **Check filters**: Some filters may be too restrictive
4. **View logs**: Check `storage/logs/laravel.log` for API errors

### Facets not returning

[](#facets-not-returning)

- Facets must be configured in the Constructor.io dashboard
- Not all indexes have facets enabled
- Try a broader search query to see available facets

### Recommendations returning empty

[](#recommendations-returning-empty)

1. Verify the pod ID exists in your Constructor account
2. Some pods require `item_id` - use `getItemRecommendations()` instead
3. Check that the pod has been trained with data

### Agent authentication failures

[](#agent-authentication-failures)

```
Constructor Agent API authentication failed. Check your API key and domain configuration.

```

- Ensure `CONSTRUCTOR_AGENT_DOMAIN` is set correctly
- The agent domain is separate from the search API key

### Rate limit errors

[](#rate-limit-errors)

```
Rate limit exceeded. Please try again later.

```

- Implement caching for repeated requests
- Contact Constructor.io to increase limits for production

Testing Your Integration
------------------------

[](#testing-your-integration)

### Artisan Test Command

[](#artisan-test-command)

```
# Test search functionality
php artisan tinker
>>> Constructor::search('test')->toArray()

# Test recommendations
>>> Constructor::getRecommendations('your-pod-id')->toArray()

# Test agent (if configured)
>>> app(ConstructorAgentService::class)->getProductQuestions('product-id')
```

### Unit Testing

[](#unit-testing)

Mock the facade for testing:

```
use ConstructorIO\Laravel\Facades\Constructor;
use ConstructorIO\Laravel\DataTransferObjects\SearchResults;

public function test_search_page_displays_products()
{
    Constructor::shouldReceive('search')
        ->once()
        ->with('shoes', [], \Mockery::any())
        ->andReturn(new SearchResults(
            products: [['id' => '1', 'name' => 'Nike Shoes']],
            total: 1,
            page: 1,
            perPage: 24
        ));

    $response = $this->get('/search?q=shoes');

    $response->assertSee('Nike Shoes');
}
```

Best Practices
--------------

[](#best-practices)

### Caching Recommendations

[](#caching-recommendations)

```
use Illuminate\Support\Facades\Cache;

$recommendations = Cache::remember(
    "recs:home-page:{$userId}",
    now()->addMinutes(15),
    fn() => Constructor::getRecommendations('home-page-1')
);
```

### User Personalization

[](#user-personalization)

Pass user identifiers for personalized results:

```
$results = Constructor::search('shoes', [], [
    'user_id' => auth()->id(),
    'session_id' => session()->getId(),
]);
```

### Handling Zero-State Gracefully

[](#handling-zero-state-gracefully)

```
public function autocomplete(Request $request)
{
    $query = trim($request->input('q', ''));

    if (empty($query)) {
        return Constructor::getZeroStateData([
            'show_top_categories' => true,
            'recommendation_pod_id' => 'autocomplete-bestsellers',
        ])->toArray();
    }

    return Constructor::autocomplete($query)->toArray();
}
```

Documentation
-------------

[](#documentation)

- [Constructor.io Documentation](https://docs.constructor.io/)
- [Search API Reference](https://docs.constructor.com/reference/search-search-results)
- [Browse API Reference](https://docs.constructor.com/reference/browse-browse-results)
- [Autocomplete API Reference](https://docs.constructor.com/reference/autocomplete-autocomplete-results)
- [Recommendations API Reference](https://docs.constructor.com/reference/recommendations-recommendation-results)
- [AI Shopping Agent API Reference](https://docs.constructor.com/reference/v1-asa-retrieve-intent)

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

###  Health Score

39

—

LowBetter than 85% of packages

Maintenance76

Regular maintenance activity

Popularity18

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~12 days

Total

2

Last Release

131d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f909e824af61330fb1e325a973bdf2a01c8ce5ee71b8aebb1bb54d4b67e2b181?d=identicon)[timjohnbancroft](/maintainers/timjohnbancroft)

---

Top Contributors

[![timjohnbancroft](https://avatars.githubusercontent.com/u/56043603?v=4)](https://github.com/timjohnbancroft "timjohnbancroft (11 commits)")

---

Tags

searchlaravelautocompleteconstructoraiecommercerecommendationsproduct-discovery

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/timjohnbancroft-constructor-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/timjohnbancroft-constructor-laravel/health.svg)](https://phpackages.com/packages/timjohnbancroft-constructor-laravel)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[spatie/laravel-export

Create a static site bundle from a Laravel app

672139.5k6](/packages/spatie-laravel-export)[simplestats-io/laravel-client

Analytics for Laravel. Track visitors, registrations, and payments. Discover which channels actually drive revenue, not just traffic. Server-side, GDPR compliant, ad-blocker proof.

5019.3k](/packages/simplestats-io-laravel-client)[jasara/php-amzn-selling-partner-api

A fluent interface for Amazon's Selling Partner API in PHP

1348.1k1](/packages/jasara-php-amzn-selling-partner-api)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1232.2k16](/packages/fleetbase-core-api)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
