Skip to content

Instantly share code, notes, and snippets.

@secrethash
Last active January 13, 2023 02:18
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save secrethash/426f709f29af93cd739cba4f393ac81f to your computer and use it in GitHub Desktop.
Save secrethash/426f709f29af93cd739cba4f393ac81f to your computer and use it in GitHub Desktop.
Laravel Helper Function to create a Unique slug based on Provided Model Instance. Save 'slugify_model.php' in your 'app/Helpers/' directory and update your composer.json to reference and autoload the helper function.
{
...
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
},
"files": [
...
"app/Helpers/slugify_model.php",
...
]
},
...
}
<?php
/* Usage Example: Post */
$validated = $request->validated();
// Creating a New Model
$validated['slug'] = slugify_model(Post::class, $validated['title']);
// return: this-is-an-example-of-slugify
// if slug already exists: this-is-an-example-of-slugify-9rkt6
Post::create($validated);
// Updating a Model
$validated['slug'] = slugify_model(
model: Post::class,
columnOrTitle: $validated['title'],
ignore: $post->slug
);
// return: this-is-an-updated-example-of-slugify
// if slug already exists: this-is-an-updated-example-of-slugify-jToVK
$post->update($validated);
// On-the-fly Slugify :P
// 1. Here, 'title' Column in 'posts' table will be slugified
// and 'slug' column will be used to verify if it exists.
$slug = slugify_model($post, 'title');
// return: on-the-fly-slugify
// 2. Here, custom slug column is used to verify if it exists.
$slug = slugify_model($post, 'title', slugColumn: 'shortname');
// return: on-the-fly-slugify
// 3. Ignoring a Slug when ClassName::class is provided as first param
$slug = slugify_model(Post::class, $validated['title'], $post->slug);
<?php
use Illuminate\Database\Eloquent\Model;
if (! function_exists('slugify_model')) {
/**
* Creates a URL Friendly Unique Slug (also ignore if necessary)
* It will also verify if it already exists, & if it does, append Str::random()
* Example: this-is-a-friendly-slug
* OR Example: this-is-a-friendly-slug-9rkt6
*
* @param \Illuminate\Database\Eloquent\Model|string $model
* @param string|null $columnOrTitle Database Column for "title" or Title to Slugify
* @param string|null $ignore Ignore a slug for Regeneration if slug is similar
* @param string $slugColumn column used to check for duplicates
* @param bool $regenrate Specifies if regeneration is done
* @return string
*/
function slugify_model(
Model|string $model,
string $columnOrTitle,
?string $ignore = null,
string $slugColumn = 'slug',
bool $regenerate = false
): string
{
$data = ($model instanceof Model) ?
$model->$columnOrTitle :
$columnOrTitle;
(!$model instanceof Model && ($columnOrTitle == null OR $columnOrTitle == '')) ?
throw(new Exception('No Title Provided to Slugify')) : null;
$slug = Str::slug($data);
$ignore = ($model instanceof Model && $ignore === null) ?
$model->$slugColumn : $ignore;
$slug = ($regenerate && $slug !== $ignore) ?
$slug . '-' . Str::random(5) :
$slug;
$instance = ($model instanceof Model) ?
get_class($model) :
$model;
$lookup = ($slug !== $ignore) ?
$instance::where($slugColumn, $slug)->first() :
false;
return ($lookup) ?
slugify_model(
$model,
$columnOrTitle,
$ignore,
$slugColumn,
regenerate: true
) : $slug;
}
}
@johhann
Copy link

johhann commented Jun 4, 2022

cool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment