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 $sObjectid = $sNewId?"'$sNewId'":'oxobjectid';
00162 $sType = $sType?"oxtype = {$sType} and":'';
00163
00164
00165 $sSub = "select {$sObjectid}, MD5( LOWER( oxseourl ) ), oxshopid, oxlang, now() from oxseo where {$sType} oxobjectid = {$sId} and oxshopid = {$iShopId} and oxlang = {$iLang} limit 1";
00166 $sQ = "replace oxseohistory ( oxobjectid, oxident, oxshopid, oxlang, oxinsert ) {$sSub}";
00167 oxDb::getDb()->execute( $sQ );
00168 }
00169
00176 protected function _getAddParams()
00177 {
00178
00179 if ( $this->_sAddParams === null ) {
00180 $this->_sAddParams = $this->_getAddParamsFnc( oxConfig::getParameter('currency'), $this->getConfig()->getShopId() );
00181 }
00182 return $this->_sAddParams;
00183 }
00184
00194 protected function _getAddParamsFnc( $iCur, $iActShop )
00195 {
00196
00197 $this->_sAddParams = '';
00198 $sSep = '?';
00199 if ( $iCur ) {
00200 $this->_sAddParams .= $sSep . 'cur=' . $iCur;
00201 $sSep = '&';
00202 }
00203
00204
00205 return $this->_sAddParams;
00206 }
00207
00218 protected function _getDynamicObjectId( $iShopId, $sStdUrl )
00219 {
00220 return $this->getDynamicObjectId( $iShopId, $sStdUrl );
00221 }
00222
00231 public function getDynamicObjectId( $iShopId, $sStdUrl )
00232 {
00233 return $this->_getStaticObjectId( $iShopId, $sStdUrl );
00234 }
00235
00245 protected function _getDynamicUri( $sStdUrl, $sSeoUrl, $iLang )
00246 {
00247 $iShopId = $this->getConfig()->getShopId();
00248
00249 $sStdUrl = $this->_trimUrl( $sStdUrl );
00250 $sObjectId = $this->getDynamicObjectId( $iShopId, $sStdUrl );
00251 $sSeoUrl = $this->_prepareTitle( $sSeoUrl );
00252
00253
00254 $sOldSeoUrl = $this->_loadFromDb( 'dynamic', $sObjectId, $iLang );
00255 if ( $sOldSeoUrl === $sSeoUrl ) {
00256 $sSeoUrl = $sOldSeoUrl;
00257 } else {
00258
00259 if ( $sOldSeoUrl ) {
00260 $oDb = oxDb::getDb();
00261 $this->_copyToHistory( $oDb->quote( $sObjectId ), $oDb->quote( $iShopId ), $iLang, $oDb->quote( 'dynamic' ) );
00262 }
00263
00264
00265 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl, $sObjectId, $iLang );
00266
00267
00268 $this->_saveToDb( 'dynamic', $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId );
00269 }
00270
00271 return $sSeoUrl;
00272 }
00273
00282 protected function _getFullUrl( $sSeoUrl, $iLang = null)
00283 {
00284 $sFullUrl = $this->getConfig()->getShopUrl( $iLang ) . $sSeoUrl . $this->_getAddParams();
00285 return $this->getSession()->processUrl( $sFullUrl );
00286 }
00287
00298 protected function _getSeoIdent( $sSeoUrl, $iLang = null )
00299 {
00300 return md5( strtolower( $sSeoUrl ) );
00301 }
00302
00312 protected function _getStaticUri( $sStdUrl, $iShopId, $iLang )
00313 {
00314 $sStdUrl = $this->_trimUrl( $sStdUrl, $iLang );
00315 return $this->_loadFromDb( 'static', $this->_getStaticObjectId( $iShopId, $sStdUrl ), $iLang );
00316 }
00317
00323 protected function _getUrlExtension()
00324 {
00325 return;
00326 }
00327
00340 protected function _getUniqueSeoUrl( $sSeoUrl, $sObjectId = null, $iObjectLang = null )
00341 {
00342 $oStr = getStr();
00343 $sConstEnd = $this->_getUrlExtension();
00344 if ($sConstEnd === null) {
00345 $aMatched = array();
00346 if ( preg_match('/\.html?$/i', $sSeoUrl, $aMatched ) ) {
00347 $sConstEnd = $aMatched[0];
00348 } else {
00349 if ($sSeoUrl{$oStr->strlen($sSeoUrl)-1} != '/') {
00350 $sSeoUrl .= '/';
00351 }
00352 $sConstEnd = '/';
00353 }
00354 }
00355
00356
00357 $sAdd = ' ';
00358 if ('/' != self::$_sSeparator) {
00359 $sAdd = self::$_sSeparator . self::$_sPrefix;
00360 } else {
00361 $sAdd = '_' . self::$_sPrefix;
00362 }
00363 $sSeoUrl = preg_replace( "#^(/*)(".implode('|', $this->_getReservedEntryKeys()).")/#i", "\$1\$2$sAdd/", $sSeoUrl );
00364
00365 $sBaseSeoUrl = $sSeoUrl;
00366 if ( $sConstEnd && $oStr->substr( $sSeoUrl, 0 - $oStr->strlen( $sConstEnd ) ) == $sConstEnd ) {
00367 $sBaseSeoUrl = $oStr->substr( $sSeoUrl, 0, $oStr->strlen( $sSeoUrl ) - $oStr->strlen( $sConstEnd ) );
00368 }
00369
00370 $oDb = oxDb::getDb();
00371 $iShopId = $this->getConfig()->getShopId();
00372 $iCnt = 0;
00373 $sCheckSeoUrl = $this->_trimUrl( $sSeoUrl );
00374 $sQ = "select 1 from oxseo where oxshopid = '{$iShopId}'";
00375
00376
00377 if ( $sObjectId && isset($iObjectLang) ) {
00378 $sQ .= " and not (oxobjectid = '{$sObjectId}' and oxlang = $iObjectLang)";
00379 }
00380
00381 while ( $oDb->getOne( $sQ ." and oxident='".$this->_getSeoIdent( $sCheckSeoUrl )."' " ) ) {
00382 $sAdd = '';
00383 if ( self::$_sPrefix ) {
00384 $sAdd = self::$_sSeparator . self::$_sPrefix;
00385 }
00386 if ( $iCnt ) {
00387 $sAdd .= self::$_sSeparator . $iCnt;
00388 }
00389 ++$iCnt;
00390
00391 $sSeoUrl = $sBaseSeoUrl . $sAdd . $sConstEnd;
00392 $sCheckSeoUrl = $this->_trimUrl( $sSeoUrl );
00393 }
00394 return $sSeoUrl;
00395 }
00396
00412 protected function _loadFromDb( $sType, $sId, $iLang, $iShopId = null, $sParams = null, $blStrictParamsCheck = true)
00413 {
00414 $oDb = oxDb::getDb( true );
00415 if ( $iShopId === null ) {
00416 $iShopId = $this->getConfig()->getShopId();
00417 }
00418
00419 $iShopId = $oDb->quote( $iShopId );
00420 $sId = $oDb->quote( $sId );
00421 $sType = $oDb->quote( $sType );
00422 $iLang = (int) $iLang;
00423
00424 $sQ = "select oxfixed, oxseourl, oxexpired, oxtype from oxseo where oxtype = {$sType}
00425 and oxobjectid = {$sId} and oxshopid = {$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
00436 $sIdent = md5($sQ);
00437 if ( isset( $this->_aSeoCache[$sIdent] ) ) {
00438 return $this->_aSeoCache[$sIdent];
00439 }
00440
00441 $sSeoUrl = false;
00442 $oRs = $oDb->execute( $sQ );
00443 if ( $oRs && $oRs->recordCount() > 0 && !$oRs->EOF ) {
00444
00445 if ( $oRs->fields['oxexpired'] && ( $oRs->fields['oxtype'] == 'static' || $oRs->fields['oxtype'] == 'dynamic' ) ) {
00446
00447 $this->_copyToHistory( $sId, $iShopId, $iLang );
00448 $oDb->execute( "update oxseo set oxexpired = 0 where oxobjectid = {$sId} and oxlang = '{$iLang}' " );
00449 $sSeoUrl = $oRs->fields['oxseourl'];
00450 } elseif ( !$oRs->fields['oxexpired'] || $oRs->fields['oxfixed'] ) {
00451
00452 $sSeoUrl = $oRs->fields['oxseourl'];
00453 }
00454
00455
00456 $this->_aSeoCache[$sIdent] = $sSeoUrl;
00457 }
00458 return $sSeoUrl;
00459 }
00460
00467 protected function _getReservedEntryKeys()
00468 {
00469 if (!isset(self::$_aReservedEntryKeys) && !is_array(self::$_aReservedEntryKeys)) {
00470 $sDir = getShopBasePath();
00471 self::$_aReservedEntryKeys = array();
00472 foreach (glob("$sDir/*") as $file) {
00473 if (preg_match('/^(.+)\.php[0-9]*$/i', basename($file), $m)) {
00474 self::$_aReservedEntryKeys[] = $m[0];
00475 self::$_aReservedEntryKeys[] = $m[1];
00476 } elseif (is_dir($file)) {
00477 self::$_aReservedEntryKeys[] = basename($file);
00478 }
00479 }
00480 }
00481 return self::$_aReservedEntryKeys;
00482 }
00483
00492 protected function _prepareTitle( $sTitle, $blSkipTruncate = false )
00493 {
00494
00495 $sTitle = $this->encodeString( $sTitle );
00496
00497
00498 $sTitle = strip_tags( $sTitle );
00499 $sSeparator = self::$_sSeparator;
00500 $sPrefix = self::$_sPrefix;
00501
00502 foreach ( self::$_aReservedWords as $sWord ) {
00503
00504 $sTitle = preg_replace( array( "/(\s$sWord)$/i", "/^($sWord\s)/i", "/(\s$sWord\s)/i", "/^($sWord)$/i",
00505 "/(\/$sWord)$/i", "/^($sWord\/)/i", "/(\/$sWord\/)/i"),
00506 " $1{$sSeparator}{$sPrefix}{$sSeparator} ", $sTitle );
00507 }
00508
00509
00510 $sExt = '';
00511 $oStr = getStr();
00512 $aMatched = array();
00513 if ( preg_match( '/\.html?$/i', $sTitle, $aMatched ) ) {
00514 $sExt = $oStr->substr( $sTitle, 0 - $oStr->strlen( $aMatched[0] ) );
00515 $sTitle = $oStr->substr( $sTitle, 0, $oStr->strlen( $sTitle ) - $oStr->strlen( $aMatched[0] ) );
00516 }
00517
00518
00519 if ( !$blSkipTruncate && $oStr->strlen( $sTitle ) > $this->_iIdLength ) {
00520
00521 if ( ( $iFirstSpace = $oStr->strstr( $oStr->substr( $sTitle, $this->_iIdLength ), ' ' ) !== false ) ) {
00522 $sTitle = $oStr->substr( $sTitle, 0, $this->_iIdLength + $iFirstSpace );
00523 }
00524 }
00525
00526
00527 $sRegExp = '/[^A-Za-z0-9'.preg_quote( self::$_sSeparator, '/').'\/]+/';
00528 $sTitle = trim( $oStr->preg_replace( array( "/\W*\/\W*/", $sRegExp ), array( "/", self::$_sSeparator ), $sTitle ), self::$_sSeparator );
00529
00530
00531 if ( !$sTitle ) {
00532 $sTitle = $this->_prepareTitle( self::$_sPrefix );
00533 }
00534
00535
00536 $sTitle .= $sExt;
00537
00538
00539 return $oStr->preg_replace( array( '|//+|', '/' . preg_quote( self::$_sSeparator . self::$_sSeparator, '/' ) .'+/' ),
00540 array( '/', self::$_sSeparator ), $sTitle );
00541 }
00542
00543
00562 protected function _saveToDb( $sType, $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId = null, $blFixed = null, $sKeywords = false, $sDescription = false, $sParams = null )
00563 {
00564 $oDb = oxDb::getDb( true );
00565 if ( $iShopId === null ) {
00566 $iShopId = $this->getConfig()->getShopId();
00567 }
00568
00569 $iShopId = $oDb->quote( $iShopId );
00570
00571 $sObjectId = $oDb->quote( $sObjectId );
00572 $sType = $oDb->quote( $sType );
00573
00574 $iLang = (int) $iLang;
00575
00576 $sStdUrl = $this->_trimUrl( $sStdUrl );
00577 $sSeoUrl = $this->_trimUrl( $sSeoUrl );
00578
00579 $sIdent = $this->_getSeoIdent( $sSeoUrl );
00580
00581 $sStdUrl = $oDb->quote( $sStdUrl );
00582 $sSeoUrl = $oDb->quote( $sSeoUrl );
00583
00584
00585 $sQ = "select oxfixed, oxexpired, ( oxstdurl like {$sStdUrl} and oxexpired != 2 ) as samestdurl, oxseourl like {$sSeoUrl} as sameseourl from oxseo where oxtype = {$sType} and oxobjectid = {$sObjectId} and oxshopid = {$iShopId} and oxlang = {$iLang} ";
00586 $sQ .= $sParams ? " and oxparams = " . $oDb->quote( $sParams ) : '';
00587 $sQ .= ( $sKeywords !== false ) ? " and oxkeywords = " . $oDb->quote( $sKeywords ) . " " : '';
00588 $sQ .= ( $sDescription !== false ) ? " and oxdescription = " . $oDb->quote( $sDescription ) . " " : '';
00589 $sQ .= isset( $blFixed ) ? " and oxfixed = " . ( (int) $blFixed ) . " " : '';
00590 $sQ .= "limit 1";
00591
00592 $oRs = $oDb->execute( $sQ );
00593 if ( $oRs && $oRs->recordCount() > 0 && !$oRs->EOF ) {
00594 if ( $oRs->fields['samestdurl'] && $oRs->fields['sameseourl'] && $oRs->fields['oxexpired'] ) {
00595
00596 $sSql = "update oxseo set oxexpired = 0 where oxtype = {$sType} and oxobjectid = {$sObjectId} and oxshopid = {$iShopId} and oxlang = {$iLang} ";
00597 $sSql .= $sParams ? " and oxparams = " . $oDb->quote( $sParams ) : '';
00598 $sSql .= " limit 1";
00599
00600 return $oDb->execute( $sSql );
00601 } elseif ( $oRs->fields['oxexpired'] && !$oRs->fields['oxfixed'] ) {
00602
00603 $this->_copyToHistory( $sObjectId, $iShopId, $iLang, $sType );
00604 }
00605 }
00606 $oStr = getStr();
00607 if ( $sKeywords !== false ) {
00608 $sKeywords = $oDb->quote( $oStr->htmlentities( $this->encodeString( strip_tags( $sKeywords ), false ) ) );
00609 }
00610
00611 if ( $sDescription !== false ) {
00612 $sDescription = $oDb->quote( $oStr->htmlentities( strip_tags( $sDescription ) ) );
00613 }
00614
00615
00616 $sParams = $sParams ? $oDb->quote( $sParams ) :'""';
00617 $blFixed = (int) $blFixed;
00618
00619 $sQ = "insert into oxseo
00620 (oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype, oxfixed, oxexpired, oxkeywords, oxdescription, oxparams)
00621 values
00622 ( {$sObjectId}, '$sIdent', {$iShopId}, {$iLang}, {$sStdUrl}, {$sSeoUrl}, {$sType}, '$blFixed', '0',
00623 ".( $sKeywords ? $sKeywords : "''" ).", ".( $sDescription ? $sDescription : "''" ).", $sParams )
00624 on duplicate key update oxident = '$sIdent', oxstdurl = {$sStdUrl}, oxseourl = {$sSeoUrl}, oxfixed = '$blFixed', oxexpired = '0',
00625 oxkeywords = ".( $sKeywords ? $sKeywords : "oxkeywords" ).", oxdescription = ".( $sDescription ? $sDescription : "oxdescription" );
00626
00627 return $oDb->execute( $sQ );
00628 }
00629
00640 protected function _trimUrl( $sUrl, $iLang = null )
00641 {
00642 $sUrl = str_replace( $this->getConfig()->getShopURL( $iLang ), '', $sUrl );
00643 return preg_replace( '/(force_)?sid=[a-z0-9\.]+&?(amp;)?/i', '', $sUrl );
00644 }
00645
00654 public function encodeString( $sString, $blReplaceChars = true )
00655 {
00656
00657 $sString = getStr()->html_entity_decode( $sString );
00658
00659 if ( $blReplaceChars ) {
00660 $aReplaceChars = $this->getConfig()->getConfigParam( 'aSeoReplaceChars' );
00661 $sString = str_replace( array_keys( $aReplaceChars ), array_values( $aReplaceChars ), $sString );
00662 }
00663
00664
00665 $aReplaceWhat = array( '&', '"', ''', '<', '>' );
00666 return str_replace( $aReplaceWhat, '', $sString );
00667 }
00668
00676 public function setSeparator( $sSeparator = null )
00677 {
00678 self::$_sSeparator = $sSeparator;
00679 if ( !self::$_sSeparator ) {
00680 self::$_sSeparator = '-';
00681 }
00682 }
00683
00691 public function setPrefix( $sPrefix )
00692 {
00693 if ($sPrefix) {
00694 self::$_sPrefix = $sPrefix;
00695 } else {
00696 self::$_sPrefix = 'oxid';
00697 }
00698 }
00699
00707 public function setIdLength( $iIdlength = null )
00708 {
00709 if ( isset( $iIdlength ) ) {
00710 $this->_iIdLength = $iIdlength;
00711 }
00712 }
00713
00721 public function setReservedWords( $aReservedWords )
00722 {
00723 self::$_aReservedWords = array_merge( self::$_aReservedWords, $aReservedWords );
00724 }
00725
00726
00738 public function markAsExpired( $sId, $iShopId = null, $iExpStat = 1, $iLang = null, $sParams = null )
00739 {
00740 $sWhere = $sId ? "where oxobjectid = '{$sId}'" : '';
00741 $sWhere .= isset( $iShopId ) ? ( $sWhere ? " and oxshopid = '{$iShopId}'" : "where oxshopid = '{$iShopId}'" ) : '';
00742 $sWhere .= $iLang ? ( $sWhere ? " and oxlang = '{$iLang}'" : "where oxlang = '{$iLang}'" ) : '';
00743 $sWhere .= $sParams ? ( $sWhere ? " and {$sParams}" : "where {$sParams}" ) : '';
00744
00745 $sQ = "update oxseo set oxexpired = '{$iExpStat}' $sWhere ";
00746 oxDb::getDb()->execute( $sQ );
00747 }
00748
00762 protected function _getPageUri( $oObject, $sType, $sStdUrl, $sSeoUrl, $sParams, $iLang = null, $blFixed = false )
00763 {
00764 if (!isset($iLang)) {
00765 $iLang = $oObject->getLanguage();
00766 }
00767 $iShopId = $this->getConfig()->getShopId();
00768
00769
00770 if ( ( $sOldSeoUrl = $this->_loadFromDb( $sType, $oObject->getId(), $iLang, $iShopId, $sParams ) ) ) {
00771 if ( $sOldSeoUrl === $sSeoUrl ) {
00772 return $sSeoUrl;
00773 } else {
00774 $oDb = oxDb::getDb();
00775 $this->_copyToHistory( $oDb->quote( $oObject->getId() ), $oDb->quote( $iShopId ), $iLang, $oDb->quote( $sType ) );
00776 }
00777 }
00778
00779 $this->_saveToDb( $sType, $oObject->getId(), $sStdUrl, $sSeoUrl, $iLang, $iShopId, (int) $blFixed, false, false, $sParams );
00780
00781 return $sSeoUrl;
00782 }
00783
00792 protected function _getStaticObjectId( $iShopId, $sStdUrl )
00793 {
00794 return md5( strtolower ( $iShopId . $this->_trimUrl( $sStdUrl ) ) );
00795 }
00796
00806 public function encodeStaticUrls( $aStaticUrl, $iShopId, $iLang )
00807 {
00808 $oDb = oxDb::getDb();
00809 $sValues = '';
00810 $sOldObjectId = null;
00811
00812
00813 $sStdUrl = $this->_trimUrl( trim( $aStaticUrl['oxseo__oxstdurl'] ) );
00814 $sObjectId = $aStaticUrl['oxseo__oxobjectid'];
00815
00816 if ( !$sObjectId || $sObjectId == '-1' ) {
00817 $sObjectId = $this->_getStaticObjectId( $iShopId, $sStdUrl );
00818 } else {
00819
00820 $sOldObjectId = $sObjectId;
00821
00822
00823 if ( $this->_getStaticObjectId( $iShopId, $sStdUrl ) != $sObjectId ) {
00824 $sObjectId = $this->_getStaticObjectId( $iShopId, $sStdUrl );
00825 }
00826 }
00827
00828 foreach ( $aStaticUrl['oxseo__oxseourl'] as $iLang => $sSeoUrl ) {
00829
00830
00831 if ( ( $sSeoUrl = trim( $sSeoUrl ) ) ) {
00832 $sSeoUrl = $this->_prepareTitle( $this->_trimUrl( $sSeoUrl ) );
00833 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl, $sObjectId, $iLang );
00834 }
00835
00836 if ( $sOldObjectId ) {
00837
00838 if ( !$oDb->getOne( "select ('{$sSeoUrl}' like oxseourl) & ('{$sStdUrl}' like oxstdurl) from oxseo where oxobjectid = '{$sOldObjectId}' and oxshopid = '{$iShopId}' and oxlang = '{$iLang}' " ) ) {
00839 $this->_copyToHistory( $oDb->quote( $sOldObjectId ), $oDb->quote( $iShopId ), $iLang, $oDb->quote( 'static' ), $sObjectId );
00840 }
00841 }
00842
00843 if ( !$sSeoUrl || !$sStdUrl ) {
00844 continue;
00845 }
00846
00847 $sIdent = $this->_getSeoIdent( $sSeoUrl );
00848
00849 if ( $sValues ) {
00850 $sValues .= ', ';
00851 }
00852
00853 $sValues .= "( '{$sObjectId}', '{$sIdent}', '{$iShopId}', '{$iLang}', '$sStdUrl', '$sSeoUrl', 'static' )";
00854 }
00855
00856
00857 if ( $sOldObjectId ) {
00858 $oDb->execute( "delete from oxseo where oxobjectid in ( '{$sOldObjectId}', '{$sObjectId}' )" );
00859 }
00860
00861
00862 if ( $sValues ) {
00863
00864 $sQ = "insert into oxseo ( oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype ) values {$sValues} ";
00865 $oDb->execute( $sQ );
00866 }
00867
00868 return $sObjectId;
00869 }
00870
00878 public function copyStaticUrls( $iShopId )
00879 {
00880 $iBaseShopId = $this->getConfig()->getBaseShopId();
00881 if ( $iShopId != $iBaseShopId ) {
00882 foreach (array_keys(oxLang::getInstance()->getLanguageIds()) as $iLang) {
00883 $iLang = (int) $iLang;
00884 $sQ = "insert into oxseo ( oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype )
00885 select MD5( LOWER( CONCAT( '{$iShopId}', oxstdurl ) ) ), MD5( LOWER( oxseourl ) ),
00886 '$iShopId', oxlang, oxstdurl, oxseourl, oxtype from oxseo where oxshopid = '{$iBaseShopId}' and oxtype = 'static' and oxlang='$iLang' ";
00887 oxDb::getDb()->execute( $sQ );
00888 }
00889 }
00890 }
00891
00901 public function getStaticUrl( $sStdUrl, $iLang = null, $iShopId = null )
00902 {
00903 if (!isset($iShopId)) {
00904 $iShopId = $this->getConfig()->getShopId();
00905 }
00906 if (!isset($iLang)) {
00907 $iLang = oxLang::getInstance()->getEditLanguage();
00908 }
00909
00910 $sFullUrl = '';
00911 if ( ( $sSeoUrl = $this->_getStaticUri( $sStdUrl, $iShopId, $iLang ) ) ) {
00912 $sFullUrl = $this->_getFullUrl( $sSeoUrl, $iLang );
00913 }
00914 return $sFullUrl;
00915 }
00916
00934 public function addSeoEntry( $sObjectId, $iShopId, $iLang, $sStdUrl, $sSeoUrl, $sType, $blFixed = 1, $sKeywords = '', $sDescription = '', $sParams = '', $blExclude = false )
00935 {
00936 $sSeoUrl = $this->_processSeoUrl( $this->_prepareTitle( $this->_trimUrl( $sSeoUrl ) ), $sObjectId, $iLang, $blExclude );
00937 $this->_saveToDb( $sType, $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId, $blFixed, $sKeywords, $sDescription, $sParams );
00938 }
00939
00950 public function deleteSeoEntry( $sObjectId, $iShopId, $iLang, $sType )
00951 {
00952 $sQ = "delete from oxseo where oxobjectid = '{$sObjectId}' and oxshopid = '{$iShopId}' and oxlang = '{$iLang}' and oxtype = '{$sType}' ";
00953 oxDb::getDb()->execute( $sQ );
00954 }
00955
00966 public function getMetaData( $sObjectId, $sMetaType, $iShopId = null, $iLang = null )
00967 {
00968 $iShopId = ( !isset( $iShopId ) ) ? $this->getConfig()->getShopId():$iShopId;
00969 $iLang = ( !isset( $iLang ) ) ? oxLang::getInstance()->getTplLanguage():$iLang;
00970
00971 return oxDb::getDb()->getOne( "select {$sMetaType} from oxseo where oxobjectid = '{$sObjectId}' and oxshopid = '{$iShopId}' and oxlang = '{$iLang}' order by oxparams" );
00972 }
00973
00987 public function getDynamicUrl( $sStdUrl, $sSeoUrl, $iLang )
00988 {
00989 return $this->_getFullUrl( $this->_getDynamicUri( $sStdUrl, $sSeoUrl, $iLang ) );
00990 }
00991
01000 public function fetchSeoUrl( $sStdUrl, $iLanguage = null )
01001 {
01002 $oDb = oxDb::getDb( true );
01003 $sStdUrl = $oDb->quote( $sStdUrl );
01004 $iLanguage = isset( $iLanguage ) ? $iLanguage : oxLang::getInstance()->getBaseLanguage();
01005
01006 $sSeoUrl = false;
01007
01008 $sQ = "select oxseourl, oxlang from oxseo where oxstdurl = $sStdUrl and oxlang = '$iLanguage' limit 1";
01009 $oRs = $oDb->execute( $sQ );
01010 if ( !$oRs->EOF ) {
01011 $sSeoUrl = $oRs->fields['oxseourl'];
01012 }
01013
01014 return $sSeoUrl;
01015 }
01016 }