sluggable.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. return [
  3. /**
  4. * What attributes do we use to build the slug?
  5. * This can be a single field, like "name" which will build a slug from:
  6. *
  7. * $model->name;
  8. *
  9. * Or it can be an array of fields, like ("name", "company"), which builds a slug from:
  10. *
  11. * $model->name . ' ' . $model->company;
  12. *
  13. * If you've defined custom getters in your model, you can use those too,
  14. * since Eloquent will call them when you request a custom attribute.
  15. *
  16. * Defaults to null, which uses the toString() method on your model.
  17. */
  18. 'source' => null,
  19. /**
  20. * The maximum length of a generated slug. Defaults to "null", which means
  21. * no length restrictions are enforced. Set it to a positive integer if you
  22. * want to make sure your slugs aren't too long.
  23. */
  24. 'maxLength' => null,
  25. /**
  26. * If you are setting a maximum length on your slugs, you may not want the
  27. * truncated string to split a word in half. The default setting of "true"
  28. * will ensure this, e.g. with a maxLength of 12:
  29. *
  30. * "my source string" -> "my-source"
  31. *
  32. * Setting it to "false" will simply truncate the generated slug at the
  33. * desired length, e.g.:
  34. *
  35. * "my source string" -> "my-source-st"
  36. */
  37. 'maxLengthKeepWords' => true,
  38. /**
  39. * If left to "null", then use the cocur/slugify package to generate the slug
  40. * (with the separator defined below).
  41. *
  42. * Set this to a closure that accepts two parameters (string and separator)
  43. * to define a custom slugger. e.g.:
  44. *
  45. * 'method' => function( $string, $sep ) {
  46. * return preg_replace('/[^a-z]+/i', $sep, $string);
  47. * },
  48. *
  49. * Otherwise, this will be treated as a callable to be used. e.g.:
  50. *
  51. * 'method' => array('Str','slug'),
  52. */
  53. 'method' => function($string, $separator = '-')
  54. {
  55. $_transliteration = array(
  56. '/ä|æ|ǽ/' => 'ae',
  57. '/ö|œ/' => 'oe',
  58. '/ü/' => 'ue',
  59. '/Ä/' => 'Ae',
  60. '/Ü/' => 'Ue',
  61. '/Ö/' => 'Oe',
  62. '/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
  63. '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
  64. '/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
  65. '/ç|ć|ĉ|ċ|č/' => 'c',
  66. '/Ð|Ď|Đ/' => 'D',
  67. '/ð|ď|đ/' => 'd',
  68. '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
  69. '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
  70. '/Ĝ|Ğ|Ġ|Ģ/' => 'G',
  71. '/ĝ|ğ|ġ|ģ/' => 'g',
  72. '/Ĥ|Ħ/' => 'H',
  73. '/ĥ|ħ/' => 'h',
  74. '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
  75. '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
  76. '/Ĵ/' => 'J',
  77. '/ĵ/' => 'j',
  78. '/Ķ/' => 'K',
  79. '/ķ/' => 'k',
  80. '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
  81. '/ĺ|ļ|ľ|ŀ|ł/' => 'l',
  82. '/Ñ|Ń|Ņ|Ň/' => 'N',
  83. '/ñ|ń|ņ|ň|ʼn/' => 'n',
  84. '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
  85. '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
  86. '/Ŕ|Ŗ|Ř/' => 'R',
  87. '/ŕ|ŗ|ř/' => 'r',
  88. '/Ś|Ŝ|Ş|Ș|Š/' => 'S',
  89. '/ś|ŝ|ş|ș|š|ſ/' => 's',
  90. '/Ţ|Ț|Ť|Ŧ/' => 'T',
  91. '/ţ|ț|ť|ŧ/' => 't',
  92. '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
  93. '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
  94. '/Ý|Ÿ|Ŷ/' => 'Y',
  95. '/ý|ÿ|ŷ/' => 'y',
  96. '/Ŵ/' => 'W',
  97. '/ŵ/' => 'w',
  98. '/Ź|Ż|Ž/' => 'Z',
  99. '/ź|ż|ž/' => 'z',
  100. '/Æ|Ǽ/' => 'AE',
  101. '/ß/' => 'ss',
  102. '/IJ/' => 'IJ',
  103. '/ij/' => 'ij',
  104. '/Œ/' => 'OE',
  105. '/ƒ/' => 'f'
  106. );
  107. $quotedReplacement = preg_quote($separator, '/');
  108. $merge = array(
  109. '/[^\s\p{Zs}\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
  110. '/[\s\p{Zs}]+/mu' => $separator,
  111. sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
  112. );
  113. $map = $_transliteration + $merge;
  114. unset($_transliteration);
  115. return mb_strtolower(preg_replace(array_keys($map), array_values($map), $string));
  116. },
  117. /**
  118. * Separator to use when generating slugs. Defaults to a hyphen.
  119. */
  120. 'separator' => '-',
  121. /**
  122. * Enforce uniqueness of slugs? Defaults to true.
  123. * If a generated slug already exists, an incremental numeric
  124. * value will be appended to the end until a unique slug is found. e.g.:
  125. *
  126. * my-slug
  127. * my-slug-1
  128. * my-slug-2
  129. */
  130. 'unique' => true,
  131. /**
  132. * If you are enforcing unique slugs, the default is to add an
  133. * incremental value to the end of the base slug. Alternatively, you
  134. * can change this value to a closure that accepts three parameters:
  135. * the base slug, the separator, and a Collection of the other
  136. * "similar" slugs. The closure should return the new unique
  137. * suffix to append to the slug.
  138. */
  139. 'uniqueSuffix' => null,
  140. /**
  141. * Should we include the trashed items when generating a unique slug?
  142. * This only applies if the softDelete property is set for the Eloquent model.
  143. * If set to "false", then a new slug could duplicate one that exists on a trashed model.
  144. * If set to "true", then uniqueness is enforced across trashed and existing models.
  145. */
  146. 'includeTrashed' => false,
  147. /**
  148. * An array of slug names that can never be used for this model,
  149. * e.g. to prevent collisions with existing routes or controller methods, etc..
  150. * Defaults to null (i.e. no reserved names).
  151. * Can be a static array, e.g.:
  152. *
  153. * 'reserved' => array('add', 'delete'),
  154. *
  155. * or a closure that returns an array of reserved names.
  156. * If using a closure, it will accept one parameter: the model itself, and should
  157. * return an array of reserved names, or null. e.g.
  158. *
  159. * 'reserved' => function( Model $model) {
  160. * return $model->some_method_that_returns_an_array();
  161. * }
  162. *
  163. * In the case of a slug that gets generated with one of these reserved names,
  164. * we will do:
  165. *
  166. * $slug .= $separator + "1"
  167. *
  168. * and continue from there.
  169. */
  170. 'reserved' => null,
  171. /**
  172. * Whether to update the slug value when a model is being
  173. * re-saved (i.e. already exists). Defaults to false, which
  174. * means slugs are not updated.
  175. *
  176. * Be careful! If you are using slugs to generate URLs, then
  177. * updating your slug automatically might change your URLs which
  178. * is probably not a good idea from an SEO point of view.
  179. * Only set this to true if you understand the possible consequences.
  180. */
  181. 'onUpdate' => false,
  182. ];