00001 <?php
00002
00007 class oxSeoEncoder extends oxSuperCfg
00008 {
00015 protected static $_aReservedWords = array( 'admin' );
00016
00022 protected static $_aReservedEntryKeys = null;
00023
00029 protected static $_sSeparator = null;
00030
00036 protected $_iIdLength = 255;
00037
00043 protected static $_sPrefix = null;
00044
00050 protected $_sAddParams = null;
00051
00057 protected static $_instance = null;
00058
00064 protected $_aSeoCache = array();
00065
00071 public static function getInstance()
00072 {
00073 if (!self::$_instance) {
00074 self::$_instance = oxNew("oxSeoEncoder");
00075 }
00076
00077 if ( defined( 'OXID_PHP_UNIT' ) ) {
00078
00079 self::$_instance->_aSeoCache = array();
00080 }
00081
00082 return self::$_instance;
00083 }
00084
00093 public function addLanguageParam( $sSeoUrl, $iLang )
00094 {
00095 $iLang = (int) $iLang;
00096 $iDefLang = (int) $this->getConfig()->getConfigParam( 'iDefSeoLang' );
00097 $aLangIds = oxLang::getInstance()->getLanguageIds();
00098
00099 if ( $iLang != $iDefLang && isset( $aLangIds[$iLang] ) && getStr()->strpos( $sSeoUrl, $aLangIds[$iLang] . '/' ) !== 0 ) {
00100 $sSeoUrl = $aLangIds[$iLang] . '/'.$sSeoUrl;
00101 }
00102
00103 return $sSeoUrl;
00104 }
00105
00118 protected function _processSeoUrl( $sSeoUrl, $sObjectId = null, $iLang = null, $blExclude = false )
00119 {
00120 return $this->_getUniqueSeoUrl( $blExclude ? $sSeoUrl : $this->addLanguageParam( $sSeoUrl, $iLang ), $sObjectId, $iLang );
00121 }
00122
00128 public function resetCache()
00129 {
00130 $this->_aSeoCache = array();
00131 }
00132
00136 public function __construct()
00137 {
00138 $myConfig = $this->getConfig();
00139 if (!self::$_sSeparator) {
00140 $this->setSeparator( $myConfig->getConfigParam( 'sSEOSeparator' ) );
00141 }
00142 if (!self::$_sPrefix) {
00143 $this->setPrefix( $myConfig->getConfigParam( 'sSEOuprefix' ) );
00144 }
00145 $this->setReservedWords( $myConfig->getConfigParam( 'aSEOReservedWords' ) );
00146 }
00147
00159 protected function _copyToHistory( $sId, $iShopId, $iLang, $sType = null, $sNewId = null )
00160 {
00161 $oDb = oxDb::getDb();
00162 $sObjectid = $sNewId?$oDb->quote( $sNewId ):'oxobjectid';
00163 $sType = $sType?"oxtype =".$oDb->quote( $sType )." and":'';
00164 $iLang = (int) $iLang;
00165
00166
00167 $sSub = "select $sObjectid, MD5( LOWER( oxseourl ) ), oxshopid, oxlang, now() from oxseo
00168 where {$sType} oxobjectid = ".$oDb->quote( $sId )." and oxshopid = ".$oDb->quote( $iShopId )." and
00169 oxlang = {$iLang} limit 1";
00170 $sQ = "replace oxseohistory ( oxobjectid, oxident, oxshopid, oxlang, oxinsert ) {$sSub}";
00171 $oDb->execute( $sQ );
00172 }
00173
00180 protected function _getAddParams()
00181 {
00182
00183 if ( $this->_sAddParams === null ) {
00184 $this->_sAddParams = $this->_getAddParamsFnc( oxConfig::getParameter('currency'), $this->getConfig()->getShopId() );
00185 }
00186 return $this->_sAddParams;
00187 }
00188
00198 protected function _getAddParamsFnc( $iCur, $iActShop )
00199 {
00200
00201 $this->_sAddParams = '';
00202 $sSep = '?';
00203 if ( $iCur ) {
00204 $this->_sAddParams .= $sSep . 'cur=' . $iCur;
00205 $sSep = '&';
00206 }
00207
00208
00209 return $this->_sAddParams;
00210 }
00211
00222 protected function _getDynamicObjectId( $iShopId, $sStdUrl )
00223 {
00224 return $this->getDynamicObjectId( $iShopId, $sStdUrl );
00225 }
00226
00235 public function getDynamicObjectId( $iShopId, $sStdUrl )
00236 {
00237 return $this->_getStaticObjectId( $iShopId, $sStdUrl );
00238 }
00239
00249 protected function _getDynamicUri( $sStdUrl, $sSeoUrl, $iLang )
00250 {
00251 $iShopId = $this->getConfig()->getShopId();
00252
00253 $sStdUrl = $this->_trimUrl( $sStdUrl );
00254 $sObjectId = $this->getDynamicObjectId( $iShopId, $sStdUrl );
00255 $sSeoUrl = $this->_prepareUri( $sSeoUrl );
00256
00257
00258 $sOldSeoUrl = $this->_loadFromDb( 'dynamic', $sObjectId, $iLang );
00259 if ( $sOldSeoUrl === $sSeoUrl ) {
00260 $sSeoUrl = $sOldSeoUrl;
00261 } else {
00262
00263 if ( $sOldSeoUrl ) {
00264 $this->_copyToHistory( $sObjectId, $iShopId, $iLang, 'dynamic' );
00265 }
00266
00267
00268 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl, $sObjectId, $iLang );
00269
00270
00271 $this->_saveToDb( 'dynamic', $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId );
00272 }
00273
00274 return $sSeoUrl;
00275 }
00276
00285 protected function _getFullUrl( $sSeoUrl, $iLang = null)
00286 {
00287 $sFullUrl = $this->getConfig()->getShopUrl( $iLang ) . $sSeoUrl . $this->_getAddParams();
00288 return $this->getSession()->processUrl( $sFullUrl );
00289 }
00290
00301 protected function _getSeoIdent( $sSeoUrl, $iLang = null )
00302 {
00303 return md5( strtolower( $sSeoUrl ) );
00304 }
00305
00315 protected function _getStaticUri( $sStdUrl, $iShopId, $iLang )
00316 {
00317 $sStdUrl = $this->_trimUrl( $sStdUrl, $iLang );
00318 return $this->_loadFromDb( 'static', $this->_getStaticObjectId( $iShopId, $sStdUrl ), $iLang );
00319 }
00320
00326 protected function _getUrlExtension()
00327 {
00328 return;
00329 }
00330
00343 protected function _getUniqueSeoUrl( $sSeoUrl, $sObjectId = null, $iObjectLang = null )
00344 {
00345 $oStr = getStr();
00346 $sConstEnd = $this->_getUrlExtension();
00347 if ($sConstEnd === null) {
00348 $aMatched = array();
00349 if ( preg_match('/\.html?$/i', $sSeoUrl, $aMatched ) ) {
00350 $sConstEnd = $aMatched[0];
00351 } else {
00352 if ($sSeoUrl{$oStr->strlen($sSeoUrl)-1} != '/') {
00353 $sSeoUrl .= '/';
00354 }
00355 $sConstEnd = '/';
00356 }
00357 }
00358
00359
00360 $sAdd = ' ';
00361 if ('/' != self::$_sSeparator) {
00362 $sAdd = self::$_sSeparator . self::$_sPrefix;
00363 } else {
00364 $sAdd = '_' . self::$_sPrefix;
00365 }
00366 $sSeoUrl = preg_replace( "#^(/*)(".implode('|', $this->_getReservedEntryKeys()).")/#i", "\$1\$2$sAdd/", $sSeoUrl );
00367
00368 $sBaseSeoUrl = $sSeoUrl;
00369 if ( $sConstEnd && $oStr->substr( $sSeoUrl, 0 - $oStr->strlen( $sConstEnd ) ) == $sConstEnd ) {
00370 $sBaseSeoUrl = $oStr->substr( $sSeoUrl, 0, $oStr->strlen( $sSeoUrl ) - $oStr->strlen( $sConstEnd ) );
00371 }
00372
00373 $oDb = oxDb::getDb();
00374 $iShopId = $this->getConfig()->getShopId();
00375 $iCnt = 0;
00376 $sCheckSeoUrl = $this->_trimUrl( $sSeoUrl );
00377 $sQ = "select 1 from oxseo where oxshopid = '{$iShopId}'";
00378
00379
00380 if ( $sObjectId && isset($iObjectLang) ) {
00381 $iObjectLang = (int) $iObjectLang;
00382 $sQ .= " and not (oxobjectid = " . $oDb->quote( $sObjectId ) . " and oxlang = $iObjectLang)";
00383 }
00384
00385 while ( $oDb->getOne( $sQ ." and oxident= " . $oDb->quote( $this->_getSeoIdent( $sCheckSeoUrl ) ) ) ) {
00386 $sAdd = '';
00387 if ( self::$_sPrefix ) {
00388 $sAdd = self::$_sSeparator . self::$_sPrefix;
00389 }
00390 if ( $iCnt ) {
00391 $sAdd .= self::$_sSeparator . $iCnt;
00392 }
00393 ++$iCnt;
00394
00395 $sSeoUrl = $sBaseSeoUrl . $sAdd . $sConstEnd;
00396 $sCheckSeoUrl = $this->_trimUrl( $sSeoUrl );
00397 }
00398 return $sSeoUrl;
00399 }
00400
00415 protected function _isFixed( $sType, $sId, $iLang, $iShopId = null, $sParams = null, $blStrictParamsCheck = true)
00416 {
00417 $oDb = oxDb::getDb( true );
00418 if ( $iShopId === null ) {
00419 $iShopId = $this->getConfig()->getShopId();
00420 }
00421
00422 $iLang = (int) $iLang;
00423
00424 $sQ = "select oxfixed from oxseo where oxtype = ".$oDb->quote( $sType )."
00425 and oxobjectid = ".$oDb->quote( $sId ) ." and oxshopid = ".$oDb->quote( $iShopId )." and oxlang = '{$iLang}'";
00426
00427 $sParams = $sParams ? $sParams : '';
00428 if ( $sParams && $blStrictParamsCheck ) {
00429 $sQ .= " and oxparams = '{$sParams}'";
00430 } else {
00431 $sQ .= " order by oxparams = '{$sParams}' desc";
00432 }
00433 $sQ .= " limit 1";
00434
00435 return (bool) $oDb->getOne( $sQ );
00436 }
00437
00453 protected function _loadFromDb( $sType, $sId, $iLang, $iShopId = null, $sParams = null, $blStrictParamsCheck = true)
00454 {
00455 $oDb = oxDb::getDb( true );
00456 if ( $iShopId === null ) {
00457 $iShopId = $this->getConfig()->getShopId();
00458 }
00459
00460 $iLang = (int) $iLang;
00461
00462 $sQ = "select oxfixed, oxseourl, oxexpired, oxtype from oxseo where oxtype = ".$oDb->quote( $sType )."
00463 and oxobjectid = ".$oDb->quote( $sId ) ." and oxshopid = ".$oDb->quote( $iShopId )." and oxlang = '{$iLang}'";
00464
00465 $sParams = $sParams ? $sParams : '';
00466 if ( $sParams && $blStrictParamsCheck ) {
00467 $sQ .= " and oxparams = '{$sParams}'";
00468 } else {
00469 $sQ .= " order by oxparams = '{$sParams}' desc";
00470 }
00471 $sQ .= " limit 1";
00472
00473
00474 $sIdent = md5($sQ);
00475 if ( isset( $this->_aSeoCache[$sIdent] ) ) {
00476 return $this->_aSeoCache[$sIdent];
00477 }
00478
00479 $sSeoUrl = false;
00480 $oRs = $oDb->execute( $sQ );
00481 if ( $oRs && $oRs->recordCount() > 0 && !$oRs->EOF ) {
00482
00483 if ( $oRs->fields['oxexpired'] && ( $oRs->fields['oxtype'] == 'static' || $oRs->fields['oxtype'] == 'dynamic' ) ) {
00484
00485 $this->_copyToHistory( $sId, $iShopId, $iLang );
00486 $oDb->execute( "update oxseo set oxexpired = 0 where oxobjectid = ".$oDb->quote( $sId )." and oxlang = '{$iLang}'" );
00487 $sSeoUrl = $oRs->fields['oxseourl'];
00488 } elseif ( !$oRs->fields['oxexpired'] || $oRs->fields['oxfixed'] ) {
00489
00490 $sSeoUrl = $oRs->fields['oxseourl'];
00491 }
00492
00493
00494 $this->_aSeoCache[$sIdent] = $sSeoUrl;
00495 }
00496 return $sSeoUrl;
00497 }
00498
00505 protected function _getReservedEntryKeys()
00506 {
00507 if (!isset(self::$_aReservedEntryKeys) && !is_array(self::$_aReservedEntryKeys)) {
00508 $sDir = getShopBasePath();
00509 self::$_aReservedEntryKeys = array();
00510 foreach (glob("$sDir/*") as $file) {
00511 if (preg_match('/^(.+)\.php[0-9]*$/i', basename($file), $m)) {
00512 self::$_aReservedEntryKeys[] = $m[0];
00513 self::$_aReservedEntryKeys[] = $m[1];
00514 } elseif (is_dir($file)) {
00515 self::$_aReservedEntryKeys[] = basename($file);
00516 }
00517 }
00518 }
00519 return self::$_aReservedEntryKeys;
00520 }
00521
00529 protected function _prepareUri( $sUri )
00530 {
00531
00532 $sUri = $this->encodeString( $sUri );
00533
00534
00535 $sUri = strip_tags( $sUri );
00536
00537 $sSeparator = self::$_sSeparator;
00538 $sPrefix = self::$_sPrefix;
00539
00540 foreach ( self::$_aReservedWords as $sWord ) {
00541
00542 $sUri = preg_replace( array( "/(\s$sWord)$/i", "/^($sWord\s)/i", "/(\s$sWord\s)/i", "/^($sWord)$/i",
00543 "/(\/$sWord)$/i", "/^($sWord\/)/i", "/(\/$sWord\/)/i"),
00544 " $1{$sSeparator}{$sPrefix}{$sSeparator} ", $sUri );
00545 }
00546
00547
00548 $sExt = '';
00549 $oStr = getStr();
00550 $aMatched = array();
00551 if ( preg_match( '/\.html?$/i', $sUri, $aMatched ) ) {
00552 $sExt = $oStr->substr( $sUri, 0 - $oStr->strlen( $aMatched[0] ) );
00553 $sUri = $oStr->substr( $sUri, 0, $oStr->strlen( $sUri ) - $oStr->strlen( $aMatched[0] ) );
00554 }
00555
00556
00557 $sRegExp = '/[^A-Za-z0-9'.preg_quote( self::$_sSeparator, '/').'\/]+/';
00558 $sUri = trim( $oStr->preg_replace( array( "/\W*\/\W*/", $sRegExp ), array( "/", self::$_sSeparator ), $sUri ), self::$_sSeparator );
00559
00560
00561 if ( !$sUri ) {
00562 $sUri = $this->_prepareUri( self::$_sPrefix );
00563 }
00564
00565
00566 $sUri .= $sExt;
00567
00568
00569 return $oStr->preg_replace( array( '|//+|', '/' . preg_quote( self::$_sSeparator . self::$_sSeparator, '/' ) .'+/' ),
00570 array( '/', self::$_sSeparator ), $sUri );
00571 }
00572
00581 protected function _prepareTitle( $sTitle, $blSkipTruncate = false )
00582 {
00583 $sTitle = $this->_prepareUri( str_replace( "/", self::$_sSeparator, $sTitle ) );
00584
00585 $oStr = getStr();
00586
00587 if ( !$blSkipTruncate && $oStr->strlen( $sTitle ) > $this->_iIdLength ) {
00588 if ( ( $iFirstSpace = $oStr->strstr( $oStr->substr( $sTitle, $this->_iIdLength ), self::$_sSeparator ) !== false ) ) {
00589 $sTitle = trim( $oStr->substr( $sTitle, 0, $this->_iIdLength + $iFirstSpace ), self::$_sSeparator );
00590 }
00591 }
00592
00593
00594 return $sTitle;
00595 }
00596
00597
00616 protected function _saveToDb( $sType, $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId = null, $blFixed = null, $sKeywords = false, $sDescription = false, $sParams = null )
00617 {
00618 $oDb = oxDb::getDb( true );
00619 if ( $iShopId === null ) {
00620 $iShopId = $this->getConfig()->getShopId();
00621 }
00622
00623 $iLang = (int) $iLang;
00624
00625 $sStdUrl = $this->_trimUrl( $sStdUrl );
00626 $sSeoUrl = $this->_trimUrl( $sSeoUrl );
00627 $sIdent = $this->_getSeoIdent( $sSeoUrl );
00628
00629
00630 $sQ = "select oxfixed, oxexpired, ( oxstdurl like ".$oDb->quote( $sStdUrl )." ) as samestdurl,
00631 oxseourl like ".$oDb->quote( $sSeoUrl )." as sameseourl from oxseo where oxtype = ".$oDb->quote( $sType )." and
00632 oxobjectid = ".$oDb->quote( $sObjectId )." and oxshopid = ".$oDb->quote( $iShopId )." and oxlang = {$iLang} ";
00633
00634 $sQ .= $sParams ? " and oxparams = " . $oDb->quote( $sParams ) : '';
00635 $sQ .= ( $sKeywords !== false ) ? " and oxkeywords = " . $oDb->quote( $sKeywords ) . " " : '';
00636 $sQ .= ( $sDescription !== false ) ? " and oxdescription = " . $oDb->quote( $sDescription ) . " " : '';
00637
00638 $sQ .= "limit 1";
00639
00640 $oRs = $oDb->execute( $sQ );
00641 if ( $oRs && $oRs->recordCount() > 0 && !$oRs->EOF ) {
00642 if ( $oRs->fields['samestdurl'] && $oRs->fields['sameseourl'] && $oRs->fields['oxexpired'] ) {
00643
00644 $sFixed = isset( $blFixed ) ? ", oxfixed = " . ( (int) $blFixed ) . " " : '';
00645
00646 $sSql = "update oxseo set oxexpired = 0 {$sFixed} where oxtype = ".$oDb->quote( $sType )." and
00647 oxobjectid = ".$oDb->quote( $sObjectId )." and oxshopid = ".$oDb->quote( $iShopId ) ." and oxlang = {$iLang} ";
00648 $sSql .= $sParams ? " and oxparams = " . $oDb->quote( $sParams ) : '';
00649 $sSql .= " limit 1";
00650
00651 return $oDb->execute( $sSql );
00652 } elseif ( $oRs->fields['oxexpired'] ) {
00653
00654 $this->_copyToHistory( $sObjectId, $iShopId, $iLang, $sType );
00655 }
00656 }
00657 $oStr = getStr();
00658 if ( $sKeywords !== false ) {
00659 $sKeywords = $oDb->quote( $oStr->htmlspecialchars( $this->encodeString( strip_tags( $sKeywords ), false ) ) );
00660 }
00661
00662 if ( $sDescription !== false ) {
00663 $sDescription = $oDb->quote( $oStr->htmlspecialchars( strip_tags( $sDescription ) ) );
00664 }
00665
00666
00667 $sParams = $sParams ? $oDb->quote( $sParams ) :'""';
00668 $blFixed = (int) $blFixed;
00669
00670 $sQ = "insert into oxseo
00671 (oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype, oxfixed, oxexpired, oxkeywords, oxdescription, oxparams)
00672 values
00673 ( ".$oDb->quote( $sObjectId ).", ".$oDb->quote( $sIdent ).", ".$oDb->quote( $iShopId ).", {$iLang}, ".$oDb->quote( $sStdUrl ).", ".$oDb->quote( $sSeoUrl ).", ".$oDb->quote( $sType ).", '$blFixed', '0',
00674 ".( $sKeywords ? $sKeywords : "''" ).", ".( $sDescription ? $sDescription : "''" ).", $sParams )
00675 on duplicate key update oxident = ".$oDb->quote( $sIdent ).", oxstdurl = ".$oDb->quote( $sStdUrl ).", oxseourl = ".$oDb->quote( $sSeoUrl ).", oxfixed = '$blFixed', oxexpired = '0',
00676 oxkeywords = ".( $sKeywords ? $sKeywords : "oxkeywords" ).", oxdescription = ".( $sDescription ? $sDescription : "oxdescription" );
00677
00678 return $oDb->execute( $sQ );
00679 }
00680
00691 protected function _trimUrl( $sUrl, $iLang = null )
00692 {
00693 $sUrl = str_replace( $this->getConfig()->getShopURL( $iLang ), '', $sUrl );
00694 return preg_replace( '/(force_)?sid=[a-z0-9\.]+&?(amp;)?/i', '', $sUrl );
00695 }
00696
00705 public function encodeString( $sString, $blReplaceChars = true )
00706 {
00707
00708 $sString = getStr()->html_entity_decode( $sString );
00709
00710 if ( $blReplaceChars ) {
00711 $aReplaceChars = $this->getConfig()->getConfigParam( 'aSeoReplaceChars' );
00712 $sString = str_replace( array_keys( $aReplaceChars ), array_values( $aReplaceChars ), $sString );
00713 }
00714
00715
00716 $aReplaceWhat = array( '&', '"', ''', '<', '>' );
00717 return str_replace( $aReplaceWhat, '', $sString );
00718 }
00719
00727 public function setSeparator( $sSeparator = null )
00728 {
00729 self::$_sSeparator = $sSeparator;
00730 if ( !self::$_sSeparator ) {
00731 self::$_sSeparator = '-';
00732 }
00733 }
00734
00742 public function setPrefix( $sPrefix )
00743 {
00744 if ($sPrefix) {
00745 self::$_sPrefix = $sPrefix;
00746 } else {
00747 self::$_sPrefix = 'oxid';
00748 }
00749 }
00750
00758 public function setIdLength( $iIdlength = null )
00759 {
00760 if ( isset( $iIdlength ) ) {
00761 $this->_iIdLength = $iIdlength;
00762 }
00763 }
00764
00772 public function setReservedWords( $aReservedWords )
00773 {
00774 self::$_aReservedWords = array_merge( self::$_aReservedWords, $aReservedWords );
00775 }
00776
00777
00789 public function markAsExpired( $sId, $iShopId = null, $iExpStat = 1, $iLang = null, $sParams = null )
00790 {
00791 $oDb = oxDb::getDb();
00792 $sWhere = $sId ? "where oxobjectid = " . $oDb->quote( $sId ) : '';
00793 $sWhere .= isset( $iShopId ) ? ( $sWhere ? " and oxshopid = ". $oDb->quote( $iShopId ) : "where oxshopid = ". $oDb->quote( $iShopId ) ) : '';
00794 $sWhere .= $iLang ? ( $sWhere ? " and oxlang = '{$iLang}'" : "where oxlang = '{$iLang}'" ) : '';
00795 $sWhere .= $sParams ? ( $sWhere ? " and {$sParams}" : "where {$sParams}" ) : '';
00796
00797 $sQ = "update oxseo set oxexpired = " . $oDb->quote( $iExpStat ) . " $sWhere ";
00798 $oDb->execute( $sQ );
00799 }
00800
00814 protected function _getPageUri( $oObject, $sType, $sStdUrl, $sSeoUrl, $sParams, $iLang = null, $blFixed = false )
00815 {
00816 if (!isset($iLang)) {
00817 $iLang = $oObject->getLanguage();
00818 }
00819 $iShopId = $this->getConfig()->getShopId();
00820
00821
00822 if ( ( $sOldSeoUrl = $this->_loadFromDb( $sType, $oObject->getId(), $iLang, $iShopId, $sParams ) ) ) {
00823 if ( $sOldSeoUrl === $sSeoUrl ) {
00824 return $sSeoUrl;
00825 } else {
00826 $this->_copyToHistory( $oObject->getId(), $iShopId, $iLang, $sType );
00827 }
00828 }
00829
00830 $this->_saveToDb( $sType, $oObject->getId(), $sStdUrl, $sSeoUrl, $iLang, $iShopId, (int) $blFixed, false, false, $sParams );
00831
00832 return $sSeoUrl;
00833 }
00834
00843 protected function _getStaticObjectId( $iShopId, $sStdUrl )
00844 {
00845 return md5( strtolower ( $iShopId . $this->_trimUrl( $sStdUrl ) ) );
00846 }
00847
00857 public function encodeStaticUrls( $aStaticUrl, $iShopId, $iLang )
00858 {
00859 $oDb = oxDb::getDb();
00860 $sValues = '';
00861 $sOldObjectId = null;
00862
00863
00864 $sStdUrl = $this->_trimUrl( trim( $aStaticUrl['oxseo__oxstdurl'] ) );
00865 $sObjectId = $aStaticUrl['oxseo__oxobjectid'];
00866
00867 if ( !$sObjectId || $sObjectId == '-1' ) {
00868 $sObjectId = $this->_getStaticObjectId( $iShopId, $sStdUrl );
00869 } else {
00870
00871 $sOldObjectId = $sObjectId;
00872
00873
00874 if ( $this->_getStaticObjectId( $iShopId, $sStdUrl ) != $sObjectId ) {
00875 $sObjectId = $this->_getStaticObjectId( $iShopId, $sStdUrl );
00876 }
00877 }
00878
00879 foreach ( $aStaticUrl['oxseo__oxseourl'] as $iLang => $sSeoUrl ) {
00880
00881 $iLang = (int) $iLang;
00882
00883
00884 if ( ( $sSeoUrl = trim( $sSeoUrl ) ) ) {
00885 $sSeoUrl = $this->_prepareUri( $this->_trimUrl( $sSeoUrl ) );
00886 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl, $sObjectId, $iLang );
00887 }
00888
00889
00890 if ( $sOldObjectId ) {
00891
00892 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}' " ) ) {
00893 $this->_copyToHistory( $sOldObjectId, $iShopId, $iLang, 'static', $sObjectId );
00894 }
00895 }
00896
00897 if ( !$sSeoUrl || !$sStdUrl ) {
00898 continue;
00899 }
00900
00901 $sIdent = $this->_getSeoIdent( $sSeoUrl );
00902
00903 if ( $sValues ) {
00904 $sValues .= ', ';
00905 }
00906
00907 $sValues .= "( " . $oDb->quote( $sObjectId ) . ", " . $oDb->quote( $sIdent ) . ", " . $oDb->quote( $iShopId ).", '{$iLang}', " . $oDb->quote( $sStdUrl ) . ", " . $oDb->quote( $sSeoUrl ) . ", 'static' )";
00908 }
00909
00910
00911 if ( $sOldObjectId ) {
00912 $oDb->execute( "delete from oxseo where oxobjectid in ( " . $oDb->quote( $sOldObjectId ) . ", " . $oDb->quote( $sObjectId ) . " )" );
00913 }
00914
00915
00916 if ( $sValues ) {
00917
00918 $sQ = "insert into oxseo ( oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype ) values {$sValues} ";
00919 $oDb->execute( $sQ );
00920 }
00921
00922 return $sObjectId;
00923 }
00924
00932 public function copyStaticUrls( $iShopId )
00933 {
00934 $iBaseShopId = $this->getConfig()->getBaseShopId();
00935 if ( $iShopId != $iBaseShopId ) {
00936 $oDb = oxDb::getDb();
00937 foreach (array_keys(oxLang::getInstance()->getLanguageIds()) as $iLang) {
00938 $sQ = "insert into oxseo ( oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype )
00939 select MD5( LOWER( CONCAT( " . $oDb->quote( $iShopId ) . ", oxstdurl ) ) ), MD5( LOWER( oxseourl ) ),
00940 " . $oDb->quote( $iShopId ) . ", oxlang, oxstdurl, oxseourl, oxtype from oxseo where oxshopid = '{$iBaseShopId}' and oxtype = 'static' and oxlang='$iLang' ";
00941 $oDb->execute( $sQ );
00942 }
00943 }
00944 }
00945
00955 public function getStaticUrl( $sStdUrl, $iLang = null, $iShopId = null )
00956 {
00957 if (!isset($iShopId)) {
00958 $iShopId = $this->getConfig()->getShopId();
00959 }
00960 if (!isset($iLang)) {
00961 $iLang = oxLang::getInstance()->getEditLanguage();
00962 }
00963
00964 $sFullUrl = '';
00965 if ( ( $sSeoUrl = $this->_getStaticUri( $sStdUrl, $iShopId, $iLang ) ) ) {
00966 $sFullUrl = $this->_getFullUrl( $sSeoUrl, $iLang );
00967 }
00968 return $sFullUrl;
00969 }
00970
00988 public function addSeoEntry( $sObjectId, $iShopId, $iLang, $sStdUrl, $sSeoUrl, $sType, $blFixed = 1, $sKeywords = '', $sDescription = '', $sParams = '', $blExclude = false )
00989 {
00990 $sSeoUrl = $this->_processSeoUrl( $this->_prepareUri( $this->_trimUrl( $sSeoUrl ) ), $sObjectId, $iLang, $blExclude );
00991 $this->_saveToDb( $sType, $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId, $blFixed, $sKeywords, $sDescription, $sParams );
00992 }
00993
01004 public function deleteSeoEntry( $sObjectId, $iShopId, $iLang, $sType )
01005 {
01006 $oDb = oxDb::getDb();
01007 $sQ = "delete from oxseo where oxobjectid = " . $oDb->quote( $sObjectId ) . " and oxshopid = " . $oDb->quote( $iShopId ) . " and oxlang = " . $oDb->quote( $iLang ) . " and oxtype = " . $oDb->quote( $sType ) . " ";
01008 oxDb::getDb()->execute( $sQ );
01009 }
01010
01021 public function getMetaData( $sObjectId, $sMetaType, $iShopId = null, $iLang = null )
01022 {
01023 $iShopId = ( !isset( $iShopId ) ) ? $this->getConfig()->getShopId():$iShopId;
01024 $iLang = ( !isset( $iLang ) ) ? oxLang::getInstance()->getTplLanguage():((int)$iLang);
01025
01026 $oDb = oxDb::getDb();
01027 return $oDb->getOne( "select {$sMetaType} from oxseo where oxobjectid = " . $oDb->quote( $sObjectId ) . " and oxshopid = " . $oDb->quote( $iShopId )." and oxlang = '{$iLang}' order by oxparams" );
01028 }
01029
01043 public function getDynamicUrl( $sStdUrl, $sSeoUrl, $iLang )
01044 {
01045 return $this->_getFullUrl( $this->_getDynamicUri( $sStdUrl, $sSeoUrl, $iLang ) );
01046 }
01047
01056 public function fetchSeoUrl( $sStdUrl, $iLanguage = null )
01057 {
01058 $oDb = oxDb::getDb( true );
01059 $iLanguage = isset( $iLanguage ) ? ( (int) $iLanguage ) : oxLang::getInstance()->getBaseLanguage();
01060 $sSeoUrl = false;
01061
01062 $sQ = "select oxseourl, oxlang from oxseo where oxstdurl = ".$oDb->quote( $sStdUrl )." and oxlang = '$iLanguage' limit 1";
01063 $oRs = $oDb->execute( $sQ );
01064 if ( !$oRs->EOF ) {
01065 $sSeoUrl = $oRs->fields['oxseourl'];
01066 }
01067
01068 return $sSeoUrl;
01069 }
01070 }