Skip to content

Commit

Permalink
Make PHP slug generation consistent with JS
Browse files Browse the repository at this point in the history
Fixes #4607
cc #4295, #4381, #4266
  • Loading branch information
brandonkelly committed Jul 19, 2019
1 parent c007f4b commit a6ee904
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
### Changed
- If an invalid entry draft or revision edit URL is accessed, but the source entry does exist, Craft now redirects the browser to the source entry’s edit page. ([#4574](https://github.com/craftcms/cms/issues/4574))
- Preview requests now include the previewed entry in element queries even if the `status`, `drafts`, or `revisions` parameters are set to exclude it. ([#4581](https://github.com/craftcms/cms/issues/4581))
- Back-end slug generation now follows the same rules as JavaScript. ([#4607](https://github.com/craftcms/cms/issues/4607))

### Fixed
- Fixed a bug where each GIF frame would still be parsed when generating thumbnail, even if the `transformGifs` setting was set to `false`. ([#4588](https://github.com/craftcms/cms/issues/4588))
Expand Down
18 changes: 13 additions & 5 deletions src/helpers/ElementHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,20 @@ public static function createSlug(string $str): string
// Remove HTML tags
$str = StringHelper::stripHtml($str);

// Convert to kebab case
$glue = Craft::$app->getConfig()->getGeneral()->slugWordSeparator;
$lower = !Craft::$app->getConfig()->getGeneral()->allowUppercaseInSlug;
$str = StringHelper::toKebabCase($str, $glue, $lower, false);
// Remove inner-word punctuation
$str = preg_replace('/[\'"‘’“”\[\]\(\)\{\}:]/', '', $str);

return $str;
// Make it lowercase
$generalConfig = Craft::$app->getConfig()->getGeneral();
if (!$generalConfig->allowUppercaseInSlug) {
$str = mb_strtolower($str);
}

// Get the "words". Split on anything that is not alphanumeric or allowed punctuation
// Reference: http://www.regular-expressions.info/unicode.html
$words = array_filter(preg_split('/[^\p{L}\p{N}\p{M}\._\-]+/', $str));

return implode($generalConfig->slugWordSeparator, $words);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/helpers/ElementHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public function testSetNextOnPrevElement()
public function createSlugDataProvider(): array
{
return [
['word[separator-here]Word', 'wordWord'],
['wordWord', 'wordWord'],
['word[separator-here]word', 'word word'],
['word', 'word'],
['123456789', '123456789'],
Expand All @@ -176,6 +176,7 @@ public function createSlugDataProvider(): array
['__home__', '__home__'], // https://github.com/craftcms/cms/issues/4096
['A[separator-here]B[separator-here]C', 'A-B-C'], // https://github.com/craftcms/cms/issues/4266
['test_slug', 'test_slug'],
['Audi[separator-here]S8[separator-here]4E[separator-here]2006-2010', 'Audi S8 4E (2006-2010)'], // https://github.com/craftcms/cms/issues/4607
];
}

Expand Down

0 comments on commit a6ee904

Please sign in to comment.