Skip to content
This repository was archived by the owner on Sep 27, 2022. It is now read-only.

Commit fe33e55

Browse files
MPurSandeesh
authored andcommitted
Remove eloquent-sluggable package and create Slug class + HasSlug trait (#4)
* Remove eloquent-sluggable package and create Simple HasSlug trait * some fixes + add uniqueness feature and reserved values * create Sluggable directory and put all logic here
1 parent d858ee9 commit fe33e55

File tree

8 files changed

+282
-324
lines changed

8 files changed

+282
-324
lines changed

app/Article.php

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
namespace App;
44

55
use App\Filters\Filterable;
6+
use App\Sluggable\HasSlug;
67
use App\Traits\FavoritedTrait;
7-
use Cviebrock\EloquentSluggable\Sluggable;
88
use Illuminate\Database\Eloquent\Model;
99

1010
class Article extends Model
1111
{
12-
use Filterable, FavoritedTrait, Sluggable;
12+
use Filterable,
13+
FavoritedTrait,
14+
HasSlug;
1315

1416
/**
1517
* The attributes that are mass assignable.
@@ -87,26 +89,32 @@ public function tags()
8789
}
8890

8991
/**
90-
* Return the sluggable configuration array for this model.
92+
* Get the key name for route model binding.
9193
*
92-
* @return array
94+
* @return string
9395
*/
94-
public function sluggable()
96+
public function getRouteKeyName()
9597
{
96-
return [
97-
'slug' => [
98-
'source' => 'title'
99-
]
100-
];
98+
return 'slug';
10199
}
102100

103101
/**
104-
* Get the key name for route model binding.
102+
* Get the attribute name to slugify.
105103
*
106104
* @return string
107105
*/
108-
public function getRouteKeyName()
106+
public function getSlugSourceColumn()
109107
{
110-
return 'slug';
108+
return 'title';
109+
}
110+
111+
/**
112+
* Get list of values which are not allowed for this resource
113+
*
114+
* @return array
115+
*/
116+
public function getBannedSlugValues()
117+
{
118+
return ['feed'];
111119
}
112120
}

app/Sluggable/HasSlug.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace App\Sluggable;
4+
5+
trait HasSlug
6+
{
7+
/**
8+
* Adding or updating slug when attribute to "slugify" is set.
9+
*
10+
* @param string $key
11+
* @param mixed $value
12+
* @return $this
13+
*/
14+
public function setAttribute($key, $value)
15+
{
16+
if($key == $this->getSlugSourceColumn()) {
17+
$slug = (new Slug($value))
18+
->uniqueFor($this)
19+
->without($this->getBannedSlugValues())
20+
->generate();
21+
22+
$this->attributes[$this->getSlugSourceColumn()] = $value;
23+
$this->attributes[$this->getSlugColumn()] = $slug;
24+
}
25+
26+
return parent::setAttribute($key, $value);
27+
}
28+
29+
/**
30+
* Get the attribute name to slugify.
31+
*
32+
* @return string
33+
*/
34+
abstract public function getSlugSourceColumn();
35+
36+
37+
/**
38+
* Get the name of the slug column
39+
*
40+
* @return string
41+
*/
42+
public function getSlugColumn()
43+
{
44+
return 'slug';
45+
}
46+
47+
/**
48+
* Get list of values wich are not allowed
49+
*
50+
* @return array
51+
*/
52+
public function getBannedSlugValues()
53+
{
54+
return [];
55+
}
56+
57+
}

app/Sluggable/Slug.php

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
namespace App\Sluggable;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Slug
8+
{
9+
/**
10+
* Eloquent model used for example for uniqueness
11+
*
12+
* @var Model
13+
*/
14+
protected $model;
15+
16+
/**
17+
* Banned values for slug generation
18+
*
19+
* @var array
20+
*/
21+
protected $banned = [];
22+
23+
/**
24+
* Initial value to slugify
25+
*
26+
* @var string
27+
*/
28+
private $initialValue;
29+
30+
/**
31+
* Separator use to generate slugs
32+
*
33+
* @var string
34+
*/
35+
const SEPARATOR = '-';
36+
37+
/**
38+
* Slug constructor.
39+
*
40+
* @param string $value
41+
*/
42+
public function __construct($value)
43+
{
44+
$this->initialValue = $value;
45+
}
46+
47+
/**
48+
* Generate a unique slug
49+
*
50+
* @return string
51+
*/
52+
public function generate()
53+
{
54+
$slug = str_slug($this->initialValue, static::SEPARATOR);
55+
56+
$notAllowed = $this->getSimilarSlugs($slug)->merge($this->banned);
57+
58+
if ($notAllowed->isEmpty() || !$notAllowed->contains($slug)) {
59+
return $slug;
60+
}
61+
62+
$suffix = $this->generateSuffix($slug, $notAllowed);
63+
64+
return "{$slug}-{$suffix}";
65+
66+
}
67+
68+
/**
69+
* Generate suffix for unique slug
70+
*
71+
* @param string $slug
72+
* @param array $notAllowed
73+
* @return string
74+
*/
75+
public function generateSuffix($slug, $notAllowed)
76+
{
77+
/** @var Collection $notAllowed */
78+
$notAllowed->transform(function ($item, $key) use ($slug) {
79+
80+
if ($slug == $item) {
81+
return 0;
82+
}
83+
84+
return (int)str_replace($slug . static::SEPARATOR, '', $item);
85+
});
86+
87+
return $notAllowed->max() + 1;
88+
}
89+
90+
/**
91+
* Set eloquent model to check uniqueness on.
92+
*
93+
* @param \Illuminate\Database\Eloquent\Model $model
94+
* @return $this
95+
*/
96+
public function uniqueFor(Model $model)
97+
{
98+
$this->model = $model;
99+
100+
return $this;
101+
}
102+
103+
/**
104+
* Set array of values which are not allowed.
105+
*
106+
* @param $values
107+
* @return $this
108+
*/
109+
public function without($values)
110+
{
111+
$this->banned = $values;
112+
113+
return $this;
114+
}
115+
116+
/**
117+
* Get collection of similar slugs based on database
118+
*
119+
* @param $slug
120+
* @return \Illuminate\Support\Collection
121+
*/
122+
private function getSimilarSlugs($slug)
123+
{
124+
if (!$this->model instanceof Model || !method_exists($this->model, 'getSlugColumn')) {
125+
return collect([]);
126+
}
127+
$slugColumn = $this->model->getSlugColumn();
128+
129+
return $this->model->newQuery()
130+
->where($slugColumn, $slug)
131+
->orWhere($slugColumn, 'LIKE', "{$slug}-%")
132+
->get()
133+
->pluck($slugColumn);
134+
}
135+
136+
}

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"require": {
88
"php": ">=5.6.4",
99
"barryvdh/laravel-cors": "^0.9.2",
10-
"cviebrock/eloquent-sluggable": "^4.2",
1110
"laravel/framework": "5.4.*",
1211
"laravel/tinker": "~1.0",
1312
"tymon/jwt-auth": "0.5.*"

0 commit comments

Comments
 (0)