Enabled utf8 slugs
Prevents slug change when using only non-ascii chars Allows use of more localised urls. Closes #233
Showing
8 changed files
with
29 additions
and
15 deletions
| ... | @@ -13,9 +13,9 @@ class Book extends Entity | ... | @@ -13,9 +13,9 @@ class Book extends Entity |
| 13 | public function getUrl($path = false) | 13 | public function getUrl($path = false) |
| 14 | { | 14 | { |
| 15 | if ($path !== false) { | 15 | if ($path !== false) { |
| 16 | - return baseUrl('/books/' . $this->slug . '/' . trim($path, '/')); | 16 | + return baseUrl('/books/' . urlencode($this->slug) . '/' . trim($path, '/')); |
| 17 | } | 17 | } |
| 18 | - return baseUrl('/books/' . $this->slug); | 18 | + return baseUrl('/books/' . urlencode($this->slug)); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | /* | 21 | /* | ... | ... |
| ... | @@ -32,9 +32,9 @@ class Chapter extends Entity | ... | @@ -32,9 +32,9 @@ class Chapter extends Entity |
| 32 | { | 32 | { |
| 33 | $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug; | 33 | $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug; |
| 34 | if ($path !== false) { | 34 | if ($path !== false) { |
| 35 | - return baseUrl('/books/' . $bookSlug. '/chapter/' . $this->slug . '/' . trim($path, '/')); | 35 | + return baseUrl('/books/' . urlencode($bookSlug) . '/chapter/' . urlencode($this->slug) . '/' . trim($path, '/')); |
| 36 | } | 36 | } |
| 37 | - return baseUrl('/books/' . $bookSlug. '/chapter/' . $this->slug); | 37 | + return baseUrl('/books/' . urlencode($bookSlug) . '/chapter/' . urlencode($this->slug)); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | /** | 40 | /** | ... | ... |
| ... | @@ -115,8 +115,10 @@ class ChapterController extends Controller | ... | @@ -115,8 +115,10 @@ class ChapterController extends Controller |
| 115 | $book = $this->bookRepo->getBySlug($bookSlug); | 115 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 116 | $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); | 116 | $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); |
| 117 | $this->checkOwnablePermission('chapter-update', $chapter); | 117 | $this->checkOwnablePermission('chapter-update', $chapter); |
| 118 | + if ($chapter->name !== $request->get('name')) { | ||
| 119 | + $chapter->slug = $this->chapterRepo->findSuitableSlug($request->get('name'), $book->id, $chapter->id); | ||
| 120 | + } | ||
| 118 | $chapter->fill($request->all()); | 121 | $chapter->fill($request->all()); |
| 119 | - $chapter->slug = $this->chapterRepo->findSuitableSlug($chapter->name, $book->id, $chapter->id); | ||
| 120 | $chapter->updated_by = user()->id; | 122 | $chapter->updated_by = user()->id; |
| 121 | $chapter->save(); | 123 | $chapter->save(); |
| 122 | Activity::add($chapter, 'chapter_update', $book->id); | 124 | Activity::add($chapter, 'chapter_update', $book->id); | ... | ... |
| ... | @@ -72,13 +72,13 @@ class Page extends Entity | ... | @@ -72,13 +72,13 @@ class Page extends Entity |
| 72 | { | 72 | { |
| 73 | $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug; | 73 | $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug; |
| 74 | $midText = $this->draft ? '/draft/' : '/page/'; | 74 | $midText = $this->draft ? '/draft/' : '/page/'; |
| 75 | - $idComponent = $this->draft ? $this->id : $this->slug; | 75 | + $idComponent = $this->draft ? $this->id : urlencode($this->slug); |
| 76 | 76 | ||
| 77 | if ($path !== false) { | 77 | if ($path !== false) { |
| 78 | - return baseUrl('/books/' . $bookSlug . $midText . $idComponent . '/' . trim($path, '/')); | 78 | + return baseUrl('/books/' . urlencode($bookSlug) . $midText . $idComponent . '/' . trim($path, '/')); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | - return baseUrl('/books/' . $bookSlug . $midText . $idComponent); | 81 | + return baseUrl('/books/' . urlencode($bookSlug) . $midText . $idComponent); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | /** | 84 | /** | ... | ... |
| ... | @@ -147,8 +147,10 @@ class BookRepo extends EntityRepo | ... | @@ -147,8 +147,10 @@ class BookRepo extends EntityRepo |
| 147 | */ | 147 | */ |
| 148 | public function updateFromInput(Book $book, $input) | 148 | public function updateFromInput(Book $book, $input) |
| 149 | { | 149 | { |
| 150 | + if ($book->name !== $input['name']) { | ||
| 151 | + $book->slug = $this->findSuitableSlug($input['name'], $book->id); | ||
| 152 | + } | ||
| 150 | $book->fill($input); | 153 | $book->fill($input); |
| 151 | - $book->slug = $this->findSuitableSlug($book->name, $book->id); | ||
| 152 | $book->updated_by = user()->id; | 154 | $book->updated_by = user()->id; |
| 153 | $book->save(); | 155 | $book->save(); |
| 154 | $this->permissionService->buildJointPermissionsForEntity($book); | 156 | $this->permissionService->buildJointPermissionsForEntity($book); |
| ... | @@ -208,8 +210,7 @@ class BookRepo extends EntityRepo | ... | @@ -208,8 +210,7 @@ class BookRepo extends EntityRepo |
| 208 | */ | 210 | */ |
| 209 | public function findSuitableSlug($name, $currentId = false) | 211 | public function findSuitableSlug($name, $currentId = false) |
| 210 | { | 212 | { |
| 211 | - $slug = Str::slug($name); | 213 | + $slug = $this->nameToSlug($name); |
| 212 | - if ($slug === "") $slug = substr(md5(rand(1, 500)), 0, 5); | ||
| 213 | while ($this->doesSlugExist($slug, $currentId)) { | 214 | while ($this->doesSlugExist($slug, $currentId)) { |
| 214 | $slug .= '-' . substr(md5(rand(1, 500)), 0, 3); | 215 | $slug .= '-' . substr(md5(rand(1, 500)), 0, 3); |
| 215 | } | 216 | } | ... | ... |
| ... | @@ -150,8 +150,7 @@ class ChapterRepo extends EntityRepo | ... | @@ -150,8 +150,7 @@ class ChapterRepo extends EntityRepo |
| 150 | */ | 150 | */ |
| 151 | public function findSuitableSlug($name, $bookId, $currentId = false) | 151 | public function findSuitableSlug($name, $bookId, $currentId = false) |
| 152 | { | 152 | { |
| 153 | - $slug = Str::slug($name); | 153 | + $slug = $this->nameToSlug($name); |
| 154 | - if ($slug === "") $slug = substr(md5(rand(1, 500)), 0, 5); | ||
| 155 | while ($this->doesSlugExist($slug, $bookId, $currentId)) { | 154 | while ($this->doesSlugExist($slug, $bookId, $currentId)) { |
| 156 | $slug .= '-' . substr(md5(rand(1, 500)), 0, 3); | 155 | $slug .= '-' . substr(md5(rand(1, 500)), 0, 3); |
| 157 | } | 156 | } | ... | ... |
| ... | @@ -269,6 +269,19 @@ class EntityRepo | ... | @@ -269,6 +269,19 @@ class EntityRepo |
| 269 | $this->permissionService->buildJointPermissionsForEntities($collection); | 269 | $this->permissionService->buildJointPermissionsForEntities($collection); |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | + /** | ||
| 273 | + * Format a name as a url slug. | ||
| 274 | + * @param $name | ||
| 275 | + * @return string | ||
| 276 | + */ | ||
| 277 | + protected function nameToSlug($name) | ||
| 278 | + { | ||
| 279 | + $slug = str_replace(' ', '-', strtolower($name)); | ||
| 280 | + $slug = preg_replace('/[\+\/\\\?\@\}\{\.\,\=\[\]\#\&\!\*\'\;\:\$\%]/', '', $slug); | ||
| 281 | + if ($slug === "") $slug = substr(md5(rand(1, 500)), 0, 5); | ||
| 282 | + return $slug; | ||
| 283 | + } | ||
| 284 | + | ||
| 272 | } | 285 | } |
| 273 | 286 | ||
| 274 | 287 | ... | ... |
| ... | @@ -614,8 +614,7 @@ class PageRepo extends EntityRepo | ... | @@ -614,8 +614,7 @@ class PageRepo extends EntityRepo |
| 614 | */ | 614 | */ |
| 615 | public function findSuitableSlug($name, $bookId, $currentId = false) | 615 | public function findSuitableSlug($name, $bookId, $currentId = false) |
| 616 | { | 616 | { |
| 617 | - $slug = Str::slug($name); | 617 | + $slug = $this->nameToSlug($name); |
| 618 | - if ($slug === "") $slug = substr(md5(rand(1, 500)), 0, 5); | ||
| 619 | while ($this->doesSlugExist($slug, $bookId, $currentId)) { | 618 | while ($this->doesSlugExist($slug, $bookId, $currentId)) { |
| 620 | $slug .= '-' . substr(md5(rand(1, 500)), 0, 3); | 619 | $slug .= '-' . substr(md5(rand(1, 500)), 0, 3); |
| 621 | } | 620 | } | ... | ... |
-
Please register or sign in to post a comment