SlugHelper.php 6.51 KB
<?php
    
    namespace artbox\core\helpers;
    
    use artbox\core\models\Alias;
    use artbox\core\models\Language;
    use yii\helpers\Inflector;

    /**
     * Class SlugHelper
     * Class to work with slugs, transliteration and aliases
     */
    class SlugHelper
    {
        /**
         * SlugHelper constructor. Private in order to restict instance creation.
         */
        private function __construct()
        {
        }
    
        /**
         * Custom trasliteration rules.
         *
         * @param string $string  string to translit
         * @param string $setting all, letter, symbol possible variants
         *
         * @return string
         */
        static function translit(string $string, string $setting = 'all'): string
        {
            $letter = [
                
                'а' => 'a',
                'б' => 'b',
                'в' => 'v',
                'г' => 'g',
                'д' => 'd',
                'е' => 'e',
                'ё' => 'e',
                'ж' => 'zh',
                'з' => 'z',
                'и' => 'i',
                'й' => 'y',
                'к' => 'k',
                'л' => 'l',
                'м' => 'm',
                'н' => 'n',
                'о' => 'o',
                'п' => 'p',
                'р' => 'r',
                'с' => 's',
                'т' => 't',
                'у' => 'u',
                'ф' => 'f',
                'х' => 'h',
                'ц' => 'c',
                'ч' => 'ch',
                'ш' => 'sh',
                'щ' => 'sch',
                'ь' => "",
                'ы' => 'y',
                'ъ' => "",
                'э' => 'e',
                'ю' => 'yu',
                'я' => 'ya',
                'ї' => 'yi',
                'є' => 'ye',
                'і' => 'ee',
                
                'А' => 'A',
                'Б' => 'B',
                'В' => 'V',
                'Г' => 'G',
                'Д' => 'D',
                'Е' => 'E',
                'Ё' => 'E',
                'Ж' => 'Zh',
                'З' => 'Z',
                'И' => 'I',
                'Й' => 'Y',
                'К' => 'K',
                'Л' => 'L',
                'М' => 'M',
                'Н' => 'N',
                'О' => 'O',
                'П' => 'P',
                'Р' => 'R',
                'С' => 'S',
                'Т' => 'T',
                'У' => 'U',
                'Ф' => 'F',
                'Х' => 'H',
                'Ц' => 'C',
                'Ч' => 'Ch',
                'Ш' => 'Sh',
                'Щ' => 'Sch',
                'Ь' => "",
                'Ы' => 'Y',
                'Ъ' => "",
                'Э' => 'E',
                'Ю' => 'Yu',
                'Я' => 'Ya',
                'Ї' => 'Yi',
                'Є' => 'Ye',
                'І' => 'Ee',
            ];
            
            $symbol = [
                ' ' => '-',
                "'" => '',
                '"' => '',
                '!' => '',
                "@" => '',
                '#' => '',
                '$' => '',
                "%" => '',
                '^' => '',
                ';' => '',
                "*" => '',
                '(' => '',
                ')' => '',
                "+" => '',
                '~' => '',
                '.' => '',
                ',' => '-',
                '?' => '',
                '…' => '',
                '№' => 'N',
                '°' => '',
                '`' => '',
                '|' => '',
                '&' => '-and-',
                '<' => '',
                '>' => '',
            ];
            
            if ($setting == 'letter') {
                $converter = $letter;
            } else if ($setting == 'symbol') {
                $converter = $symbol;
            } else {
                $converter = $letter + $symbol;
            }
            
            $url = strtr($string, $converter);
            
            $url = str_replace("---", '-', $url);
            $url = str_replace("--", '-', $url);
            
            return $url;
        }
    
        /**
         * Generate slug
         *
         * @param string $string    string to translit
         * @param bool   $translit  whether to use custom translit
         * @param string $replacement
         * @param bool   $lowercase whether to lowercase result
         *
         * @see Inflector::slug()
         * @return string
         */
        static function slugify(
            string $string,
            bool $translit = true,
            string $replacement = '-',
            bool $lowercase = true
        ): string {
            return Inflector::slug($translit ? SlugHelper::translit($string) : $string, $replacement, $lowercase);
        }
    
        /**
         * Get unique to alias table slug
         *
         * @param string                    $string string to translit
         * @param \artbox\core\models\Alias $alias  Current alias
         * @param int|null                  $languageId
         *
         * @return string
         */
        static function unify(string $string, Alias $alias = null, int $languageId = null): string
        {
            $new_string = $string;
            $suffix = 2;
            while (!self::checkUnique($new_string, $alias, $languageId)) {
                $new_string = $string . '-' . $suffix;
                $suffix++;
            }
            return $new_string;
        }
    
        /**
         * Checks uniqueness of the slug
         *
         * @param string                    $string
         * @param \artbox\core\models\Alias $alias
         * @param int|null                  $languageId
         *
         * @return bool
         */
        private static function checkUnique(string $string, Alias $alias = null, int $languageId = null): bool
        {
            if (empty($languageId)) {
                $languageId = Language::$current->id;
            }
            $query = Alias::find()
                          ->where(
                              [
                                  'value'       => $string,
                                  'language_id' => $languageId,
                              ]
                          );
            if (!empty($alias) && !$alias->isNewRecord) {
                $query->andWhere(
                    [
                        'not',
                        [ 'id' => $alias->id ],
                    ]
                );
            }
            return !$query->exists();
        }
    }