Installation:
composer require 21torr/snail
Add the bundle to config/bundles.php (Symfony only):
return [
// ...
Snail\SnailBundle::class => ['all' => true],
];
First Use Case: Generate a snail from a string:
use Snail\Snail;
$snail = Snail::generate('Hello World!'); // Returns 'hello-world-123'
Verify a snail:
Snail::isValid('hello-world-123'); // Returns true/false
Where to Look First:
src/Snail.php for core logic (e.g., generate(), isValid()).tests/ for edge-case examples.Slug Generation:
// Basic usage
$snail = Snail::generate('User Profile'); // 'user-profile-123'
// Custom separator/length
Snail::generate('Test', separator: '-', length: 8); // 'test-12345'
Validation & Sanitization:
// Validate a snail
if (Snail::isValid($input)) {
// Safe to use
}
// Sanitize user input
$cleanSnail = Snail::sanitize('user@123'); // 'user-123'
Integration with Eloquent:
// Model trait (if provided)
use Snail\SnailTrait;
class Post extends Model {
use SnailTrait;
protected $snailField = 'slug';
protected $titleField = 'title';
// Automatically generates snail on save
}
API/Route Slugs:
// Generate route-friendly slugs
$route = 'posts/' . Snail::generate($post->title);
// Validate incoming slugs
if (!Snail::isValid(request('slug'))) {
abort(400, 'Invalid slug format');
}
Custom Rules:
Extend Snail to enforce business logic (e.g., disallow certain words):
class CustomSnail extends Snail {
public static function generate(string $string): string {
$snail = parent::generate($string);
return str_replace(['admin', 'test'], '', $snail);
}
}
Localization: Override separators for multilingual apps:
Snail::setSeparator('_'); // For non-Latin scripts
Testing: Mock snail generation in unit tests:
Snail::shouldReceive('generate')->andReturn('mock-snail');
Collisions:
-123) to avoid duplicates. If collisions occur in production, increase the length parameter or use a deterministic hash (e.g., uniqid()).Reserved Words:
Snail::setReservedWords(['custom-word']);
Performance:
$cacheKey = "snail:{$string}";
$snail = cache()->remember($cacheKey, 3600, fn() => Snail::generate($string));
Symfony-Specific:
SnailBundle is properly registered in config/bundles.php. Forgetting this will throw ClassNotFoundException.Invalid Snails:
Use Snail::debug($snail) to inspect why a snail fails validation (Symfony-specific).
Snail::debug('invalid-snail'); // Outputs: "Failed rules: [length, separator]"
Character Encoding: Ensure UTF-8 strings are passed to avoid encoding issues:
$snail = Snail::generate(mb_convert_encoding($string, 'UTF-8'));
Custom Generators:
Implement Snail\GeneratorInterface for bespoke logic:
class HashSnail implements GeneratorInterface {
public function generate(string $string): string {
return hash('crc32b', $string);
}
}
Event Hooks:
Listen for snail.generated events (if supported in future versions) to log or transform snails:
// Example (hypothetical)
event(new SnailGenerated($snail));
Database Indexing: Optimize queries by indexing snail fields:
Schema::table('posts', function (Blueprint $table) {
$table->string('slug')->unique();
$table->index('slug'); // Add index for faster lookups
});
Default Values:
Override defaults in config/snail.php (if provided):
'default' => [
'separator' => '-',
'length' => 6,
'reserved_words' => ['admin', 'test'],
],
Environment-Specific Rules: Use environment variables for dynamic settings:
$separator = env('SNAIL_SEPARATOR', '-');
Snail::setSeparator($separator);
How can I help you explore Laravel packages today?