[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/symfony/string/Slugger/ -> AsciiSlugger.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <[email protected]>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\String\Slugger;
  13  
  14  use Symfony\Component\String\AbstractUnicodeString;
  15  use Symfony\Component\String\UnicodeString;
  16  use Symfony\Contracts\Translation\LocaleAwareInterface;
  17  
  18  if (!interface_exists(LocaleAwareInterface::class)) {
  19      throw new \LogicException('You cannot use the "Symfony\Component\String\Slugger\AsciiSlugger" as the "symfony/translation-contracts" package is not installed. Try running "composer require symfony/translation-contracts".');
  20  }
  21  
  22  /**
  23   * @author Titouan Galopin <[email protected]>
  24   */
  25  class AsciiSlugger implements SluggerInterface, LocaleAwareInterface
  26  {
  27      private const LOCALE_TO_TRANSLITERATOR_ID = [
  28          'am' => 'Amharic-Latin',
  29          'ar' => 'Arabic-Latin',
  30          'az' => 'Azerbaijani-Latin',
  31          'be' => 'Belarusian-Latin',
  32          'bg' => 'Bulgarian-Latin',
  33          'bn' => 'Bengali-Latin',
  34          'de' => 'de-ASCII',
  35          'el' => 'Greek-Latin',
  36          'fa' => 'Persian-Latin',
  37          'he' => 'Hebrew-Latin',
  38          'hy' => 'Armenian-Latin',
  39          'ka' => 'Georgian-Latin',
  40          'kk' => 'Kazakh-Latin',
  41          'ky' => 'Kirghiz-Latin',
  42          'ko' => 'Korean-Latin',
  43          'mk' => 'Macedonian-Latin',
  44          'mn' => 'Mongolian-Latin',
  45          'or' => 'Oriya-Latin',
  46          'ps' => 'Pashto-Latin',
  47          'ru' => 'Russian-Latin',
  48          'sr' => 'Serbian-Latin',
  49          'sr_Cyrl' => 'Serbian-Latin',
  50          'th' => 'Thai-Latin',
  51          'tk' => 'Turkmen-Latin',
  52          'uk' => 'Ukrainian-Latin',
  53          'uz' => 'Uzbek-Latin',
  54          'zh' => 'Han-Latin',
  55      ];
  56  
  57      private $defaultLocale;
  58      private $symbolsMap = [
  59          'en' => ['@' => 'at', '&' => 'and'],
  60      ];
  61  
  62      /**
  63       * Cache of transliterators per locale.
  64       *
  65       * @var \Transliterator[]
  66       */
  67      private $transliterators = [];
  68  
  69      /**
  70       * @param array|\Closure|null $symbolsMap
  71       */
  72      public function __construct(string $defaultLocale = null, $symbolsMap = null)
  73      {
  74          if (null !== $symbolsMap && !\is_array($symbolsMap) && !$symbolsMap instanceof \Closure) {
  75              throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be array, Closure or null, "%s" given.', __METHOD__, \gettype($symbolsMap)));
  76          }
  77  
  78          $this->defaultLocale = $defaultLocale;
  79          $this->symbolsMap = $symbolsMap ?? $this->symbolsMap;
  80      }
  81  
  82      /**
  83       * {@inheritdoc}
  84       */
  85      public function setLocale($locale)
  86      {
  87          $this->defaultLocale = $locale;
  88      }
  89  
  90      /**
  91       * {@inheritdoc}
  92       */
  93      public function getLocale()
  94      {
  95          return $this->defaultLocale;
  96      }
  97  
  98      /**
  99       * {@inheritdoc}
 100       */
 101      public function slug(string $string, string $separator = '-', string $locale = null): AbstractUnicodeString
 102      {
 103          $locale = $locale ?? $this->defaultLocale;
 104  
 105          $transliterator = [];
 106          if ($locale && ('de' === $locale || 0 === strpos($locale, 'de_'))) {
 107              // Use the shortcut for German in UnicodeString::ascii() if possible (faster and no requirement on intl)
 108              $transliterator = ['de-ASCII'];
 109          } elseif (\function_exists('transliterator_transliterate') && $locale) {
 110              $transliterator = (array) $this->createTransliterator($locale);
 111          }
 112  
 113          if ($this->symbolsMap instanceof \Closure) {
 114              // If the symbols map is passed as a closure, there is no need to fallback to the parent locale
 115              // as the closure can just provide substitutions for all locales of interest.
 116              $symbolsMap = $this->symbolsMap;
 117              array_unshift($transliterator, static function ($s) use ($symbolsMap, $locale) {
 118                  return $symbolsMap($s, $locale);
 119              });
 120          }
 121  
 122          $unicodeString = (new UnicodeString($string))->ascii($transliterator);
 123  
 124          if (\is_array($this->symbolsMap)) {
 125              $map = null;
 126              if (isset($this->symbolsMap[$locale])) {
 127                  $map = $this->symbolsMap[$locale];
 128              } else {
 129                  $parent = self::getParentLocale($locale);
 130                  if ($parent && isset($this->symbolsMap[$parent])) {
 131                      $map = $this->symbolsMap[$parent];
 132                  }
 133              }
 134              if ($map) {
 135                  foreach ($map as $char => $replace) {
 136                      $unicodeString = $unicodeString->replace($char, ' '.$replace.' ');
 137                  }
 138              }
 139          }
 140  
 141          return $unicodeString
 142              ->replaceMatches('/[^A-Za-z0-9]++/', $separator)
 143              ->trim($separator)
 144          ;
 145      }
 146  
 147      private function createTransliterator(string $locale): ?\Transliterator
 148      {
 149          if (\array_key_exists($locale, $this->transliterators)) {
 150              return $this->transliterators[$locale];
 151          }
 152  
 153          // Exact locale supported, cache and return
 154          if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$locale] ?? null) {
 155              return $this->transliterators[$locale] = \Transliterator::create($id.'/BGN') ?? \Transliterator::create($id);
 156          }
 157  
 158          // Locale not supported and no parent, fallback to any-latin
 159          if (!$parent = self::getParentLocale($locale)) {
 160              return $this->transliterators[$locale] = null;
 161          }
 162  
 163          // Try to use the parent locale (ie. try "de" for "de_AT") and cache both locales
 164          if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$parent] ?? null) {
 165              $transliterator = \Transliterator::create($id.'/BGN') ?? \Transliterator::create($id);
 166          }
 167  
 168          return $this->transliterators[$locale] = $this->transliterators[$parent] = $transliterator ?? null;
 169      }
 170  
 171      private static function getParentLocale(?string $locale): ?string
 172      {
 173          if (!$locale) {
 174              return null;
 175          }
 176          if (false === $str = strrchr($locale, '_')) {
 177              // no parent locale
 178              return null;
 179          }
 180  
 181          return substr($locale, 0, -\strlen($str));
 182      }
 183  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer