HTTPQuery =& $this->Application->recallObject('HTTPQuery'); // domain based primary language $this->primaryLanguageId = $this->Application->siteDomainField('PrimaryLanguageId'); if (!$this->primaryLanguageId) { // when domain-based language not found -> use site-wide language $this->primaryLanguageId = $this->Application->GetDefaultLanguageId(); } // domain based primary theme $this->primaryThemeId = $this->Application->siteDomainField('PrimaryThemeId'); if (!$this->primaryThemeId) { // when domain-based theme not found -> use site-wide theme $this->primaryThemeId = $this->Application->GetDefaultThemeId(true); } $this->_initRewriteListeners(); } /** * Parses url * * @return void */ public function parseRewriteURL() { $url = $this->Application->GetVar('_mod_rw_url_'); if ($url) { foreach ($this->_urlEndings as $url_ending) { if (substr($url, strlen($url) - strlen($url_ending)) == $url_ending) { $url = substr($url, 0, strlen($url) - strlen($url_ending)); $default_ending = $this->Application->ConfigValue('ModRewriteUrlEnding'); // user manually typed url with different url ending -> redirect to same url with default url ending if (($url_ending != $default_ending) && $this->Application->ConfigValue('ForceModRewriteUrlEnding')) { $target_url = $this->Application->BaseURL() . $url . $default_ending; $this->Application->Redirect('external:' . $target_url, Array ('response_code' => 301)); } break; } } } $cached = $this->_getCachedUrl($url); if ( $cached !== false ) { $vars = $cached['vars']; $passed = $cached['passed']; } else { $vars = $this->parse($url); $passed = $vars['pass']; // also used in bottom of this method unset($vars['pass']); if ( !$this->_partsToParse ) { // don't cache 404 Not Found $this->_setCachedUrl($url, Array ('vars' => $vars, 'passed' => $passed)); } if ( $this->Application->GetVarDirect('t', 'Post') ) { // template from POST overrides template from URL. $vars['t'] = $this->Application->GetVarDirect('t', 'Post'); if ( isset($vars['is_virtual']) && $vars['is_virtual'] ) { $vars['m_cat_id'] = 0; // this is virtual template category (for Proj-CMS) } } unset($vars['is_virtual']); } foreach ($vars as $name => $value) { $this->HTTPQuery->Set($name, $value); } $this->_initAll(); // also will use parsed language to load phrases from it $this->HTTPQuery->finalizeParsing($passed); } /** * Returns url parsing result from cache or false, when not yet parsed * * @param $url * @return Array|bool * @access protected */ protected function _getCachedUrl($url) { if (!$url) { return false; } $sql = 'SELECT * FROM ' . TABLE_PREFIX . 'CachedUrls WHERE Hash = ' . crc32($url) . ' AND DomainId = ' . (int)$this->Application->siteDomainField('DomainId'); $data = $this->Conn->GetRow($sql); if ($data) { $lifetime = (int)$data['LifeTime']; // in seconds if (($lifetime > 0) && ($data['Cached'] + $lifetime < adodb_mktime())) { // delete expired $sql = 'DELETE FROM ' . TABLE_PREFIX . 'CachedUrls WHERE UrlId = ' . $data['UrlId']; $this->Conn->Query($sql); return false; } return unserialize($data['ParsedVars']); } return false; } /** * Caches url * * @param string $url * @param Array $data * @return void * @access protected */ protected function _setCachedUrl($url, $data) { if (!$url) { return ; } $vars = $data['vars']; $passed = $data['passed']; sort($passed); // get expiration if ($vars['m_cat_id'] > 0) { $sql = 'SELECT PageExpiration FROM ' . TABLE_PREFIX . 'Categories WHERE CategoryId = ' . $vars['m_cat_id']; $expiration = $this->Conn->GetOne($sql); } // get prefixes $prefixes = Array (); $m_index = array_search('m', $passed); if ($m_index !== false) { unset($passed[$m_index]); if ($vars['m_cat_id'] > 0) { $prefixes[] = 'c:' . $vars['m_cat_id']; } $prefixes[] = 'lang:' . $vars['m_lang']; $prefixes[] = 'theme:' . $vars['m_theme']; } foreach ($passed as $prefix) { if (array_key_exists($prefix . '_id', $vars) && is_numeric($vars[$prefix . '_id'])) { $prefixes[] = $prefix . ':' . $vars[$prefix . '_id']; } else { $prefixes[] = $prefix; } } $fields_hash = Array ( 'Url' => $url, 'Hash' => crc32($url), 'DomainId' => (int)$this->Application->siteDomainField('DomainId'), 'Prefixes' => $prefixes ? '|' . implode('|', $prefixes) . '|' : '', 'ParsedVars' => serialize($data), 'Cached' => adodb_mktime(), 'LifeTime' => isset($expiration) && is_numeric($expiration) ? $expiration : -1 ); $this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'CachedUrls'); } /** * Loads all registered rewrite listeners, so they could be quickly accessed later * * @access protected */ protected function _initRewriteListeners() { static $init_done = false; if ($init_done || count($this->Application->RewriteListeners) == 0) { // not initialized OR mod-rewrite url with missing config cache return ; } foreach ($this->Application->RewriteListeners as $prefix => $listener_data) { foreach ($listener_data['listener'] as $index => $rewrite_listener) { list ($listener_prefix, $listener_method) = explode(':', $rewrite_listener); // don't use temp variable, since it will swap objects in Factory in PHP5 $this->rewriteListeners[$prefix][$index] = Array (); $this->rewriteListeners[$prefix][$index][0] =& $this->Application->recallObject($listener_prefix); $this->rewriteListeners[$prefix][$index][1] = $listener_method; } } define('MOD_REWRITE_URL_ENDING', $this->Application->ConfigValue('ModRewriteUrlEnding')); $init_done = true; } /** * Parses given string into a set of variables (url in this case) * * @param string $string * @param string $pass_name * @return Array * @access public */ public function parse($string, $pass_name = 'pass') { $vars = Array ($pass_name => Array ('m')); $url_parts = $string ? explode('/', trim(mb_strtolower($string, 'UTF-8'), '/')) : Array (); $this->_partsToParse = $url_parts; if ( ($this->HTTPQuery->Get('rewrite') == 'on') || !$url_parts ) { $this->_setDefaultValues($vars); } if ( !$url_parts ) { $this->_initAll(); $vars['t'] = $this->Application->UrlManager->getTemplateName(); return $vars; } $this->_parseLanguage($url_parts, $vars); $this->_parseTheme($url_parts, $vars); // http://site-url///[_]/