PHP CEO

niksdevil

Registered
Как можем да го направим да работи и на кирилица ?

Код:
 private function makeSlug( $string )
    {
        $slug = strtolower(stripslashes($this->removeAccents($string)));
        $slug = preg_replace('/&.+?;/', '', $slug);
        $slug = preg_replace("/[^a-zA-Z0-9 ]/", "", $slug);

        $slugArray = explode(" ", $slug);

        if ( $this->configs[self::CNF_SLUG_FILTER_COMMON_WORDS] )
        {
            $slugArray = array_diff($slugArray, $this->filterInSlugs);
        }

        $slug = implode("-", $slugArray);
        return $slug;
    }

    private function removeAccents( $string )
    {
        if ( !preg_match('/[\x80-\xff]/', $string) )
        {
            return $string;
        }

        $chars = array(
            // Decompositions for Latin-1 Supplement
            chr(194) . chr(170) => 'a', chr(194) . chr(186) => 'o',
            chr(195) . chr(128) => 'A', chr(195) . chr(129) => 'A',
            chr(195) . chr(130) => 'A', chr(195) . chr(131) => 'A',
            chr(195) . chr(132) => 'A', chr(195) . chr(133) => 'A',
            chr(195) . chr(134) => 'AE', chr(195) . chr(135) => 'C',
            chr(195) . chr(136) => 'E', chr(195) . chr(137) => 'E',
            chr(195) . chr(138) => 'E', chr(195) . chr(139) => 'E',
            chr(195) . chr(140) => 'I', chr(195) . chr(141) => 'I',
            chr(195) . chr(142) => 'I', chr(195) . chr(143) => 'I',
            chr(195) . chr(144) => 'D', chr(195) . chr(145) => 'N',
            chr(195) . chr(146) => 'O', chr(195) . chr(147) => 'O',
            chr(195) . chr(148) => 'O', chr(195) . chr(149) => 'O',
            chr(195) . chr(150) => 'O', chr(195) . chr(153) => 'U',
            chr(195) . chr(154) => 'U', chr(195) . chr(155) => 'U',
            chr(195) . chr(156) => 'U', chr(195) . chr(157) => 'Y',
            chr(195) . chr(158) => 'TH', chr(195) . chr(159) => 's',
            chr(195) . chr(160) => 'a', chr(195) . chr(161) => 'a',
            chr(195) . chr(162) => 'a', chr(195) . chr(163) => 'a',
            chr(195) . chr(164) => 'a', chr(195) . chr(165) => 'a',
            chr(195) . chr(166) => 'ae', chr(195) . chr(167) => 'c',
            chr(195) . chr(168) => 'e', chr(195) . chr(169) => 'e',
            chr(195) . chr(170) => 'e', chr(195) . chr(171) => 'e',
            chr(195) . chr(172) => 'i', chr(195) . chr(173) => 'i',
            chr(195) . chr(174) => 'i', chr(195) . chr(175) => 'i',
            chr(195) . chr(176) => 'd', chr(195) . chr(177) => 'n',
            chr(195) . chr(178) => 'o', chr(195) . chr(179) => 'o',
            chr(195) . chr(180) => 'o', chr(195) . chr(181) => 'o',
            chr(195) . chr(182) => 'o', chr(195) . chr(184) => 'o',
            chr(195) . chr(185) => 'u', chr(195) . chr(186) => 'u',
            chr(195) . chr(187) => 'u', chr(195) . chr(188) => 'u',
            chr(195) . chr(189) => 'y', chr(195) . chr(190) => 'th',
            chr(195) . chr(191) => 'y', chr(195) . chr(152) => 'O',
            // Decompositions for Latin Extended-A
            chr(196) . chr(128) => 'A', chr(196) . chr(129) => 'a',
            chr(196) . chr(130) => 'A', chr(196) . chr(131) => 'a',
            chr(196) . chr(132) => 'A', chr(196) . chr(133) => 'a',
            chr(196) . chr(134) => 'C', chr(196) . chr(135) => 'c',
            chr(196) . chr(136) => 'C', chr(196) . chr(137) => 'c',
            chr(196) . chr(138) => 'C', chr(196) . chr(139) => 'c',
            chr(196) . chr(140) => 'C', chr(196) . chr(141) => 'c',
            chr(196) . chr(142) => 'D', chr(196) . chr(143) => 'd',
            chr(196) . chr(144) => 'D', chr(196) . chr(145) => 'd',
            chr(196) . chr(146) => 'E', chr(196) . chr(147) => 'e',
            chr(196) . chr(148) => 'E', chr(196) . chr(149) => 'e',
            chr(196) . chr(150) => 'E', chr(196) . chr(151) => 'e',
            chr(196) . chr(152) => 'E', chr(196) . chr(153) => 'e',
            chr(196) . chr(154) => 'E', chr(196) . chr(155) => 'e',
            chr(196) . chr(156) => 'G', chr(196) . chr(157) => 'g',
            chr(196) . chr(158) => 'G', chr(196) . chr(159) => 'g',
            chr(196) . chr(160) => 'G', chr(196) . chr(161) => 'g',
            chr(196) . chr(162) => 'G', chr(196) . chr(163) => 'g',
            chr(196) . chr(164) => 'H', chr(196) . chr(165) => 'h',
            chr(196) . chr(166) => 'H', chr(196) . chr(167) => 'h',
            chr(196) . chr(168) => 'I', chr(196) . chr(169) => 'i',
            chr(196) . chr(170) => 'I', chr(196) . chr(171) => 'i',
            chr(196) . chr(172) => 'I', chr(196) . chr(173) => 'i',
            chr(196) . chr(174) => 'I', chr(196) . chr(175) => 'i',
            chr(196) . chr(176) => 'I', chr(196) . chr(177) => 'i',
            chr(196) . chr(178) => 'IJ', chr(196) . chr(179) => 'ij',
            chr(196) . chr(180) => 'J', chr(196) . chr(181) => 'j',
            chr(196) . chr(182) => 'K', chr(196) . chr(183) => 'k',
            chr(196) . chr(184) => 'k', chr(196) . chr(185) => 'L',
            chr(196) . chr(186) => 'l', chr(196) . chr(187) => 'L',
            chr(196) . chr(188) => 'l', chr(196) . chr(189) => 'L',
            chr(196) . chr(190) => 'l', chr(196) . chr(191) => 'L',
            chr(197) . chr(128) => 'l', chr(197) . chr(129) => 'L',
            chr(197) . chr(130) => 'l', chr(197) . chr(131) => 'N',
            chr(197) . chr(132) => 'n', chr(197) . chr(133) => 'N',
            chr(197) . chr(134) => 'n', chr(197) . chr(135) => 'N',
            chr(197) . chr(136) => 'n', chr(197) . chr(137) => 'N',
            chr(197) . chr(138) => 'n', chr(197) . chr(139) => 'N',
            chr(197) . chr(140) => 'O', chr(197) . chr(141) => 'o',
            chr(197) . chr(142) => 'O', chr(197) . chr(143) => 'o',
            chr(197) . chr(144) => 'O', chr(197) . chr(145) => 'o',
            chr(197) . chr(146) => 'OE', chr(197) . chr(147) => 'oe',
            chr(197) . chr(148) => 'R', chr(197) . chr(149) => 'r',
            chr(197) . chr(150) => 'R', chr(197) . chr(151) => 'r',
            chr(197) . chr(152) => 'R', chr(197) . chr(153) => 'r',
            chr(197) . chr(154) => 'S', chr(197) . chr(155) => 's',
            chr(197) . chr(156) => 'S', chr(197) . chr(157) => 's',
            chr(197) . chr(158) => 'S', chr(197) . chr(159) => 's',
            chr(197) . chr(160) => 'S', chr(197) . chr(161) => 's',
            chr(197) . chr(162) => 'T', chr(197) . chr(163) => 't',
            chr(197) . chr(164) => 'T', chr(197) . chr(165) => 't',
            chr(197) . chr(166) => 'T', chr(197) . chr(167) => 't',
            chr(197) . chr(168) => 'U', chr(197) . chr(169) => 'u',
            chr(197) . chr(170) => 'U', chr(197) . chr(171) => 'u',
            chr(197) . chr(172) => 'U', chr(197) . chr(173) => 'u',
            chr(197) . chr(174) => 'U', chr(197) . chr(175) => 'u',
            chr(197) . chr(176) => 'U', chr(197) . chr(177) => 'u',
            chr(197) . chr(178) => 'U', chr(197) . chr(179) => 'u',
            chr(197) . chr(180) => 'W', chr(197) . chr(181) => 'w',
            chr(197) . chr(182) => 'Y', chr(197) . chr(183) => 'y',
            chr(197) . chr(184) => 'Y', chr(197) . chr(185) => 'Z',
            chr(197) . chr(186) => 'z', chr(197) . chr(187) => 'Z',
            chr(197) . chr(188) => 'z', chr(197) . chr(189) => 'Z',
            chr(197) . chr(190) => 'z', chr(197) . chr(191) => 's',
            // Decompositions for Latin Extended-B
            chr(200) . chr(152) => 'S', chr(200) . chr(153) => 's',
            chr(200) . chr(154) => 'T', chr(200) . chr(155) => 't',
            // Euro Sign
            chr(226) . chr(130) . chr(172) => 'E',
            // GBP (Pound) Sign
            chr(194) . chr(163) => '');

        return strtr($string, $chars);
    }
}
 
PHP:
	# Convert from Cyrillic to Latin URL
	public function _convert_domains($str, $length = '', $cyr2lat=true, $lower=true){
		$str = trim($str);
		$str = str_replace('  ',' ',$str);
		$str = stripslashes($str);
		$str = trim($str);
		if($cyr2lat == true){
			$str = str_replace('а','a',$str);
			$str = str_replace('б','b',$str);
			$str = str_replace('в','v',$str);
			$str = str_replace('г','g',$str);
			$str = str_replace('д','d',$str);
			$str = str_replace('е','e',$str);
			$str = str_replace('ж','j',$str);
			$str = str_replace('з','z',$str);
			$str = str_replace('и','i',$str);
			$str = str_replace('й','i',$str);
			$str = str_replace('к','k',$str);
			$str = str_replace('л','l',$str);
			$str = str_replace('м','m',$str);
			$str = str_replace('н','n',$str);
			$str = str_replace('о','o',$str);
			$str = str_replace('п','p',$str);
			$str = str_replace('р','r',$str);
			$str = str_replace('с','s',$str);
			$str = str_replace('т','t',$str);
			$str = str_replace('у','u',$str);
			$str = str_replace('ф','f',$str);
			$str = str_replace('х','h',$str);
			$str = str_replace('ц','c',$str);
			$str = str_replace('ч','ch',$str);
			$str = str_replace('ш','sh',$str);
			$str = str_replace('щ','sht',$str);
			$str = str_replace('ъ','y',$str);
			$str = str_replace('ь','yy',$str);
			$str = str_replace('ю','iu',$str);
			$str = str_replace('я','ia',$str);
			$str = str_replace('А','A',$str);
			$str = str_replace('Б','V',$str);
			$str = str_replace('В','V',$str);
			$str = str_replace('Г','G',$str);
			$str = str_replace('Д','D',$str);
			$str = str_replace('Е','E',$str);
			$str = str_replace('Ж','J',$str);
			$str = str_replace('З','Z',$str);
			$str = str_replace('И','I',$str);
			$str = str_replace('Й','I',$str);
			$str = str_replace('К','K',$str);
			$str = str_replace('Л','L',$str);
			$str = str_replace('М','M',$str);
			$str = str_replace('Н','N',$str);
			$str = str_replace('О','O',$str);
			$str = str_replace('П','P',$str);
			$str = str_replace('Р','R',$str);
			$str = str_replace('С','S',$str);
			$str = str_replace('Т','T',$str);
			$str = str_replace('У','U',$str);
			$str = str_replace('Ф','F',$str);
			$str = str_replace('Х','H',$str);
			$str = str_replace('Ц','C',$str);
			$str = str_replace('Ч','Ch',$str);;
			$str = str_replace('Ш','Sh',$str);
			$str = str_replace('Щ','Sht',$str);
			$str = str_replace('Ъ','Y',$str);
			$str = str_replace('Ь','YY',$str);
			$str = str_replace('Ю','Iu',$str);
			$str = str_replace('Я','Ia',$str);
		}
		$str = preg_replace('/[^\w]+/u', '-', $str);
		#$str = preg_replace('/[^\w]/', '-', $str);
		$str = str_replace('-----','-',$str);
		$str = str_replace('----','-',$str);
		$str = str_replace('---','-',$str);
		$str = str_replace('--','-',$str);
		if(!empty($length) && strlen($length)>0 && !is_null($length)){
			#$str = $this->_utf8_substr($str,0,$length,'UTF-8');
			$str = mb_substr($str,0,$length,'UTF-8');	
		}
		if($lower == true){
			$str = mb_strtolower(trim($str, '-'),'UTF-8');
		}
		$str = trim($str, '-');
		return $str;
	}
 
Ето го файла

Код:
<?php

/**
 * Copyright (c) 2011 Sardar Madumarov
 * All rights reserved.

 * ATTENTION: This commercial software is intended for use with Oxwall Free Community Software http://www.oxwall.org/
 * and is licensed under Oxwall Store Commercial License.
 * Full text of this license can be found at http://www.oxwall.org/store/oscl
 */

/**
 * @author Sardar Madumarov <madumarov@gmail.com>
 * @package oaseo.bol
 */
final class OASEO_BOL_Service
{
    const DATA_ROUTE_NAME = 'rname';
    const DATA_CALLBACK = 'callback';
    const DATA_DTO_PROP = 'dtoProp';
    const DATA_PATH_PROP = 'pathProp';

    const CNF_SLUG_FILTER_COMMON_WORDS = 'slug_filter_words';
    const CNF_SLUG_OLD_URLS_ENABLE = 'slug_old_urls_enabled';
    const CNF_SLUG_PLUGINS = 'slug_plugins';
    const CNF_ROBOTS_CONTENTS = 'robots_contents';

    /**
     * @var array
     */
    private $slugs = array('str' => array(), 'id' => array());
    /**
     * @var array
     */
    private $filterInSlugs = array("a", "able", "about", "above", "abroad", "according", "accordingly", "across", "actually", "adj", "after", "afterwards", "again", "against", "ago", "ahead", "ain't", "all", "allow", "allows", "almost", "alone", "along", "alongside", "already", "also", "although", "always", "am", "amid", "amidst", "among", "amongst", "an", "and", "another", "any", "anybody", "anyhow", "anyone", "anything", "anyway", "anyways", "anywhere", "apart", "appear", "appreciate", "appropriate", "are", "aren't", "around", "as", "a's", "aside", "ask", "asking", "associated", "at", "available", "away", "awfully", "b", "back", "backward", "backwards", "be", "became", "because", "become", "becomes", "becoming", "been", "before", "beforehand", "begin", "behind", "being", "believe", "below", "beside", "besides", "best", "better", "between", "beyond", "both", "brief", "but", "by", "c", "came", "can", "cannot", "cant", "can't", "caption", "cause", "causes", "certain", "certainly", "changes", "clearly", "c'mon", "co", "co.", "com", "come", "comes", "concerning", "consequently", "consider", "considering", "contain", "containing", "contains", "corresponding", "could", "couldn't", "course", "c's", "currently", "d", "dare", "daren't", "definitely", "described", "despite", "did", "didn't", "different", "directly", "do", "does", "doesn't", "doing", "done", "don't", "down", "downwards", "during", "e", "each", "edu", "eg", "eight", "eighty", "either", "else", "elsewhere", "end", "ending", "enough", "entirely", "especially", "et", "etc", "even", "ever", "evermore", "every", "everybody", "everyone", "everything", "everywhere", "ex", "exactly", "example", "except", "f", "fairly", "far", "farther", "few", "fewer", "fifth", "first", "five", "followed", "following", "follows", "for", "forever", "former", "formerly", "forth", "forward", "found", "four", "from", "further", "furthermore", "g", "get", "gets", "getting", "given", "gives", "go", "goes", "going", "gone", "got", "gotten", "greetings", "h", "had", "hadn't", "half", "happens", "hardly", "has", "hasn't", "have", "haven't", "having", "he", "he'd", "he'll", "hello", "help", "hence", "her", "here", "hereafter", "hereby", "herein", "here's", "hereupon", "hers", "herself", "he's", "hi", "him", "himself", "his", "hither", "hopefully", "how", "howbeit", "however", "hundred", "i", "i'd", "ie", "if", "ignored", "i'll", "i'm", "immediate", "in", "inasmuch", "inc", "inc.", "indeed", "indicate", "indicated", "indicates", "inner", "inside", "insofar", "instead", "into", "inward", "is", "isn't", "it", "it'd", "it'll", "its", "it's", "itself", "i've", "j", "just", "k", "keep", "keeps", "kept", "know", "known", "knows", "l", "last", "lately", "later", "latter", "latterly", "least", "less", "lest", "let", "let's", "like", "liked", "likely", "likewise", "little", "look", "looking", "looks", "low", "lower", "ltd", "m", "made", "mainly", "make", "makes", "many", "may", "maybe", "mayn't", "me", "mean", "meantime", "meanwhile", "merely", "might", "mightn't", "mine", "minus", "miss", "more", "moreover", "most", "mostly", "mr", "mrs", "much", "must", "mustn't", "my", "myself", "n", "name", "namely", "nd", "near", "nearly", "necessary", "need", "needn't", "needs", "neither", "never", "neverf", "neverless", "nevertheless", "new", "next", "nine", "ninety", "no", "nobody", "non", "none", "nonetheless", "noone", "no-one", "nor", "normally", "not", "nothing", "notwithstanding", "novel", "now", "nowhere", "o", "obviously", "of", "off", "often", "oh", "ok", "okay", "old", "on", "once", "one", "ones", "one's", "only", "onto", "opposite", "or", "other", "others", "otherwise", "ought", "oughtn't", "our", "ours", "ourselves", "out", "outside", "over", "overall", "own", "p", "particular", "particularly", "past", "per", "perhaps", "placed", "please", "plus", "possible", "presumably", "probably", "provided", "provides", "q", "que", "quite", "qv", "r", "rather", "rd", "re", "really", "reasonably", "recent", "recently", "regarding", "regardless", "regards", "relatively", "respectively", "right", "round", "s", "said", "same", "saw", "say", "saying", "says", "second", "secondly", "see", "seeing", "seem", "seemed", "seeming", "seems", "seen", "self", "selves", "sensible", "sent", "serious", "seriously", "seven", "several", "shall", "shan't", "she", "she'd", "she'll", "she's", "should", "shouldn't", "since", "six", "so", "some", "somebody", "someday", "somehow", "someone", "something", "sometime", "sometimes", "somewhat", "somewhere", "soon", "sorry", "specified", "specify", "specifying", "still", "sub", "such", "sup", "sure", "t", "take", "taken", "taking", "tell", "tends", "th", "than", "thank", "thanks", "thanx", "that", "that'll", "thats", "that's", "that've", "the", "their", "theirs", "them", "themselves", "then", "thence", "there", "thereafter", "thereby", "there'd", "therefore", "therein", "there'll", "there're", "theres", "there's", "thereupon", "there've", "these", "they", "they'd", "they'll", "they're", "they've", "thing", "things", "think", "third", "thirty", "this", "thorough", "thoroughly", "those", "though", "three", "through", "throughout", "thru", "thus", "till", "to", "together", "too", "took", "toward", "towards", "tried", "tries", "truly", "try", "trying", "t's", "twice", "two", "u", "un", "under", "underneath", "undoing", "unfortunately", "unless", "unlike", "unlikely", "until", "unto", "up", "upon", "upwards", "us", "use", "used", "useful", "uses", "using", "usually", "v", "value", "various", "versus", "very", "via", "viz", "vs", "w", "want", "wants", "was", "wasn't", "way", "we", "we'd", "welcome", "well", "we'll", "went", "were", "we're", "weren't", "we've", "what", "whatever", "what'll", "what's", "what've", "when", "whence", "whenever", "where", "whereafter", "whereas", "whereby", "wherein", "where's", "whereupon", "wherever", "whether", "which", "whichever", "while", "whilst", "whither", "who", "who'd", "whoever", "whole", "who'll", "whom", "whomever", "who's", "whose", "why", "will", "willing", "wish", "with", "within", "without", "wonder", "won't", "would", "wouldn't", "x", "y", "yes", "yet", "you", "you'd", "you'll", "your", "you're", "yours", "yourself", "yourselves", "you've", "z", "zero");
    /**
     * @var OASEO_BOL_SlugDao
     */
    private $slugDao;
    /**
     * @var OASEO_BOL_MetaDao
     */
    private $metaDao;
    /**
     * @var OASEO_BOL_UrlDao
     */
    private $urlDao;
    /**
     * @var array
     */
    private $configs = array();
    /**
     * @var array
     */
    private $activeEntityTypes = array();
    /**
     * Singleton instance.
     *
     * @var OASEO_BOL_Service
     */
    private static $classInstance;

    /**
     * Returns an instance of class (singleton pattern implementation).
     *
     * @return OASEO_BOL_Service
     */
    public static function getInstance()
    {
        if ( self::$classInstance === null )
        {
            self::$classInstance = new self();
        }

        return self::$classInstance;
    }

    /**
     * Constructor.
     */
    private function __construct()
    {
        $this->metaDao = OASEO_BOL_MetaDao::getInstance();
        $this->slugDao = OASEO_BOL_SlugDao::getInstance();
        $this->urlDao = OASEO_BOL_UrlDao::getInstance();

        $this->configs[self::CNF_SLUG_FILTER_COMMON_WORDS] = false;
        $this->configs[self::CNF_SLUG_OLD_URLS_ENABLE] = OW::getConfig()->getValue('oaseo', self::CNF_SLUG_OLD_URLS_ENABLE);
        $this->configs[self::CNF_SLUG_PLUGINS] = json_decode(OW::getConfig()->getValue('oaseo', self::CNF_SLUG_PLUGINS), true);

        $slugData = $this->getSlugData();

        foreach ( $slugData as $pluginKey => $data )
        {
            if ( in_array($pluginKey, $this->configs[self::CNF_SLUG_PLUGINS]) )
            {
                $this->activeEntityTypes = array_unique(array_merge($this->activeEntityTypes, array_keys($data)));
            }
        }

        // get all active slugs
        $slugs = $this->slugDao->findWorkingSlugs($this->activeEntityTypes);

        /* @var $slug OASEO_BOL_Slug */
        foreach ( $slugs as $slug )
        {
            if ( $slug->getActive() )
            {

                $this->slugs['str'][$slug->getEntityType()][$slug->getString()] = $slug;
                $this->slugs['id'][$slug->getEntityType()][$slug->getEntityId()] = $slug;
            }
        }
    }

    /**
     * @return array
     */
    public function getConfigs()
    {
        return $this->configs;
    }

    /**
     * @return boolean
     */
    public function isAdmin()
    {
        return (OW::getUser()->isAuthenticated() && OW::getUser()->isAuthorized('admin'));
    }

    /**
     * Returns meta info for provided dispatch params.
     * 
     * @param array $dispatchParams
     * @return OASEO_BOL_Meta
     */
    public function getEntryForDispatchParams( array $dispatchParams )
    {
        return $this->getEntryByKey($this->generateKey($dispatchParams));
    }

    /**
     * Returns meta info for provided url.
     * 
     * @param string $url
     * @return OASEO_BOL_Meta
     */
    public function getEntryForUri( $uri )
    {
        $result = $this->getDispatchParamsForUri($uri);
        return $result === false ? false : $this->getEntryForDispatchParams($result);
    }

    /**
     * Returns dispatch params for url.
     * 
     * @param type $uri
     * @return array
     */
    public function getDispatchParamsForUri( $uri )
    {
        $router = OW::getRouter();
        $preUri = $router->getUri();
        $router->setUri($uri);
        try
        {
            $dispatchAttrs = $router->route();
            $router->setUri($preUri);
            if ( isset($dispatchAttrs['vars']) )
            {
                $dispatchAttrs['params'] = $dispatchAttrs['vars'];
                unset($dispatchAttrs['vars']);
            }
            return $dispatchAttrs;
        }
        catch ( Exception $e )
        {
            return false;
        }
    }

    /**
     * Generates meta key for dispatch params.
     * 
     * @param type $dispatchAttrs
     */
    public function generateKey( array $dispatchAttrs )
    {
        $keyString = $dispatchAttrs['controller'] . '::' . $dispatchAttrs['action'] . '?';

        if ( !empty($dispatchAttrs['params']) )
        {
            ksort($dispatchAttrs['params']);

            foreach ( $dispatchAttrs['params'] as $paramName => $paramVal )
            {
                $keyString .= $paramName . '|' . $paramVal;
            }
        }

        return md5($keyString);
    }

    /**
     * @param array $dispatchAttrs
     * @param array $get
     * @return string
     */
    public function generateKeyWithGet( array $dispatchAttrs, array $get )
    {
        $keyString = $dispatchAttrs['controller'] . '::' . $dispatchAttrs['action'] . '?';

        if ( !empty($dispatchAttrs['params']) )
        {
            ksort($dispatchAttrs['params']);

            foreach ( $dispatchAttrs['params'] as $paramName => $paramVal )
            {
                $keyString .= $paramName . '|' . $paramVal;
            }
        }

        if ( !empty($get) )
        {
            ksort($get);

            foreach ( $get as $paramName => $paramVal )
            {
                $keyString .= $paramName . '+' . $paramVal;
            }
        }

        return md5($keyString);
    }

    /**
     * @param OASEO_BOL_Meta $entry
     */
    public function saveEntry( OASEO_BOL_Meta $entry )
    {
        $this->metaDao->save($entry);
    }

    /**
     * @param string $key
     * @return OASEO_BOL_Meta
     */
    public function getEntryByKey( $key )
    {
        return $this->metaDao->findEntryByKey($key);
    }

    /**
     * @param string $entityType
     * @param integer $entityId
     * @param callback $serviceCallback
     * @param string $dtoProperty
     * @return string
     */
    public function getSlugStringForEntity( $entityType, $entityId, $serviceCallback, $dtoProperty )
    {
        if ( !empty($this->slugs['id'][$entityType][$entityId]) )
        {
            return $this->slugs['id'][$entityType][$entityId]->getString();
        }

        $dbSlug = $this->slugDao->findActiveSlugForEntityItem($entityType, $entityId);

        if ( $dbSlug !== null )
        {
            return $dbSlug->getString();
        }

        // processing and generating new slug
        $dto = call_user_func($serviceCallback, $entityId);

        if ( $dto !== null )
        {
            $vars = get_object_vars($dto);

            if ( !empty($vars[$dtoProperty]) && is_string($vars[$dtoProperty]) )
            {
                // do not support non latin strings
                if ( preg_match('/[^\\p{Common}\\p{Latin}]/u', $vars[$dtoProperty]) )
                {
                    return null;
                }

                $slug = $this->makeSlug($vars[$dtoProperty]);

                $duplicateSlugDto = $this->slugDao->findDuplicateSlug($entityType, $slug);

                if ( $duplicateSlugDto !== null )
                {
                    $slug = $slug . '-' . $entityId;
                }

                if ( strlen($slug) > 2 )
                {
                    $slugDto = $this->slugDao->findSlug($entityType, $entityId, $slug);

                    if ( $slugDto === null )
                    {
                        $this->slugDao->updateSlugStatus($entityType, $entityId);
                        $slugDto = new OASEO_BOL_Slug();
                        $slugDto->setEntityType($entityType);
                        $slugDto->setEntityId($entityId);
                        $slugDto->setString($slug);
                        $slugDto->setActive(true);
                        $this->slugDao->save($slugDto);
                    }

                    $this->slugs['id'][$entityType][$entityId] = $slugDto;

                    return $slugDto->getString();
                }
            }
        }
    }

    /**
     * @param string $entityType
     * @param string $slugString
     * @return OASEO_BOL_Slug
     */
    public function getSlugForString( $entityType, $slugString )
    {
        if ( !empty($this->slugs['str'][$entityType][$slugString]) )
        {
            return $this->slugs['str'][$entityType][$slugString];
        }
    }

    /**
     * @param string $entityType
     * @param string $slugString
     * @return OASEO_BOL_Slug
     */
    public function findActiveSlugForInactiveOne( $entityType, $slugString )
    {
        $oldSlug = $this->slugDao->findOldSlug($entityType, $slugString);

        if ( $oldSlug !== null )
        {
            return $this->slugDao->findActiveSlugForEntityItem($entityType, $oldSlug->getEntityId());
        }
    }

    /**
     * @param string $entityType
     * @param integer $entityId
     * @return OASEO_BOL_Slug
     */
    public function findActiveSlugForEntityItem( $entityType, $entityId )
    {
        return $this->slugDao->findActiveSlugForEntityItem($entityType, $entityId);
    }

    /**
     * @param string $entityType
     * @param integer $entityId
     * @param callback $callback
     * @param string $dtoProperty
     */
    public function checkEntityUpdate( $entityType, $entityId, $callback, $dtoProperty )
    {
        $dto = call_user_func($callback, $entityId);
        $vars = get_object_vars($dto);

        if ( empty($vars[$dtoProperty]) )
        {
            return;
        }

        $procSlug = $this->makeSlug($vars[$dtoProperty]);

        $slugArr = explode('-', $this->slugs['id'][$entityType][$entityId]->getString());
        $potencialId = $slugArr[sizeof($slugArr) - 1];

        if ( is_numeric($potencialId) && (int) $potencialId === (int) $entityId )
        {
            $procSlug .= '-' . $entityId;
        }

        if ( $procSlug !== $this->slugs['id'][$entityType][$entityId]->getString() )
        {
            $this->slugDao->updateSlugStatus($entityType, $entityId);
            $slugDto = $this->slugDao->findSlug($entityType, $entityId, $procSlug);
            if ( $slugDto === null )
            {
                $slugDto = new OASEO_BOL_Slug();
                $slugDto->setEntityType($entityType);
                $slugDto->setEntityId($entityId);
                $slugDto->setString($procSlug);
            }
            $slugDto->setActive(true);
            $this->slugDao->save($slugDto);
        }
    }

    /**
     * @return array
     */
    public function getSlugData()
    {
        return array(
            'forum' => array(
                'forum-topic' => array(
                    self::DATA_ROUTE_NAME => 'topic-default',
                    self::DATA_CALLBACK => array('FORUM_BOL_ForumService', 'findTopicById'),
                    self::DATA_DTO_PROP => 'title',
                    self::DATA_PATH_PROP => 'topicId'),
                'forum-group' => array(
                    self::DATA_ROUTE_NAME => 'group-default',
                    self::DATA_CALLBACK => array('FORUM_BOL_ForumService', 'findGroupById'),
                    self::DATA_DTO_PROP => 'name',
                    self::DATA_PATH_PROP => 'groupId'),
            ),
            'blogs' => array(
                'blogs-user-post' => array(
                    self::DATA_ROUTE_NAME => 'user-post',
                    self::DATA_CALLBACK => array('PostService', 'findById'),
                    self::DATA_DTO_PROP => 'title',
                    self::DATA_PATH_PROP => 'id'),
            ),
            'blogs' => array(
                'blogs-user-post' => array(
                    self::DATA_ROUTE_NAME => 'user-post',
                    self::DATA_CALLBACK => array('PostService', 'findById'),
                    self::DATA_DTO_PROP => 'title',
                    self::DATA_PATH_PROP => 'id'),
            ),
            'event' => array(
                'event-view' => array(
                    self::DATA_ROUTE_NAME => 'event.view',
                    self::DATA_CALLBACK => array('EVENT_BOL_EventService', 'findEvent'),
                    self::DATA_DTO_PROP => 'title',
                    self::DATA_PATH_PROP => 'eventId'),
            ),
            'groups' => array(
                'groups-view' => array(
                    self::DATA_ROUTE_NAME => 'groups-view',
                    self::DATA_CALLBACK => array('GROUPS_BOL_Service', 'findGroupById'),
                    self::DATA_DTO_PROP => 'title',
                    self::DATA_PATH_PROP => 'groupId'),
            ),
            'video' => array(
                'video-view' => array(
                    self::DATA_ROUTE_NAME => 'view_clip',
                    self::DATA_CALLBACK => array('VIDEO_BOL_ClipService', 'findClipById'),
                    self::DATA_DTO_PROP => 'title',
                    self::DATA_PATH_PROP => 'id'),
            ),
        );
    }

    public function initSlugs()
    {
        $dataArray = $this->getSlugData();
        $router = OW::getRouter();
        foreach ( $dataArray as $pluginKey => $pluginData )
        {
            if ( in_array($pluginKey, $this->configs[self::CNF_SLUG_PLUGINS]) )
            {
                foreach ( $pluginData as $entityType => $entityData )
                {
                    $route = $router->getRoute($entityData[self::DATA_ROUTE_NAME]);

                    if ( $route !== null )
                    {
                        $router->removeRoute($entityData[self::DATA_ROUTE_NAME]);
                        $specRoute = new OASEO_CLASS_SlugRoute($route, array(call_user_func(array($entityData[self::DATA_CALLBACK][0], 'getInstance')), $entityData[self::DATA_CALLBACK][1]), $entityData[self::DATA_DTO_PROP], $entityData[self::DATA_PATH_PROP], $entityType);
                        $router->addRoute($specRoute);
                    }
                }
            }
        }
    }

    public function getRouteData( $uri )
    {
        $router = OW::getRouter();
        $routerArr = (array) $router;

        $staticRoutes = $routerArr["\0OW_Router\0staticRoutes"];
        $routes = $routerArr["\0OW_Router\0routes"];

        $currentRoute = null;

        foreach ( $staticRoutes as $route )
        {
            if ( $route->match($uri) )
            {
                $currentRoute = $route;
                break;
            }
        }

        if ( $currentRoute === null )
        {
            foreach ( $routes as $route )
            {
                if ( $route->match($uri) )
                {
                    $currentRoute = $route;
                    break;
                }
            }
        }

        if ( $currentRoute === null )
        {
            return null;
        }

        $rtArr = (array) $currentRoute;

        $urlDto = $this->urlDao->findByRouteName($rtArr["\0OW_Route\0routeName"]);
        return array('name' => $rtArr["\0OW_Route\0routeName"], 'path' => ( empty($urlDto) ? $rtArr["\0OW_Route\0routePath"] : $urlDto->getUrl() ));
    }

    public function initUrls()
    {
        $router = OW::getRouter();
        $urls = $this->urlDao->findAll();
        
        /* @var $url OASEO_BOL_Url */
        foreach ( $urls as $url )
        {
            $rt = $router->getRoute($url->getRouteName());

            if ( $rt !== null )
            {
                $slugRoute = false;
                if ( get_class($rt) == 'OASEO_CLASS_SlugRoute' )
                {
                    $origRt = $rt;
                    $rt = $origRt->getRoute();
                    $slugRoute = true;
                }

                $rtArr = (array) $rt;
                $routeName = $rtArr["\0OW_Route\0routeName"];
                $routePath = $rtArr["\0OW_Route\0routePath"];
                $routePathArray = $rtArr["\0OW_Route\0routePathArray"];
                $isStatic = $rtArr["\0OW_Route\0isStatic"];
                $dispatchAttrs = $rtArr["\0OW_Route\0dispatchAttrs"];
                $routeParamOptions = $rtArr["\0OW_Route\0routeParamOptions"];
                $newRoute = new OW_Route($routeName, $url->getUrl(), $dispatchAttrs['controller'], $dispatchAttrs['action'], $routeParamOptions);

                if ( $slugRoute === true )
                {
                    $newRoute = new OASEO_CLASS_SlugRoute($newRoute, $origRt->getServiceCallback(), $origRt->getDtoProperty(), $origRt->getPathProperty(), $origRt->getEntityType());
                }

                $router->removeRoute($url->getRouteName());
                $router->addRoute($newRoute);

                $rand = uniqid('redirect_url');
                $redirectRoute = new OASEO_CLASS_RedirectRoute($rand, $routePath, $rand, $rand);
                $redirectRoute->setNewUrl($url->getUrl());
                $router->addRoute($redirectRoute);
            }
        }
    }

    /**
     * @param string $name
     * @return OASEO_BOL_Url
     */
    public function findUrlByRouteName( $name )
    {
        return $this->urlDao->findByRouteName($name);
    }

    /**
     * @param OASEO_BOL_Url $dto
     */
    public function saveUrl( OASEO_BOL_Url $dto )
    {
        $this->urlDao->save($dto);
    }

    private function makeSlug( $string )
    {
        $slug = strtolower(stripslashes($this->removeAccents($string)));
        $slug = preg_replace('/&.+?;/', '', $slug);
        $slug = preg_replace("/[^a-zA-Z0-9 ]/", "", $slug);

        $slugArray = explode(" ", $slug);

        if ( $this->configs[self::CNF_SLUG_FILTER_COMMON_WORDS] )
        {
            $slugArray = array_diff($slugArray, $this->filterInSlugs);
        }

        $slug = implode("-", $slugArray);
        return $slug;
    }

    private function removeAccents( $string )
    {
        if ( !preg_match('/[\x80-\xff]/', $string) )
        {
            return $string;
        }

        $chars = array(
            // Decompositions for Latin-1 Supplement
            chr(194) . chr(170) => 'a', chr(194) . chr(186) => 'o',
            chr(195) . chr(128) => 'A', chr(195) . chr(129) => 'A',
            chr(195) . chr(130) => 'A', chr(195) . chr(131) => 'A',
            chr(195) . chr(132) => 'A', chr(195) . chr(133) => 'A',
            chr(195) . chr(134) => 'AE', chr(195) . chr(135) => 'C',
            chr(195) . chr(136) => 'E', chr(195) . chr(137) => 'E',
            chr(195) . chr(138) => 'E', chr(195) . chr(139) => 'E',
            chr(195) . chr(140) => 'I', chr(195) . chr(141) => 'I',
            chr(195) . chr(142) => 'I', chr(195) . chr(143) => 'I',
            chr(195) . chr(144) => 'D', chr(195) . chr(145) => 'N',
            chr(195) . chr(146) => 'O', chr(195) . chr(147) => 'O',
            chr(195) . chr(148) => 'O', chr(195) . chr(149) => 'O',
            chr(195) . chr(150) => 'O', chr(195) . chr(153) => 'U',
            chr(195) . chr(154) => 'U', chr(195) . chr(155) => 'U',
            chr(195) . chr(156) => 'U', chr(195) . chr(157) => 'Y',
            chr(195) . chr(158) => 'TH', chr(195) . chr(159) => 's',
            chr(195) . chr(160) => 'a', chr(195) . chr(161) => 'a',
            chr(195) . chr(162) => 'a', chr(195) . chr(163) => 'a',
            chr(195) . chr(164) => 'a', chr(195) . chr(165) => 'a',
            chr(195) . chr(166) => 'ae', chr(195) . chr(167) => 'c',
            chr(195) . chr(168) => 'e', chr(195) . chr(169) => 'e',
            chr(195) . chr(170) => 'e', chr(195) . chr(171) => 'e',
            chr(195) . chr(172) => 'i', chr(195) . chr(173) => 'i',
            chr(195) . chr(174) => 'i', chr(195) . chr(175) => 'i',
            chr(195) . chr(176) => 'd', chr(195) . chr(177) => 'n',
            chr(195) . chr(178) => 'o', chr(195) . chr(179) => 'o',
            chr(195) . chr(180) => 'o', chr(195) . chr(181) => 'o',
            chr(195) . chr(182) => 'o', chr(195) . chr(184) => 'o',
            chr(195) . chr(185) => 'u', chr(195) . chr(186) => 'u',
            chr(195) . chr(187) => 'u', chr(195) . chr(188) => 'u',
            chr(195) . chr(189) => 'y', chr(195) . chr(190) => 'th',
            chr(195) . chr(191) => 'y', chr(195) . chr(152) => 'O',
            // Decompositions for Latin Extended-A
            chr(196) . chr(128) => 'A', chr(196) . chr(129) => 'a',
            chr(196) . chr(130) => 'A', chr(196) . chr(131) => 'a',
            chr(196) . chr(132) => 'A', chr(196) . chr(133) => 'a',
            chr(196) . chr(134) => 'C', chr(196) . chr(135) => 'c',
            chr(196) . chr(136) => 'C', chr(196) . chr(137) => 'c',
            chr(196) . chr(138) => 'C', chr(196) . chr(139) => 'c',
            chr(196) . chr(140) => 'C', chr(196) . chr(141) => 'c',
            chr(196) . chr(142) => 'D', chr(196) . chr(143) => 'd',
            chr(196) . chr(144) => 'D', chr(196) . chr(145) => 'd',
            chr(196) . chr(146) => 'E', chr(196) . chr(147) => 'e',
            chr(196) . chr(148) => 'E', chr(196) . chr(149) => 'e',
            chr(196) . chr(150) => 'E', chr(196) . chr(151) => 'e',
            chr(196) . chr(152) => 'E', chr(196) . chr(153) => 'e',
            chr(196) . chr(154) => 'E', chr(196) . chr(155) => 'e',
            chr(196) . chr(156) => 'G', chr(196) . chr(157) => 'g',
            chr(196) . chr(158) => 'G', chr(196) . chr(159) => 'g',
            chr(196) . chr(160) => 'G', chr(196) . chr(161) => 'g',
            chr(196) . chr(162) => 'G', chr(196) . chr(163) => 'g',
            chr(196) . chr(164) => 'H', chr(196) . chr(165) => 'h',
            chr(196) . chr(166) => 'H', chr(196) . chr(167) => 'h',
            chr(196) . chr(168) => 'I', chr(196) . chr(169) => 'i',
            chr(196) . chr(170) => 'I', chr(196) . chr(171) => 'i',
            chr(196) . chr(172) => 'I', chr(196) . chr(173) => 'i',
            chr(196) . chr(174) => 'I', chr(196) . chr(175) => 'i',
            chr(196) . chr(176) => 'I', chr(196) . chr(177) => 'i',
            chr(196) . chr(178) => 'IJ', chr(196) . chr(179) => 'ij',
            chr(196) . chr(180) => 'J', chr(196) . chr(181) => 'j',
            chr(196) . chr(182) => 'K', chr(196) . chr(183) => 'k',
            chr(196) . chr(184) => 'k', chr(196) . chr(185) => 'L',
            chr(196) . chr(186) => 'l', chr(196) . chr(187) => 'L',
            chr(196) . chr(188) => 'l', chr(196) . chr(189) => 'L',
            chr(196) . chr(190) => 'l', chr(196) . chr(191) => 'L',
            chr(197) . chr(128) => 'l', chr(197) . chr(129) => 'L',
            chr(197) . chr(130) => 'l', chr(197) . chr(131) => 'N',
            chr(197) . chr(132) => 'n', chr(197) . chr(133) => 'N',
            chr(197) . chr(134) => 'n', chr(197) . chr(135) => 'N',
            chr(197) . chr(136) => 'n', chr(197) . chr(137) => 'N',
            chr(197) . chr(138) => 'n', chr(197) . chr(139) => 'N',
            chr(197) . chr(140) => 'O', chr(197) . chr(141) => 'o',
            chr(197) . chr(142) => 'O', chr(197) . chr(143) => 'o',
            chr(197) . chr(144) => 'O', chr(197) . chr(145) => 'o',
            chr(197) . chr(146) => 'OE', chr(197) . chr(147) => 'oe',
            chr(197) . chr(148) => 'R', chr(197) . chr(149) => 'r',
            chr(197) . chr(150) => 'R', chr(197) . chr(151) => 'r',
            chr(197) . chr(152) => 'R', chr(197) . chr(153) => 'r',
            chr(197) . chr(154) => 'S', chr(197) . chr(155) => 's',
            chr(197) . chr(156) => 'S', chr(197) . chr(157) => 's',
            chr(197) . chr(158) => 'S', chr(197) . chr(159) => 's',
            chr(197) . chr(160) => 'S', chr(197) . chr(161) => 's',
            chr(197) . chr(162) => 'T', chr(197) . chr(163) => 't',
            chr(197) . chr(164) => 'T', chr(197) . chr(165) => 't',
            chr(197) . chr(166) => 'T', chr(197) . chr(167) => 't',
            chr(197) . chr(168) => 'U', chr(197) . chr(169) => 'u',
            chr(197) . chr(170) => 'U', chr(197) . chr(171) => 'u',
            chr(197) . chr(172) => 'U', chr(197) . chr(173) => 'u',
            chr(197) . chr(174) => 'U', chr(197) . chr(175) => 'u',
            chr(197) . chr(176) => 'U', chr(197) . chr(177) => 'u',
            chr(197) . chr(178) => 'U', chr(197) . chr(179) => 'u',
            chr(197) . chr(180) => 'W', chr(197) . chr(181) => 'w',
            chr(197) . chr(182) => 'Y', chr(197) . chr(183) => 'y',
            chr(197) . chr(184) => 'Y', chr(197) . chr(185) => 'Z',
            chr(197) . chr(186) => 'z', chr(197) . chr(187) => 'Z',
            chr(197) . chr(188) => 'z', chr(197) . chr(189) => 'Z',
            chr(197) . chr(190) => 'z', chr(197) . chr(191) => 's',
            // Decompositions for Latin Extended-B
            chr(200) . chr(152) => 'S', chr(200) . chr(153) => 's',
            chr(200) . chr(154) => 'T', chr(200) . chr(155) => 't',
            // Euro Sign
            chr(226) . chr(130) . chr(172) => 'E',
            // GBP (Pound) Sign
            chr(194) . chr(163) => '');

        return strtr($string, $chars);
    }
}
 

Горе