Skip to content

Instantly share code, notes, and snippets.

@matthewsuan
Created June 19, 2016 18:52
Show Gist options
  • Save matthewsuan/b350266e7208b898475dc515f49bf603 to your computer and use it in GitHub Desktop.
Save matthewsuan/b350266e7208b898475dc515f49bf603 to your computer and use it in GitHub Desktop.
Improved Unique Slug Generator from @ericbarnes, @AucT
<?php
namespace App\Services;
class Slug
{
private $entity;
private $slugAttr;
public function __construct($entity = \App\Post::class, $slugAttr = 'slug')
{
$this->entity = $entity;
$this->slugAttr = $slugAttr;
}
/**
* @param $title
* @param int $id
* @return string
* @throws \Exception
*/
public function createSlug($title, $id = 0)
{
// Normalize the title
$slug = str_slug($title);
// Get any that could possibly be related.
// This cuts the queries down by doing it once.
$allSlugs = $this->getRelatedSlugs($slug, $id);
// If we haven't used it before then we are all good.
if (!$allSlugs->contains($this->slugAttr, $slug)) {
return $slug;
}
// Just append numbers like a savage until we find not used.
for ($i = 1; $i <= 10; $i++) {
$newSlug = $slug . '-' . $i;
if (!$allSlugs->contains($this->slugAttr, $newSlug)) {
return $newSlug;
}
}
throw new \Exception('Can not create a unique slug');
}
protected function getRelatedSlugs($slug, $id = 0)
{
return call_user_func(array($this->entity, 'select'), $this->slugAttr)->where($this->slugAttr, 'like', $slug . '%')
->where('id', '<>', $id)
->get();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment