91         $iLang = (int) $iLang;
 
   92         $iDefLang = (int) $this->
getConfig()->getConfigParam(
'iDefSeoLang');
 
   95         if ($iLang != $iDefLang && isset($aLangIds[$iLang]) && 
getStr()->strpos($sSeoUrl, $aLangIds[$iLang] . 
'/') !== 0) {
 
   96             $sSeoUrl = $aLangIds[$iLang] . 
'/' . $sSeoUrl;
 
  114     protected function _processSeoUrl($sSeoUrl, $sObjectId = null, $iLang = null, $blExclude = 
false)
 
  129         if (!self::$_sSeparator) {
 
  132         if (!self::$_sPrefix) {
 
  147     protected function _copyToHistory($sId, $iShopId, $iLang, $sType = null, $sNewId = null)
 
  150         $sObjectid = $sNewId ? $oDb->quote($sNewId) : 
'oxobjectid';
 
  151         $sType = $sType ? 
"oxtype =" . $oDb->quote($sType) . 
" and" : 
'';
 
  152         $iLang = (int) $iLang;
 
  155         $sSub = 
"select $sObjectid, MD5( LOWER( oxseourl ) ), oxshopid, oxlang, now() from oxseo 
  156                  where {$sType} oxobjectid = " . $oDb->quote($sId) . 
" and oxshopid = " . $oDb->quote($iShopId) . 
" and 
  157                  oxlang = {$iLang} and oxexpired = '1'";
 
  158         $sQ = 
"replace oxseohistory ( oxobjectid, oxident, oxshopid, oxlang, oxinsert ) {$sSub}";
 
  186         $iShopId = $this->
getConfig()->getShopId();
 
  188         $sStdUrl = $this->
_trimUrl($sStdUrl);
 
  193         $sOldSeoUrl = $this->
_loadFromDb(
'dynamic', $sObjectId, $iLang);
 
  194         if ($sOldSeoUrl === $sSeoUrl) {
 
  195             $sSeoUrl = $sOldSeoUrl;
 
  207             $this->
_saveToDb(
'dynamic', $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId);
 
  222     protected function _getFullUrl($sSeoUrl, $iLang = null, $blSsl = 
false)
 
  225             $sFullUrl = ($blSsl ? $this->
getConfig()->getSslShopUrl($iLang) : $this->
getConfig()->getShopUrl($iLang, 
false)) . $sSeoUrl;
 
  244         return md5(strtolower($sSeoUrl));
 
  258         $sStdUrl = $this->
_trimUrl($sStdUrl, $iLang);
 
  287         $sSeoUrl = $this->
_prepareUri($sSeoUrl, $iObjectLang);
 
  290         if ($oStr->preg_match(
'/(\.html?|\/)$/i', $sSeoUrl, $aMatched)) {
 
  291             $sExt = $aMatched[0];
 
  293         $sBaseSeoUrl = $sSeoUrl;
 
  294         if ($sExt && $oStr->substr($sSeoUrl, 0 - $oStr->strlen($sExt)) == $sExt) {
 
  295             $sBaseSeoUrl = $oStr->substr($sSeoUrl, 0, $oStr->strlen($sSeoUrl) - $oStr->strlen($sExt));
 
  298         $iShopId = $this->
getConfig()->getShopId();
 
  300         $sCheckSeoUrl = $this->
_trimUrl($sSeoUrl);
 
  301         $sQ = 
"select 1 from oxseo where oxshopid = '{$iShopId}'";
 
  305         if ($sObjectId && isset($iObjectLang)) {
 
  306             $iObjectLang = (int) $iObjectLang;
 
  307             $sQ .= 
" and not (oxobjectid = " . $oDb->quote($sObjectId) . 
" and oxlang = $iObjectLang)";
 
  310         while ($oDb->getOne($sQ . 
" and oxident= " . $oDb->quote($this->_getSeoIdent($sCheckSeoUrl)))) {
 
  312             if (self::$_sPrefix) {
 
  316                 $sAdd .= self::$_sSeparator . $iCnt;
 
  320             $sSeoUrl = $sBaseSeoUrl . $sAdd . $sExt;
 
  321             $sCheckSeoUrl = $this->
_trimUrl($sSeoUrl);
 
  341     protected function _isFixed($sType, $sId, $iLang, $iShopId = null, $sParams = null, $blStrictParamsCheck = 
true)
 
  343         if ($iShopId === null) {
 
  344             $iShopId = $this->
getConfig()->getShopId();
 
  346         $iLang = (int) $iLang;
 
  348         if (!isset(self::$_aFixedCache[$sType][$sShopId][$sId][$iLang])) {
 
  351             $sQ = 
"SELECT `oxfixed` 
  353                 WHERE `oxtype` = " . $oDb->quote($sType) . 
" 
  354                    AND `oxobjectid` = " . $oDb->quote($sId) . 
" 
  355                    AND `oxshopid` = " . $oDb->quote($iShopId) . 
" 
  356                    AND `oxlang` = '{$iLang}'";
 
  358             $sParams = $sParams ? $oDb->quote($sParams) : 
"''";
 
  359             if ($sParams && $blStrictParamsCheck) {
 
  360                 $sQ .= 
" AND `oxparams` = {$sParams}";
 
  362                 $sQ .= 
" ORDER BY `oxparams` ASC";
 
  366             self::$_aFixedCache[$sType][$sShopId][$sId][$iLang] = (bool) $oDb->getOne($sQ);
 
  369         return self::$_aFixedCache[$sType][$sShopId][$sId][$iLang];
 
  382     protected function _getCacheKey($sType, $iLang = null, $iShopId = null, $sParams = null)
 
  385         if (!$blAdmin && $sType !== 
"oxarticle") {
 
  386             return $sType . ((int) $iLang) . ((int) $iShopId) . 
"seo";
 
  390         if (self::$_sCacheKey === null) {
 
  391             self::$_sCacheKey = 
false;
 
  392             if (!$blAdmin && ($oView = $this->
getConfig()->getActiveView())) {
 
  393                 self::$_sCacheKey = md5($oView->getViewId()) . 
"seo";
 
  411     protected function _loadFromCache($sCacheIdent, $sType, $iLang = null, $iShopId = null, $sParams = null)
 
  413         if (!$this->
getConfig()->getConfigParam(
'blEnableSeoCache')) {
 
  417         startProfile(
"seoencoder_loadFromCache");
 
  419         $sCacheKey = $this->
_getCacheKey($sType, $iLang, $iShopId, $sParams);
 
  422         if ($sCacheKey && !isset(self::$_aCache[$sCacheKey])) {
 
  426         if (isset(self::$_aCache[$sCacheKey]) && isset(self::$_aCache[$sCacheKey][$sCacheIdent])) {
 
  427             $sCache = self::$_aCache[$sCacheKey][$sCacheIdent];
 
  430         stopProfile(
"seoencoder_loadFromCache");
 
  447     protected function _saveInCache($sCacheIdent, $sCache, $sType, $iLang = null, $iShopId = null, $sParams = null)
 
  449         if (!$this->
getConfig()->getConfigParam(
'blEnableSeoCache')) {
 
  453         startProfile(
"seoencoder_saveInCache");
 
  456         if ($sCache && ($sCacheKey = $this->
_getCacheKey($sType, $iLang, $iShopId, $sParams)) !== 
false) {
 
  457             self::$_aCache[$sCacheKey][$sCacheIdent] = $sCache;
 
  461         stopProfile(
"seoencoder_saveInCache");
 
  481     protected function _loadFromDb($sType, $sId, $iLang, $iShopId = null, $sParams = null, $blStrictParamsCheck = 
true)
 
  484         if ($iShopId === null) {
 
  485             $iShopId = $this->
getConfig()->getShopId();
 
  488         $iLang = (int) $iLang;
 
  498             WHERE `oxtype` = " . $oDb->quote($sType) . 
" 
  499                AND `oxobjectid` = " . $oDb->quote($sId) . 
" 
  500                AND `oxshopid` = " . $oDb->quote($iShopId) . 
" 
  501                AND `oxlang` = '{$iLang}'";
 
  503         $sParams = $sParams ? $sParams : 
'';
 
  504         if ($sParams && $blStrictParamsCheck) {
 
  505             $sQ .= 
" AND `oxparams` = '{$sParams}'";
 
  507             $sQ .= 
" ORDER BY `oxparams` ASC";
 
  516         if (($sSeoUrl = $this->
_loadFromCache($sIdent, $sType, $iLang, $iShopId, $sParams)) === 
false) {
 
  517             $oRs = $oDb->select($sQ);
 
  519             if ($oRs && $oRs->recordCount() > 0 && !$oRs->EOF) {
 
  521                 if ($oRs->fields[
'oxexpired'] && ($oRs->fields[
'oxtype'] == 
'static' || $oRs->fields[
'oxtype'] == 
'dynamic')) {
 
  524                     $oDb->execute(
"update oxseo set oxexpired = 0 where oxobjectid = " . $oDb->quote($sId) . 
" and oxlang = '{$iLang}'");
 
  525                     $sSeoUrl = $oRs->fields[
'oxseourl'];
 
  526                 } elseif (!$oRs->fields[
'oxexpired'] || $oRs->fields[
'oxfixed']) {
 
  528                     $sSeoUrl = $oRs->fields[
'oxseourl'];
 
  532                 $this->
_saveInCache($sIdent, $sSeoUrl, $sType, $iLang, $iShopId, $sParams);
 
  547         if (!isset(self::$_aReservedEntryKeys) || !is_array(self::$_aReservedEntryKeys)) {
 
  548             $sDir = getShopBasePath();
 
  549             self::$_aReservedEntryKeys = array_map(
'preg_quote', self::$_aReservedWords, array(
'#'));
 
  551             foreach (glob(
"$sDir/*") as $sFile) {
 
  552                 if ($oStr->preg_match(
'/^(.+)\.php[0-9]*$/i', basename($sFile), $aMatches)) {
 
  553                     self::$_aReservedEntryKeys[] = preg_quote($aMatches[0], 
'#');
 
  554                     self::$_aReservedEntryKeys[] = preg_quote($aMatches[1], 
'#');
 
  555                 } elseif (is_dir($sFile)) {
 
  556                     self::$_aReservedEntryKeys[] = preg_quote(basename($sFile), 
'#');
 
  559             self::$_aReservedEntryKeys = array_unique(self::$_aReservedEntryKeys);
 
  580         $sUri = $oStr->strip_tags($sUri);
 
  584         if ($sExt === null) {
 
  586             if ($oStr->preg_match(
'/(\.html?|\/)$/i', $sUri, $aMatched)) {
 
  587                 $sExt = $aMatched[0];
 
  592         if ($sExt && $oStr->substr($sUri, 0 - $oStr->strlen($sExt)) == $sExt) {
 
  593             $sUri = $oStr->substr($sUri, 0, $oStr->strlen($sUri) - $oStr->strlen($sExt));
 
  598         $sQuotedPrefix = preg_quote(self::$_sSeparator . self::$_sPrefix, 
'/');
 
  599         if (phpversion() < 
'5.3') {
 
  600             $sQuotedPrefix = str_replace(
'-', 
'\-', $sQuotedPrefix);
 
  602         $sRegExp = 
'/[^A-Za-z0-9' . $sQuotedPrefix . 
'\/]+/';
 
  603         $sUri = $oStr->preg_replace(array(
"/\W*\/\W*/", $sRegExp), array(
"/", self::$_sSeparator), $sUri);
 
  606         if (!$sUri && self::$_sPrefix) {
 
  607             $sUri = $this->
_prepareUri(self::$_sPrefix, $iLang);
 
  611         if (
'/' != self::$_sSeparator) {
 
  613             $sUri = trim($sUri, self::$_sSeparator);
 
  622         $sUri = $oStr->preg_replace(
"#^(/*)(" . implode(
'|', $this->
_getReservedEntryKeys()) . 
")(/|$)#i", 
"\$1\$2$sAdd\$3", $sUri);
 
  627         if (phpversion() < 
'5.3') {
 
  628             $sQuotedSeparator = str_replace(
'-', 
'\-', $sQuotedSeparator);
 
  631         return $oStr->preg_replace(
 
  632             array(
'|//+|', 
'/' . $sQuotedSeparator . $sQuotedSeparator . 
'+/'),
 
  633             array(
'/', self::$_sSeparator), $sUri
 
  647     protected function _prepareTitle($sTitle, $blSkipTruncate = 
false, $iLang = 
false)
 
  651         if (!$sSep || (
'/' == $sSep)) {
 
  655         $sRegExp = 
'/[^A-Za-z0-9\/' . preg_quote(self::$_sPrefix, 
'/') . preg_quote($sSep, 
'/') . 
']+/';
 
  656         $sTitle = preg_replace(array(
"#/+#", $sRegExp, 
"# +#", 
"#(" . preg_quote($sSep, 
'/') . 
")+#"), $sSep, $sTitle);
 
  661             $iFirstSpace = $oStr->strpos($sTitle, $sSep, $this->_iIdLength);
 
  662             if ($iFirstSpace !== 
false) {
 
  663                 $sTitle = $oStr->substr($sTitle, 0, $iFirstSpace);
 
  667         $sTitle = trim($sTitle, $sSep);
 
  694     protected function _saveToDb($sType, $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId = null, $blFixed = null, $sParams = null)
 
  697         if ($iShopId === null) {
 
  698             $iShopId = $this->
getConfig()->getShopId();
 
  701         $iLang = (int) $iLang;
 
  703         $sStdUrl = $this->
_trimUrl($sStdUrl);
 
  704         $sSeoUrl = $this->
_trimUrl($sSeoUrl);
 
  708         $sQtedObjectId = $oDb->quote($sObjectId);
 
  709         $iQtedShopId = $oDb->quote($iShopId);
 
  710         $sQtedType = $oDb->quote($sType);
 
  711         $sQtedSeoUrl = $oDb->quote($sSeoUrl);
 
  712         $sQtedStdUrl = $oDb->quote($sStdUrl);
 
  713         $sQtedParams = $oDb->quote($sParams);
 
  714         $sQtedIdent = $oDb->quote($sIdent);
 
  717         $sQ = 
"select oxfixed, oxexpired, ( oxstdurl like {$sQtedStdUrl} ) as samestdurl, 
  718                 oxseourl like {$sQtedSeoUrl} as sameseourl from oxseo where oxtype = {$sQtedType} and 
  719                 oxobjectid = {$sQtedObjectId} and oxshopid = {$iQtedShopId}  and oxlang = {$iLang} ";
 
  721         $sQ .= $sParams ? 
" and oxparams = {$sQtedParams} " : 
'';
 
  724         $oRs = $oDb->select($sQ);
 
  725         if ($oRs && $oRs->recordCount() > 0 && !$oRs->EOF) {
 
  726             if ($oRs->fields[
'samestdurl'] && $oRs->fields[
'sameseourl'] && $oRs->fields[
'oxexpired']) {
 
  728                 $sFixed = isset($blFixed) ? 
", oxfixed = " . ((int) $blFixed) . 
" " : 
'';
 
  730                 $sSql = 
"update oxseo set oxexpired = 0 {$sFixed} where oxtype = {$sQtedType} and 
  731                           oxobjectid = {$sQtedObjectId} and oxshopid = {$iQtedShopId} and oxlang = {$iLang} ";
 
  732                 $sSql .= $sParams ? 
" and oxparams = {$sQtedParams} " : 
'';
 
  735                 return $oDb->execute($sSql);
 
  736             } elseif ($oRs->fields[
'oxexpired']) {
 
  743         $sParams = $sParams ? $oDb->quote($sParams) : 
'""';
 
  744         $blFixed = (int) $blFixed;
 
  746         $sQ = 
"insert into oxseo 
  747                     (oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype, oxfixed, oxexpired, oxparams) 
  749                     ( {$sQtedObjectId}, {$sQtedIdent}, {$iQtedShopId}, {$iLang}, {$sQtedStdUrl}, {$sQtedSeoUrl}, {$sQtedType}, '$blFixed', '0', {$sParams} ) 
  750                 on duplicate key update 
  751                     oxident = {$sQtedIdent}, oxstdurl = {$sQtedStdUrl}, oxseourl = {$sQtedSeoUrl}, oxfixed = '$blFixed', oxexpired = '0'";
 
  753         return $oDb->execute($sQ);
 
  770         $sUrl = str_replace(array(
$myConfig->getShopUrl($iLang, 
false), 
$myConfig->getSslShopUrl($iLang)), 
'', $sUrl);
 
  771         $sUrl = $oStr->preg_replace(
'/(\?|&(amp;)?)(force_)?(admin_)?sid=[a-z0-9\.]+&?(amp;)?/i', 
'\1', $sUrl);
 
  772         $sUrl = $oStr->preg_replace(
'/(\?|&(amp;)?)shp=[0-9]+&?(amp;)?/i', 
'\1', $sUrl);
 
  773         $sUrl = $oStr->preg_replace(
'/(\?|&(amp;)?)lang=[0-9]+&?(amp;)?/i', 
'\1', $sUrl);
 
  774         $sUrl = $oStr->preg_replace(
'/(\?|&(amp;)?)cur=[0-9]+&?(amp;)?/i', 
'\1', $sUrl);
 
  775         $sUrl = $oStr->preg_replace(
'/(\?|&(amp;)?)stoken=[a-z0-9]+&?(amp;)?/i', 
'\1', $sUrl);
 
  776         $sUrl = $oStr->preg_replace(
'/(\?|&(amp;)?)&(amp;)?/i', 
'\1', $sUrl);
 
  777         $sUrl = $oStr->preg_replace(
'/(\?|&(amp;)?)+$/i', 
'', $sUrl);
 
  782         if ($oStr->strlen($sUrl) > $iLength) {
 
  783             $sUrl = $oStr->substr($sUrl, 0, $iLength);
 
  796         if ($this->_iMaxUrlLength === null) {
 
  798             $this->_iMaxUrlLength = $this->
getConfig()->getConfigParam(
"iMaxSeoUrlLength");
 
  799             if (!$this->_iMaxUrlLength) {
 
  800                 $this->_iMaxUrlLength = 2048;
 
  816     public function encodeString($sString, $blReplaceChars = 
true, $iLang = 
false)
 
  819         $sString = 
getStr()->html_entity_decode($sString);
 
  821         if ($blReplaceChars) {
 
  822             if ($iLang === 
false || !is_numeric($iLang)) {
 
  827                 $sString = str_replace(array_keys($aReplaceChars), array_values($aReplaceChars), $sString);
 
  833         $aReplaceWhat = array(
'&', 
'"', 
''', 
'<', 
'>');
 
  835         return str_replace($aReplaceWhat, 
'', $sString);
 
  845         self::$_sSeparator = $sSeparator;
 
  846         if (!self::$_sSeparator) {
 
  847             self::$_sSeparator = 
'-';
 
  859             self::$_sPrefix = $sPrefix;
 
  861             self::$_sPrefix = 
'oxid';
 
  872         if (isset($iIdlength)) {
 
  873             $this->_iIdLength = $iIdlength;
 
  885         self::$_aReservedWords = array_merge(self::$_aReservedWords, $aReservedWords);
 
  898     public function markAsExpired($sId, $iShopId = null, $iExpStat = 1, $iLang = null, $sParams = null)
 
  901         $sWhere = $sId ? 
"where oxobjectid =  " . $oDb->quote($sId) : 
'';
 
  902         $sWhere .= isset($iShopId) ? ($sWhere ? 
" and oxshopid = " . $oDb->quote($iShopId) : 
"where oxshopid = " . $oDb->quote($iShopId)) : 
'';
 
  903         $sWhere .= !is_null($iLang) ? ($sWhere ? 
" and oxlang = '{$iLang}'" : 
"where oxlang = '{$iLang}'") : 
'';
 
  904         $sWhere .= $sParams ? ($sWhere ? 
" and {$sParams}" : 
"where {$sParams}") : 
'';
 
  906         $sQ = 
"update oxseo set oxexpired =  " . $oDb->quote($iExpStat) . 
" $sWhere ";
 
  923     protected function _getPageUri($oObject, $sType, $sStdUrl, $sSeoUrl, $sParams, $iLang = null, $blFixed = 
false)
 
  925         if (!isset($iLang)) {
 
  926             $iLang = $oObject->getLanguage();
 
  928         $iShopId = $this->
getConfig()->getShopId();
 
  931         $sOldSeoUrl = $this->
_loadFromDb($sType, $oObject->getId(), $iLang, $iShopId, $sParams);
 
  934             $sSeoUrl = $this->
_processSeoUrl($sSeoUrl, $oObject->getId(), $iLang);
 
  935             $this->
_saveToDb($sType, $oObject->getId(), $sStdUrl, $sSeoUrl, $iLang, $iShopId, (int) $blFixed, $sParams);
 
  938             $sSeoUrl = $sOldSeoUrl;
 
  954         return md5(strtolower($iShopId . $this->
_trimUrl($sStdUrl)));
 
  970         $sOldObjectId = null;
 
  973         $sStdUrl = $this->
_trimUrl(trim($aStaticUrl[
'oxseo__oxstdurl']));
 
  974         $sObjectId = $aStaticUrl[
'oxseo__oxobjectid'];
 
  976         if (!$sObjectId || $sObjectId == 
'-1') {
 
  980             $sOldObjectId = $sObjectId;
 
  988         foreach ($aStaticUrl[
'oxseo__oxseourl'] as $iLang => $sSeoUrl) {
 
  990             $iLang = (int) $iLang;
 
  993             $sSeoUrl = $this->
_trimUrl($sSeoUrl);
 
 1001                 if (!$oDb->getOne(
"select (" . $oDb->quote($sSeoUrl) . 
" like oxseourl) & (" . $oDb->quote($sStdUrl) . 
" like oxstdurl) from oxseo where oxobjectid = " . $oDb->quote($sOldObjectId) . 
" and oxshopid = '{$iShopId}' and oxlang = '{$iLang}' ", 
false, 
false)) {
 
 1002                     $this->
_copyToHistory($sOldObjectId, $iShopId, $iLang, 
'static', $sObjectId);
 
 1006             if (!$sSeoUrl || !$sStdUrl) {
 
 1016             $sValues .= 
"( " . $oDb->quote($sObjectId) . 
", " . $oDb->quote($sIdent) . 
", " . $oDb->quote($iShopId) . 
", '{$iLang}', " . $oDb->quote($sStdUrl) . 
", " . $oDb->quote($sSeoUrl) . 
", 'static' )";
 
 1020         if ($sOldObjectId) {
 
 1021             $oDb->execute(
"delete from oxseo where oxobjectid in ( " . $oDb->quote($sOldObjectId) . 
", " . $oDb->quote($sObjectId) . 
" )");
 
 1027             $sQ = 
"insert into oxseo ( oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype ) values {$sValues} ";
 
 1041         $iBaseShopId = $this->
getConfig()->getBaseShopId();
 
 1042         if ($iShopId != $iBaseShopId) {
 
 1045                 $sQ = 
"insert into oxseo ( oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype ) 
 1046                        select MD5( LOWER( CONCAT( " . $oDb->quote($iShopId) . 
", oxstdurl ) ) ), MD5( LOWER( oxseourl ) ), 
 1047                        " . $oDb->quote($iShopId) . 
", oxlang, oxstdurl, oxseourl, oxtype from oxseo where oxshopid = '{$iBaseShopId}' and oxtype = 'static' and oxlang='$iLang' ";
 
 1064         if (!isset($iShopId)) {
 
 1065             $iShopId = $this->
getConfig()->getShopId();
 
 1067         if (!isset($iLang)) {
 
 1071         if (isset($this->_aStaticUrlCache[$sStdUrl][$iLang][$iShopId])) {
 
 1072             return $this->_aStaticUrlCache[$sStdUrl][$iLang][$iShopId];
 
 1076         if (($sSeoUrl = $this->
_getStaticUri($sStdUrl, $iShopId, $iLang))) {
 
 1077             $sFullUrl = $this->
_getFullUrl($sSeoUrl, $iLang, strpos($sStdUrl, 
"https:") === 0);
 
 1081         $this->_aStaticUrlCache[$sStdUrl][$iLang][$iShopId] = $sFullUrl;
 
 1102     public function addSeoEntry($sObjectId, $iShopId, $iLang, $sStdUrl, $sSeoUrl, $sType, $blFixed = 1, $sKeywords = 
'', $sDescription = 
'', $sParams = 
'', $blExclude = 
false, $sAltObjectId = null)
 
 1104         $sSeoUrl = $this->
_processSeoUrl($this->
_trimUrl($sSeoUrl ? $sSeoUrl : $this->
_getAltUri($sAltObjectId ? $sAltObjectId : $sObjectId, $iLang)), $sObjectId, $iLang, $blExclude);
 
 1105         if ($this->
_saveToDb($sType, $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId, $blFixed, $sParams)) {
 
 1110             $sQtedObjectId = $oDb->quote($sAltObjectId ? $sAltObjectId : $sObjectId);
 
 1111             $iQtedShopId = $oDb->quote($iShopId);
 
 1114             if ($sKeywords !== 
false) {
 
 1115                 $sKeywords = $oDb->quote($oStr->htmlspecialchars($this->encodeString($oStr->strip_tags($sKeywords), 
false, $iLang)));
 
 1118             if ($sDescription !== 
false) {
 
 1119                 $sDescription = $oDb->quote($oStr->htmlspecialchars($oStr->strip_tags($sDescription)));
 
 1122             $sQ = 
"insert into oxobject2seodata 
 1123                        ( oxobjectid, oxshopid, oxlang, oxkeywords, oxdescription ) 
 1125                        ( {$sQtedObjectId}, {$iQtedShopId}, {$iLang}, " . ($sKeywords ? $sKeywords : 
"''") . 
", " . ($sDescription ? $sDescription : 
"''") . 
" ) 
 1126                    on duplicate key update 
 1127                        oxkeywords = " . ($sKeywords ? $sKeywords : 
"oxkeywords") . 
", oxdescription = " . ($sDescription ? $sDescription : 
"oxdescription");
 
 1153         $sQ = 
"delete from oxseo where oxobjectid = " . $oDb->quote($sObjectId) . 
" and oxshopid = " . $oDb->quote($iShopId) . 
" and oxlang = " . $oDb->quote($iLang) . 
" and oxtype = " . $oDb->quote($sType) . 
" ";
 
 1167     public function getMetaData($sObjectId, $sMetaType, $iShopId = null, $iLang = null)
 
 1171         $iShopId = (!isset($iShopId)) ? $this->
getConfig()->getShopId() : $iShopId;
 
 1172         $iLang = (!isset($iLang)) ? 
oxRegistry::getLang()->getObjectTplLanguage() : ((int) $iLang);
 
 1174         return $oDb->getOne(
"select {$sMetaType} from oxobject2seodata where oxobjectid = " . $oDb->quote($sObjectId) . 
" and oxshopid = " . $oDb->quote($iShopId) . 
" and oxlang = '{$iLang}'");
 
 1192         startProfile(
"getDynamicUrl");
 
 1193         $sDynUrl = $this->
_getFullUrl($this->
_getDynamicUri($sStdUrl, $sSeoUrl, $iLang), $iLang, strpos($sStdUrl, 
"https:") === 0);
 
 1194         stopProfile(
"getDynamicUrl");
 
 1210         $iLanguage = isset($iLanguage) ? ((int) $iLanguage) : 
oxRegistry::getLang()->getBaseLanguage();
 
 1213         $sShopId = $this->
getConfig()->getShopId();
 
 1215         $sQ = 
"SELECT `oxseourl`, `oxlang` FROM `oxseo` WHERE `oxstdurl` = " . $oDb->quote($sStdUrl) . 
" AND `oxlang` = '$iLanguage' AND `oxshopid` = '$sShopId' LIMIT 1";
 
 1218         $oRs = $oDb->select($sQ);
 
 1221             $sSeoUrl = $oRs->fields[
'oxseourl'];