PHPackages                             elstc/cakephp-slug-guard - 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. [Validation &amp; Sanitization](/categories/validation)
4. /
5. elstc/cakephp-slug-guard

ActiveCakephp-plugin[Validation &amp; Sanitization](/categories/validation)

elstc/cakephp-slug-guard
========================

CakePHP plugin for URL-safe slug validation and reserved-word collision prevention

5.1.0(2mo ago)0174↑270%MITPHPPHP &gt;=8.2CI passing

Since Mar 25Pushed 2mo agoCompare

[ Source](https://github.com/elstc/cakephp-slug-guard)[ Packagist](https://packagist.org/packages/elstc/cakephp-slug-guard)[ Docs](https://github.com/elstc/cakephp-slug-guard)[ RSS](/packages/elstc-cakephp-slug-guard/feed)WikiDiscussions cake5 Synced 3w ago

READMEChangelog (2)Dependencies (8)Versions (5)Used By (0)

SlugGuard plugin for CakePHP
============================

[](#slugguard-plugin-for-cakephp)

[![CI](https://github.com/elstc/cakephp-slug-guard/actions/workflows/ci.yml/badge.svg)](https://github.com/elstc/cakephp-slug-guard/actions/workflows/ci.yml)[![Latest Stable Version](https://camo.githubusercontent.com/a4af39d4f7ef5dfbd7da1b5f74ba159615e41084022320ef331e55f28a8ae5cc/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f656c7374632f63616b657068702d736c75672d67756172643f736f72743d73656d766572267374796c653d666c61742d737175617265)](https://packagist.org/packages/elstc/cakephp-slug-guard)[![Total Downloads](https://camo.githubusercontent.com/65f3f43b3887eff842d73ce26ea4da05bd6ee7854b8d19b65dcd2b12ef9b3614/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f656c7374632f63616b657068702d736c75672d67756172643f7374796c653d666c61742d737175617265)](https://packagist.org/packages/elstc/cakephp-slug-guard/stats)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.txt)

A CakePHP plugin that ensures user-chosen slugs are safe and conflict-free for use in URLs.

[日本語ドキュメント / Japanese](README.ja.md)

Version Map
-----------

[](#version-map)

CakePHPPHPPluginBranch5.x&gt;= 8.25.xcake5- **SlugValidator** validates that a string is well-formed for use as a subdomain label or URL path segment (lowercase alphanumeric + hyphens, length constraints).
- **IsNotReservedSlug** compares slugs against a reserved-word list so they never collide with system routes or well-known paths.
- **IsNotRouteConflict** compares slugs against first-level URL segments extracted from the CakePHP route table to prevent collisions with application routes.

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

[](#installation)

### Prerequisites

[](#prerequisites)

- A CakePHP 5.x application
- PHP &gt;= 8.2
- A database connection configured in your app (`config/app_local.php`)

### Steps

[](#steps)

1. Install the plugin via Composer:

    ```
    composer require elstc/cakephp-slug-guard
    ```
2. Load the plugin. This adds `$this->addPlugin('Elastic/SlugGuard')` to your `src/Application.php`:

    ```
    bin/cake plugin load Elastic/SlugGuard
    ```
3. Run the migration to create the `reserved_slugs` table:

    ```
    bin/cake migrations migrate --plugin Elastic/SlugGuard
    ```
4. Import the default reserved slugs (~710 common reserved words):

    ```
    bin/cake slug_guard sync
    ```

### Verify Installation

[](#verify-installation)

Run the following command to confirm the reserved slugs were imported:

```
bin/cake slug_guard list --count
```

Expected: a count of approximately 710 reserved slugs.

Usage
-----

[](#usage)

### Validation Rule

[](#validation-rule)

Add the `IsNotReservedSlug` rule to your table's `buildRules()` method:

```
use Elastic\SlugGuard\Model\Rule\IsNotReservedSlug;

public function buildRules(RulesChecker $rules): RulesChecker
{
    $rules->add(new IsNotReservedSlug('slug'), 'reservedSlug', [
        'errorField' => 'slug',
        'message' => 'This slug is reserved.',
    ]);

    return $rules;
}
```

#### Custom field name

[](#custom-field-name)

```
$rules->add(new IsNotReservedSlug('username'), 'reservedSlug', [
    'errorField' => 'username',
    'message' => 'This username is reserved.',
]);
```

#### Custom reserved slugs table

[](#custom-reserved-slugs-table)

You can use any table as the reserved slugs backend by implementing `SlugExistenceInterface`:

```
// src/Model/Table/CustomReservedSlugsTable.php
namespace App\Model\Table;

use Cake\ORM\Table;
use Elastic\SlugGuard\Model\Table\SlugExistenceInterface;

class CustomReservedSlugsTable extends Table implements SlugExistenceInterface
{
    public function slugExists(string $slug): bool
    {
        return $this->exists(['slug' => $slug]);
    }
}
```

Then pass the table name to `IsNotReservedSlug`:

```
$rules->add(new IsNotReservedSlug('slug', 'CustomReservedSlugs'), 'reservedSlug', [
    'errorField' => 'slug',
    'message' => 'This slug is reserved.',
]);
```

### Route Conflict Rule

[](#route-conflict-rule)

Add the `IsNotRouteConflict` rule to prevent slugs from colliding with application routes (e.g. `/admin`, `/api`, `/posts`):

```
use Elastic\SlugGuard\Model\Rule\IsNotRouteConflict;

public function buildRules(RulesChecker $rules): RulesChecker
{
    $rules->add(new IsNotRouteConflict('slug'), 'routeConflict', [
        'errorField' => 'slug',
        'message' => 'This slug conflicts with an application route.',
    ]);

    return $rules;
}
```

This rule extracts first-level URL path segments from all registered CakePHP routes at runtime and rejects any slug that matches.

### Slug Format Validator

[](#slug-format-validator)

The `SlugValidator` class provides a static method for validating slug format (lowercase alphanumeric and hyphens):

```
use Elastic\SlugGuard\Validation\SlugValidator;

// Use as a Validator provider
$validator->setProvider('slugValidator', SlugValidator::class);
$validator->add('slug', 'validSlug', [
    'rule' => ['isValid'],
    'provider' => 'slugValidator',
    'message' => 'Only lowercase letters, numbers, and hyphens are allowed.',
]);
```

#### Configuration Options

[](#configuration-options)

##### `minLength`

[](#minlength)

Minimum slug length. Default: `4`

##### `maxLength`

[](#maxlength)

Maximum slug length. Default: `24`

```
$validator->add('slug', 'validSlug', [
    'rule' => ['isValid', 3, 32],
    'provider' => 'slugValidator',
]);
```

### CLI Commands

[](#cli-commands)

#### List reserved slugs

[](#list-reserved-slugs)

```
bin/cake slug_guard list
bin/cake slug_guard list --count
bin/cake slug_guard list --search admin
```

#### List route paths

[](#list-route-paths)

```
bin/cake slug_guard routes
bin/cake slug_guard routes --count
```

Output is pipe-friendly (one path per line, no decoration). See [Route-based workflow](#route-based-workflow) below.

#### Add reserved slugs

[](#add-reserved-slugs)

```
bin/cake slug_guard add my-reserved-slug
bin/cake slug_guard add slug-one slug-two slug-three
```

Supports stdin for pipe usage:

```
bin/cake slug_guard routes | bin/cake slug_guard add
```

#### Remove reserved slugs

[](#remove-reserved-slugs)

```
bin/cake slug_guard remove my-reserved-slug
bin/cake slug_guard remove slug-one slug-two slug-three
```

Also supports stdin:

```
cat slugs-to-remove.txt | bin/cake slug_guard remove
```

#### Import slugs from a file

[](#import-slugs-from-a-file)

```
bin/cake slug_guard import /path/to/slugs.txt
```

File format: one slug per line, `#` for comments, empty lines are ignored.

#### Sync with a file

[](#sync-with-a-file)

```
# Sync (auto-detects app config file or falls back to plugin built-in)
bin/cake slug_guard sync

# Sync with a specific file
bin/cake slug_guard sync --file /path/to/slugs.txt

# Preview changes without applying
bin/cake slug_guard sync --dry-run
```

When `--file` is not specified, the sync command resolves the seed file in the following order:

1. Application config file: `config/reserved-slugs.txt` (in app root)
2. Plugin built-in seed file

You can override the application config file path via `Configure`:

```
// In config/app.php or config/app_local.php
'SlugGuard' => [
    'syncFile' => CONFIG . 'my-custom-slugs.txt',
],
```

### Reserved Slugs List File

[](#reserved-slugs-list-file)

The plugin ships with a default reserved slugs list at `config/reserved-slugs.txt`. This file contains ~710 common reserved words (e.g. `admin`, `api`, `login`, `settings`, `www`) that could conflict with system routes or well-known paths.

#### File format

[](#file-format)

- One slug per line
- Lines starting with `#` are comments
- Empty lines are ignored

```
# System routes
admin
api
login

# Social media
facebook
twitter
youtube

```

#### Using the built-in list

[](#using-the-built-in-list)

The built-in list is used as a fallback by the `sync` command when no app-level config file exists. You can also import it directly:

```
bin/cake slug_guard import vendor/elstc/cakephp-slug-guard/config/reserved-slugs.txt
```

#### Using a custom list

[](#using-a-custom-list)

Create your own file following the same format and use it with `import` or `sync`:

```
# Import additional slugs from a custom file
bin/cake slug_guard import /path/to/my-slugs.txt

# Sync the database to match your custom file exactly
bin/cake slug_guard sync --file /path/to/my-slugs.txt
```

> **Note:** `import` adds slugs from the file to the database (existing slugs are preserved). `sync` makes the database match the file exactly — slugs not in the file will be removed.

### Route-based Workflow

[](#route-based-workflow)

The `slug_guard routes` command extracts first-level URL path segments from your application's route table. Use it to automatically reserve paths that would conflict with user-generated slugs.

#### Pipe directly to the database

[](#pipe-directly-to-the-database)

```
bin/cake slug_guard routes | bin/cake slug_guard add
```

#### Append to your reserved slugs file, then sync

[](#append-to-your-reserved-slugs-file-then-sync)

```
bin/cake slug_guard routes >> config/reserved-slugs.txt
bin/cake slug_guard sync
```

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance83

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

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 ~1 days

Total

4

Last Release

87d ago

### Community

Maintainers

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

---

Top Contributors

[![nojimage](https://avatars.githubusercontent.com/u/100564?v=4)](https://github.com/nojimage "nojimage (30 commits)")

---

Tags

slugvalidationcakephp

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/elstc-cakephp-slug-guard/health.svg)

```
[![Health](https://phpackages.com/badges/elstc-cakephp-slug-guard/health.svg)](https://phpackages.com/packages/elstc-cakephp-slug-guard)
```

###  Alternatives

[cakephp/bake

Bake plugin for CakePHP

11211.7M190](/packages/cakephp-bake)[dereuromark/cakephp-tools

A CakePHP plugin containing lots of useful and reusable tools

333972.2k49](/packages/dereuromark-cakephp-tools)[dereuromark/cakephp-queue

The Queue plugin for CakePHP provides deferred task execution.

308914.0k25](/packages/dereuromark-cakephp-queue)[dereuromark/cakephp-ide-helper

CakePHP IdeHelper Plugin to improve auto-completion

1882.3M40](/packages/dereuromark-cakephp-ide-helper)[admad/cakephp-i18n

A CakePHP plugin for I18n related tools.

4454.1k](/packages/admad-cakephp-i18n)[dereuromark/cakephp-tinyauth

A CakePHP plugin to handle user authentication and authorization the easy way.

131237.3k13](/packages/dereuromark-cakephp-tinyauth)

PHPackages © 2026

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