PHPackages                             gowelle/sku-generator - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. gowelle/sku-generator

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

gowelle/sku-generator
=====================

Generate meaningful SKUs for Laravel e-commerce products and variants

v2.0.0(1mo ago)3124MITPHPPHP ^8.3CI passing

Since May 10Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/gowelle/sku-generator)[ Packagist](https://packagist.org/packages/gowelle/sku-generator)[ RSS](/packages/gowelle-sku-generator/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (14)Versions (15)Used By (0)

Laravel SKU Generator
=====================

[](#laravel-sku-generator)

[![Latest Version on Packagist](https://camo.githubusercontent.com/28c5fca769c2dc18c1c19e3a14a46c9d5ec89346fa1698a23732f49c39726bcf/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f676f77656c6c652f736b752d67656e657261746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gowelle/sku-generator)[![Total Downloads](https://camo.githubusercontent.com/85c45bfc005e89c4bf0550314499806cc2876be6b9892e7fcf437f4a8f30e1da/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f676f77656c6c652f736b752d67656e657261746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gowelle/sku-generator)[![Tests](https://github.com/gowelle/sku-generator/actions/workflows/tests.yml/badge.svg)](https://github.com/gowelle/sku-generator/actions/workflows/tests.yml)

Generate meaningful SKUs for Laravel e-commerce products and variants.

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

[](#requirements)

- PHP ^8.3
- Laravel ^11.0|^12.0|^13.0

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

[](#installation)

You can install the package via composer:

```
composer require gowelle/sku-generator
```

Publish the configuration:

```
php artisan vendor:publish --tag="sku-generator-config"
```

Usage
-----

[](#usage)

Add the `HasSku` trait to your models:

```
use Gowelle\SkuGenerator\Concerns\HasSku;

class Product extends Model
{
    use HasSku;
}
```

SKUs will be automatically generated when models are created:

```
$product = Product::create(['name' => 'T-Shirt']);
echo $product->sku; // Output: TM-TSH-ABC12345

$variant = $product->variants()->create([/* ... */]);
echo $variant->sku; // Output: TM-TSH-ABC12345-RED-LRG
```

Configuration
-------------

[](#configuration)

```
return [
    'prefix' => 'TM',
    'ulid_length' => 8,
    'separator' => '-',

    'models' => [
        \App\Models\Product::class => 'product',
        \App\Models\ProductVariant::class => 'variant',
    ],

    'category' => [
        'accessor' => 'category',
        'field' => 'name',
        'length' => 3,
        'has_many' => false,
    ],
];
```

SKU Format
----------

[](#sku-format)

### Products

[](#products)

- Format: `{prefix}-{category}-{unique}`
- Example: `TM-TSH-ABC12345`

### Variants

[](#variants)

- Format: `{prefix}-{category}-{unique}-{properties}`
- Example: `TM-TSH-ABC12345-RED-LRG`

Regenerating SKUs
-----------------

[](#regenerating-skus)

Use the artisan command to regenerate SKUs:

```
# Interactive mode
php artisan sku:regenerate

# Direct model specification
php artisan sku:regenerate "App\Models\Product"

# Skip confirmation
php artisan sku:regenerate --force
```

Features:

- Interactive model selection
- Progress reporting
- Chunked processing
- Failure logging
- Unique constraint preservation

SKU History &amp; Audit Trail
-----------------------------

[](#sku-history--audit-trail)

The package includes a comprehensive audit trail system to track all SKU lifecycle events.

### Setup

[](#setup)

Publish and run the migration:

```
php artisan vendor:publish --tag="sku-generator-migrations"
php artisan migrate
```

#### Customizing for Non-Integer Primary Keys

[](#customizing-for-non-integer-primary-keys)

If your models or users use primary key types other than integer (e.g., UUID, string), you'll need to modify the published migration before running it.

After publishing the migration, edit the `model_id` and `user_id` columns in the migration file to match your primary key types:

**For UUID primary keys:**

```
// Change from:
$table->unsignedBigInteger('model_id')->index();
$table->unsignedBigInteger('user_id')->nullable();

// To:
$table->uuid('model_id')->index();
$table->uuid('user_id')->nullable();
```

**For string primary keys:**

```
// Change from:
$table->unsignedBigInteger('model_id')->index();
$table->unsignedBigInteger('user_id')->nullable();

// To:
$table->string('model_id')->index();
$table->string('user_id')->nullable();
```

**For different types on model\_id and user\_id:**

```
// Example: UUID for models, integer for users
$table->uuid('model_id')->index();
$table->unsignedBigInteger('user_id')->nullable();
```

The migration file will be published to `database/migrations/YYYY_MM_DD_HHMMSS_create_sku_histories_table.php`.

### Configuration

[](#configuration-1)

Configure history tracking in `config/sku-generator.php`:

```
'history' => [
    'enabled' => env('SKU_HISTORY_ENABLED', true),
    'track_user' => true,
    'track_ip' => false,
    'track_user_agent' => false,
    'retention_days' => null, // null = keep forever
    'table_name' => 'sku_histories',
],
```

### Tracked Events

[](#tracked-events)

The following events are automatically tracked:

- **Created**: When a new SKU is generated
- **Regenerated**: When `forceRegenerateSku()` is called
- **Modified**: When a SKU is manually modified
- **Deleted**: When a model with a SKU is deleted

### Viewing History

[](#viewing-history)

#### Via Model Relationship

[](#via-model-relationship)

```
// Get all history for a model
$history = $product->skuHistory;

// Get latest history entry
$latest = $product->getLatestSkuHistory();

// Get all history entries
$allHistory = $product->getSkuHistory();
```

#### Via Artisan Command

[](#via-artisan-command)

```
# View history for a specific model
php artisan sku:history "App\Models\Product" --id=123

# View history for a specific SKU
php artisan sku:history --sku="TM-TSH-ABC12345"

# View recent changes
php artisan sku:history --recent --days=7

# Filter by event type
php artisan sku:history --event=regenerated --limit=100
```

### Query Interface

[](#query-interface)

Use the `SkuHistory` model to query history:

```
use Gowelle\SkuGenerator\Models\SkuHistory;

// Get history for a specific model
SkuHistory::forModel($product)->get();

// Find history for a specific SKU
SkuHistory::forSku('TM-TSH-ABC12345')->get();

// Filter by event type
SkuHistory::byEventType('regenerated')->get();

// Get recent changes
SkuHistory::recentChanges(7)->get();

// Filter by date range
SkuHistory::between('2024-01-01', '2024-12-31')->get();

// Filter by user
SkuHistory::byUser($userId)->get();
```

### Events

[](#events)

The package dispatches Laravel events for all SKU changes:

```
use Gowelle\SkuGenerator\Events\{SkuCreated, SkuRegenerated, SkuModified, SkuDeleted};

// Listen to events in your EventServiceProvider
Event::listen(SkuRegenerated::class, function ($event) {
    // $event->model - The model that was changed
    // $event->oldSku - The previous SKU
    // $event->newSku - The new SKU
    // $event->reason - Optional reason for change
});
```

### Cleanup Old History

[](#cleanup-old-history)

Clean up old history records:

```
# Cleanup based on configured retention policy
php artisan sku:history:cleanup

# Delete records older than 365 days
php artisan sku:history:cleanup --days=365

# Delete records before a specific date
php artisan sku:history:cleanup --before="2024-01-01"

# Preview what would be deleted
php artisan sku:history:cleanup --days=365 --dry-run

# Skip confirmation
php artisan sku:history:cleanup --days=365 --force
```

### Disabling History

[](#disabling-history)

To disable history tracking:

```
// In config/sku-generator.php
'history' => [
    'enabled' => false,
    // ...
],

// Or via environment variable
SKU_HISTORY_ENABLED=false
```

Testing
-------

[](#testing)

```
composer test
```

Format code:

```
composer format
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [John Gowelle](https://github.com/gowelle)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

48

—

FairBetter than 94% of packages

Maintenance96

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 86.5% 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 ~26 days

Recently: every ~78 days

Total

13

Last Release

49d ago

Major Versions

v1.2.1 → v2.0.02026-03-21

PHP version history (2 changes)v1.0.0PHP ^8.2

v2.0.0PHP ^8.3

### Community

Maintainers

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

---

Top Contributors

[![gowelle](https://avatars.githubusercontent.com/u/87917924?v=4)](https://github.com/gowelle "gowelle (64 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (8 commits)")[![cursoragent](https://avatars.githubusercontent.com/u/199161495?v=4)](https://github.com/cursoragent "cursoragent (2 commits)")

---

Tags

ecommercelaravelproductskuvariantlaravele-commerceproductskuvariant

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/gowelle-sku-generator/health.svg)

```
[![Health](https://phpackages.com/badges/gowelle-sku-generator/health.svg)](https://phpackages.com/packages/gowelle-sku-generator)
```

###  Alternatives

[barryvdh/laravel-ide-helper

Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.

14.9k123.0M683](/packages/barryvdh-laravel-ide-helper)[livewire/flux

The official UI component library for Livewire.

9385.0M85](/packages/livewire-flux)[dcblogdev/laravel-module-generator

Generate Laravel Modules from a template.

7710.1k1](/packages/dcblogdev-laravel-module-generator)[interaction-design-foundation/laravel-geoip

Support for multiple Geographical Location services.

17221.0k3](/packages/interaction-design-foundation-laravel-geoip)[nedwors/navigator

A Laravel package to ease defining navigation menus

433.1k](/packages/nedwors-navigator)[whitecube/laravel-prices

Manage acquisition, selling &amp; renting prices for products and services in your Laravel Application

121.6k](/packages/whitecube-laravel-prices)

PHPackages © 2026

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