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 protected $_aFixedCache = array();
00072
00078 public static function getInstance()
00079 {
00080 if ( defined( 'OXID_PHP_UNIT' ) ) {
00081 self::$_instance = modInstances::getMod( __CLASS__ );
00082 }
00083
00084 if (!self::$_instance) {
00085 self::$_instance = oxNew("oxSeoEncoder");
00086 if ( defined( 'OXID_PHP_UNIT' ) ) {
00087 modInstances::addMod( __CLASS__, self::$_instance);
00088 }
00089 }
00090
00091 if ( defined( 'OXID_PHP_UNIT' ) ) {
00092
00093 self::$_instance->_aSeoCache = array();
00094 }
00095
00096 return self::$_instance;
00097
00098 }
00099
00108 public function addLanguageParam( $sSeoUrl, $iLang )
00109 {
00110 $iLang = (int) $iLang;
00111 $iDefLang = (int) $this->getConfig()->getConfigParam( 'iDefSeoLang' );
00112 $aLangIds = oxLang::getInstance()->getLanguageIds();
00113
00114 if ( $iLang != $iDefLang && isset( $aLangIds[$iLang] ) && getStr()->strpos( $sSeoUrl, $aLangIds[$iLang] . '/' ) !== 0 ) {
00115 $sSeoUrl = $aLangIds[$iLang] . '/'.$sSeoUrl;
00116 }
00117
00118 return $sSeoUrl;
00119 }
00120
00133 protected function _processSeoUrl( $sSeoUrl, $sObjectId = null, $iLang = null, $blExclude = false )
00134 {
00135 if (!$blExclude) {
00136 $sSeoUrl = $this->addLanguageParam( $sSeoUrl, $iLang );
00137 }
00138 return $this->_getUniqueSeoUrl( $sSeoUrl, $sObjectId, $iLang );
00139 }
00140
00146 public function resetCache()
00147 {
00148 $this->_aSeoCache = array();
00149 }
00150
00154 public function __construct()
00155 {
00156 $myConfig = $this->getConfig();
00157 if (!self::$_sSeparator) {
00158 $this->setSeparator( $myConfig->getConfigParam( 'sSEOSeparator' ) );
00159 }
00160 if (!self::$_sPrefix) {
00161 $this->setPrefix( $myConfig->getConfigParam( 'sSEOuprefix' ) );
00162 }
00163 $this->setReservedWords( $myConfig->getConfigParam( 'aSEOReservedWords' ) );
00164 }
00165
00177 protected function _copyToHistory( $sId, $iShopId, $iLang, $sType = null, $sNewId = null )
00178 {
00179 $oDb = oxDb::getDb();
00180 $sObjectid = $sNewId?$oDb->quote( $sNewId ):'oxobjectid';
00181 $sType = $sType?"oxtype =".$oDb->quote( $sType )." and":'';
00182 $iLang = (int) $iLang;
00183
00184
00185 $sSub = "select $sObjectid, MD5( LOWER( oxseourl ) ), oxshopid, oxlang, now() from oxseo
00186 where {$sType} oxobjectid = ".$oDb->quote( $sId )." and oxshopid = ".$oDb->quote( $iShopId )." and
00187 oxlang = {$iLang} and oxexpired = '1'";
00188 $sQ = "replace oxseohistory ( oxobjectid, oxident, oxshopid, oxlang, oxinsert ) {$sSub}";
00189 $oDb->execute( $sQ );
00190 }
00191
00200 public function getDynamicObjectId( $iShopId, $sStdUrl )
00201 {
00202 return $this->_getStaticObjectId( $iShopId, $sStdUrl );
00203 }
00204
00214 protected function _getDynamicUri( $sStdUrl, $sSeoUrl, $iLang )
00215 {
00216 $iShopId = $this->getConfig()->getShopId();
00217
00218 $sStdUrl = $this->_trimUrl( $sStdUrl );
00219 $sObjectId = $this->getDynamicObjectId( $iShopId, $sStdUrl );
00220 $sSeoUrl = $this->_prepareUri( $sSeoUrl );
00221
00222
00223 $sOldSeoUrl = $this->_loadFromDb( 'dynamic', $sObjectId, $iLang );
00224 if ( $sOldSeoUrl === $sSeoUrl ) {
00225 $sSeoUrl = $sOldSeoUrl;
00226 } else {
00227
00228 if ( $sOldSeoUrl ) {
00229
00230 $this->_copyToHistory( $sObjectId, $iShopId, $iLang, 'dynamic' );
00231 }
00232
00233
00234 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl, $sObjectId, $iLang );
00235
00236
00237 $this->_saveToDb( 'dynamic', $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId );
00238 }
00239
00240 return $sSeoUrl;
00241 }
00242
00252 protected function _getFullUrl( $sSeoUrl, $iLang = null, $blSsl = false )
00253 {
00254 if ( $sSeoUrl ) {
00255 $sFullUrl = ( $blSsl ? $this->getConfig()->getSslShopUrl( $iLang ) : $this->getConfig()->getShopUrl( $iLang ) ) . $sSeoUrl;
00256 return oxUtilsUrl::getInstance()->processSeoUrl( $sFullUrl );
00257 }
00258 return false;
00259 }
00260
00270 protected function _getSeoIdent( $sSeoUrl )
00271 {
00272 return md5( strtolower( $sSeoUrl ) );
00273 }
00274
00284 protected function _getStaticUri( $sStdUrl, $iShopId, $iLang )
00285 {
00286 $sStdUrl = $this->_trimUrl( $sStdUrl, $iLang );
00287 return $this->_loadFromDb( 'static', $this->_getStaticObjectId( $iShopId, $sStdUrl ), $iLang );
00288 }
00289
00295 protected function _getUrlExtension()
00296 {
00297 return;
00298 }
00299
00312 protected function _getUniqueSeoUrl( $sSeoUrl, $sObjectId = null, $iObjectLang = null )
00313 {
00314 $sSeoUrl = $this->_prepareUri( $sSeoUrl );
00315 $oStr = getStr();
00316 $sExt = '';
00317 if ( $oStr->preg_match( '/(\.html?|\/)$/i', $sSeoUrl, $aMatched ) ) {
00318 $sExt = $aMatched[0];
00319 }
00320 $sBaseSeoUrl = $sSeoUrl;
00321 if ( $sExt && $oStr->substr( $sSeoUrl, 0 - $oStr->strlen( $sExt ) ) == $sExt ) {
00322 $sBaseSeoUrl = $oStr->substr( $sSeoUrl, 0, $oStr->strlen( $sSeoUrl ) - $oStr->strlen( $sExt ) );
00323 }
00324
00325 $oDb = oxDb::getDb();
00326 $iShopId = $this->getConfig()->getShopId();
00327 $iCnt = 0;
00328 $sCheckSeoUrl = $this->_trimUrl( $sSeoUrl );
00329 $sQ = "select 1 from oxseo where oxshopid = '{$iShopId}'";
00330
00331
00332 if ( $sObjectId && isset($iObjectLang) ) {
00333 $iObjectLang = (int) $iObjectLang;
00334 $sQ .= " and not (oxobjectid = " . $oDb->quote( $sObjectId ) . " and oxlang = $iObjectLang)";
00335 }
00336
00337 while ( $oDb->getOne( $sQ ." and oxident= " . $oDb->quote( $this->_getSeoIdent( $sCheckSeoUrl ) ) ) ) {
00338 $sAdd = '';
00339 if ( self::$_sPrefix ) {
00340 $sAdd = self::$_sSeparator . self::$_sPrefix;
00341 }
00342 if ( $iCnt ) {
00343 $sAdd .= self::$_sSeparator . $iCnt;
00344 }
00345 ++$iCnt;
00346
00347 $sSeoUrl = $sBaseSeoUrl . $sAdd . $sExt;
00348 $sCheckSeoUrl = $this->_trimUrl( $sSeoUrl );
00349 }
00350 return $sSeoUrl;
00351 }
00352
00367 protected function _isFixed( $sType, $sId, $iLang, $iShopId = null, $sParams = null, $blStrictParamsCheck = true)
00368 {
00369 if ( $iShopId === null ) {
00370 $iShopId = $this->getConfig()->getShopId();
00371 }
00372 $iLang = (int) $iLang;
00373
00374 if ( !isset( $this->_aFixedCache[$sType][$sShopId][$sId][$iLang] ) ) {
00375 $oDb = oxDb::getDb( true );
00376
00377 $sQ = "select oxfixed from oxseo where oxtype = ".$oDb->quote( $sType )."
00378 and oxobjectid = ".$oDb->quote( $sId ) ." and oxshopid = ".$oDb->quote( $iShopId )." and oxlang = '{$iLang}'";
00379
00380 $sParams = $sParams ? $oDb->quote( $sParams ) : "''";
00381 if ( $sParams && $blStrictParamsCheck ) {
00382 $sQ .= " and oxparams = {$sParams}";
00383 } else {
00384 $sQ .= " order by oxparams = {$sParams} desc";
00385 }
00386 $sQ .= " limit 1";
00387
00388 $this->_aFixedCache[$sType][$sShopId][$sId][$iLang] = (bool) $oDb->getOne( $sQ );
00389 }
00390 return $this->_aFixedCache[$sType][$sShopId][$sId][$iLang];
00391 }
00392
00408 protected function _loadFromDb( $sType, $sId, $iLang, $iShopId = null, $sParams = null, $blStrictParamsCheck = true)
00409 {
00410 $oDb = oxDb::getDb( true );
00411 if ( $iShopId === null ) {
00412 $iShopId = $this->getConfig()->getShopId();
00413 }
00414
00415 $iLang = (int) $iLang;
00416
00417 $sQ = "select oxfixed, oxseourl, oxexpired, oxtype from oxseo where oxtype = ".$oDb->quote( $sType )."
00418 and oxobjectid = ".$oDb->quote( $sId ) ." and oxshopid = ".$oDb->quote( $iShopId )." and oxlang = '{$iLang}'";
00419
00420 $sParams = $sParams ? $sParams : '';
00421 if ( $sParams && $blStrictParamsCheck ) {
00422 $sQ .= " and oxparams = '{$sParams}'";
00423 } else {
00424 $sQ .= " order by oxparams = '{$sParams}' desc";
00425 }
00426 $sQ .= " limit 1";
00427
00428
00429 $sIdent = md5($sQ);
00430 if ( isset( $this->_aSeoCache[$sIdent] ) ) {
00431 return $this->_aSeoCache[$sIdent];
00432 }
00433
00434 $sSeoUrl = false;
00435 $oRs = $oDb->execute( $sQ );
00436 if ( $oRs && $oRs->recordCount() > 0 && !$oRs->EOF ) {
00437
00438 if ( $oRs->fields['oxexpired'] && ( $oRs->fields['oxtype'] == 'static' || $oRs->fields['oxtype'] == 'dynamic' ) ) {
00439
00440 $this->_copyToHistory( $sId, $iShopId, $iLang );
00441 $oDb->execute( "update oxseo set oxexpired = 0 where oxobjectid = ".$oDb->quote( $sId )." and oxlang = '{$iLang}'" );
00442 $sSeoUrl = $oRs->fields['oxseourl'];
00443 } elseif ( !$oRs->fields['oxexpired'] || $oRs->fields['oxfixed'] ) {
00444
00445 $sSeoUrl = $oRs->fields['oxseourl'];
00446 }
00447
00448
00449 $this->_aSeoCache[$sIdent] = $sSeoUrl;
00450 }
00451 return $sSeoUrl;
00452 }
00453
00460 protected function _getReservedEntryKeys()
00461 {
00462 if ( !isset( self::$_aReservedEntryKeys ) || !is_array( self::$_aReservedEntryKeys ) ) {
00463 $sDir = getShopBasePath();
00464 self::$_aReservedEntryKeys = array_map('preg_quote', self::$_aReservedWords, array('#'));
00465 $oStr = getStr();
00466 foreach ( glob( "$sDir/*" ) as $sFile ) {
00467 if ( $oStr->preg_match( '/^(.+)\.php[0-9]*$/i', basename( $sFile ), $aMatches ) ) {
00468 self::$_aReservedEntryKeys[] = preg_quote( $aMatches[0], '#' );
00469 self::$_aReservedEntryKeys[] = preg_quote( $aMatches[1], '#' );
00470 } elseif ( is_dir( $sFile ) ) {
00471 self::$_aReservedEntryKeys[] = preg_quote( basename( $sFile ), '#' );
00472 }
00473 }
00474 self::$_aReservedEntryKeys = array_unique(self::$_aReservedEntryKeys);
00475 }
00476 return self::$_aReservedEntryKeys;
00477 }
00478
00486 protected function _prepareUri( $sUri )
00487 {
00488
00489 $sUri = $this->encodeString( $sUri );
00490
00491
00492 $sUri = strip_tags( $sUri );
00493 $oStr = getStr();
00494
00495
00496
00497 $oStr = getStr();
00498 $sExt = $this->_getUrlExtension();
00499 if ($sExt === null) {
00500 $aMatched = array();
00501 if ( $oStr->preg_match( '/(\.html?|\/)$/i', $sUri, $aMatched ) ) {
00502 $sExt = $aMatched[0];
00503 } else {
00504 $sExt = '/';
00505 }
00506 }
00507 if ( $sExt && $oStr->substr( $sUri, 0 - $oStr->strlen( $sExt ) ) == $sExt ) {
00508 $sUri = $oStr->substr( $sUri, 0, $oStr->strlen( $sUri ) - $oStr->strlen( $sExt ) );
00509 }
00510
00511
00512 $sRegExp = '/[^A-Za-z0-9'.preg_quote( self::$_sSeparator, '/').preg_quote( self::$_sPrefix, '/').'\/]+/';
00513 $sUri = $oStr->preg_replace( array( "/\W*\/\W*/", $sRegExp ), array( "/", self::$_sSeparator ), $sUri );
00514
00515
00516 if ( !$sUri && self::$_sPrefix ) {
00517 $sUri = $this->_prepareUri( self::$_sPrefix );
00518 }
00519
00520 $sAdd = '';
00521 if ('/' != self::$_sSeparator) {
00522 $sAdd = self::$_sSeparator . self::$_sPrefix;
00523 $sUri = trim($sUri, self::$_sSeparator);
00524 } else {
00525 $sAdd = '_' . self::$_sPrefix;
00526 }
00527
00528
00529 $sUri .= $sExt;
00530
00531
00532 $sUri = $oStr->preg_replace( "#^(/*)(".implode('|', $this->_getReservedEntryKeys()).")(/|$)#i", "\$1\$2$sAdd\$3", $sUri );
00533
00534
00535 return $oStr->preg_replace( array( '|//+|', '/' . preg_quote( self::$_sSeparator . self::$_sSeparator, '/' ) .'+/' ),
00536 array( '/', self::$_sSeparator ), $sUri );
00537 }
00538
00539
00548 protected function _prepareTitle( $sTitle, $blSkipTruncate = false )
00549 {
00550 $sTitle = $this->encodeString( $sTitle );
00551 $sSep = self::$_sSeparator;
00552 if (!$sSep || ('/' == $sSep)) {
00553 $sSep = '_';
00554 }
00555
00556 $sRegExp = '/[^A-Za-z0-9\/'.preg_quote( self::$_sPrefix, '/').preg_quote($sSep, '/').']+/';
00557 $sTitle = preg_replace( array("#/+#", $sRegExp, "# +#", "#(".preg_quote($sSep, '/').")+#"), $sSep, $sTitle );
00558
00559 $oStr = getStr();
00560
00561 if ( !$blSkipTruncate && $oStr->strlen( $sTitle ) > $this->_iIdLength ) {
00562 $iFirstSpace = $oStr->strpos( $sTitle, $sSep, $this->_iIdLength);
00563 if ( $iFirstSpace !== false ) {
00564 $sTitle = $oStr->substr( $sTitle, 0, $iFirstSpace );
00565 }
00566 }
00567
00568 $sTitle = trim( $sTitle, $sSep );
00569
00570 if (!$sTitle) {
00571 return self::$_sPrefix;
00572 }
00573
00574 return $sTitle;
00575 }
00576
00577
00594 protected function _saveToDb( $sType, $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId = null, $blFixed = null, $sParams = null )
00595 {
00596 $oDb = oxDb::getDb( true );
00597 if ( $iShopId === null ) {
00598 $iShopId = $this->getConfig()->getShopId();
00599 }
00600
00601 $iLang = (int) $iLang;
00602
00603 $sStdUrl = $this->_trimUrl( $sStdUrl );
00604 $sSeoUrl = $this->_trimUrl( $sSeoUrl );
00605 $sIdent = $this->_getSeoIdent( $sSeoUrl );
00606
00607
00608 $sQtedObjectId = $oDb->quote( $sObjectId );
00609 $iQtedShopId = $oDb->quote( $iShopId );
00610 $sQtedType = $oDb->quote( $sType );
00611 $sQtedSeoUrl = $oDb->quote( $sSeoUrl );
00612 $sQtedStdUrl = $oDb->quote( $sStdUrl );
00613 $sQtedParams = $oDb->quote( $sParams );
00614 $sQtedIdent = $oDb->quote( $sIdent );
00615
00616
00617 $sQ = "select oxfixed, oxexpired, ( oxstdurl like {$sQtedStdUrl} ) as samestdurl,
00618 oxseourl like {$sQtedSeoUrl} as sameseourl from oxseo where oxtype = {$sQtedType} and
00619 oxobjectid = {$sQtedObjectId} and oxshopid = {$iQtedShopId} and oxlang = {$iLang} ";
00620
00621 $sQ .= $sParams ? " and oxparams = {$sQtedParams} " : '';
00622
00623 $sQ .= "limit 1";
00624
00625 $oRs = $oDb->execute( $sQ );
00626 if ( $oRs && $oRs->recordCount() > 0 && !$oRs->EOF ) {
00627 if ( $oRs->fields['samestdurl'] && $oRs->fields['sameseourl'] && $oRs->fields['oxexpired'] ) {
00628
00629 $sFixed = isset( $blFixed ) ? ", oxfixed = " . ( (int) $blFixed ) . " " : '';
00630
00631 $sSql = "update oxseo set oxexpired = 0 {$sFixed} where oxtype = {$sQtedType} and
00632 oxobjectid = {$sQtedObjectId} and oxshopid = {$iQtedShopId} and oxlang = {$iLang} ";
00633 $sSql .= $sParams ? " and oxparams = {$sQtedParams} " : '';
00634 $sSql .= " limit 1";
00635
00636 return $oDb->execute( $sSql );
00637 } elseif ( $oRs->fields['oxexpired'] ) {
00638
00639 $this->_copyToHistory( $sObjectId, $iShopId, $iLang, $sType );
00640 }
00641 }
00642
00643
00644 $sParams = $sParams ? $oDb->quote( $sParams ) :'""';
00645 $blFixed = (int) $blFixed;
00646
00647 $sQ = "insert into oxseo
00648 (oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype, oxfixed, oxexpired, oxparams)
00649 values
00650 ( {$sQtedObjectId}, {$sQtedIdent}, {$iQtedShopId}, {$iLang}, {$sQtedStdUrl}, {$sQtedSeoUrl}, {$sQtedType}, '$blFixed', '0', {$sParams} )
00651 on duplicate key update
00652 oxident = {$sQtedIdent}, oxstdurl = {$sQtedStdUrl}, oxseourl = {$sQtedSeoUrl}, oxfixed = '$blFixed', oxexpired = '0'";
00653
00654 return $oDb->execute( $sQ );
00655 }
00656
00667 protected function _trimUrl( $sUrl, $iLang = null )
00668 {
00669 $myConfig = $this->getConfig();
00670 $oStr = getStr();
00671 $sUrl = str_replace( array( $myConfig->getShopUrl( $iLang ), $myConfig->getSslShopUrl( $iLang ) ), '', $sUrl );
00672 $sUrl = $oStr->preg_replace( '/(\?|&(amp;)?)(force_)?(admin_)?sid=[a-z0-9\.]+&?(amp;)?/i', '\1', $sUrl );
00673 $sUrl = $oStr->preg_replace( '/(\?|&(amp;)?)shp=[0-9]+&?(amp;)?/i', '\1', $sUrl );
00674 $sUrl = $oStr->preg_replace( '/(\?|&(amp;)?)lang=[0-9]+&?(amp;)?/i', '\1', $sUrl );
00675 $sUrl = $oStr->preg_replace( '/(\?|&(amp;)?)&(amp;)?/i', '\1', $sUrl );
00676 $sUrl = $oStr->preg_replace( '/(\?|&(amp;)?)+$/i', '', $sUrl );
00677 return trim($sUrl);
00678 }
00679
00688 public function encodeString( $sString, $blReplaceChars = true )
00689 {
00690
00691 $sString = getStr()->html_entity_decode( $sString );
00692
00693 if ( $blReplaceChars ) {
00694 $aReplaceChars = $this->getConfig()->getConfigParam( 'aSeoReplaceChars' );
00695 $sString = str_replace( array_keys( $aReplaceChars ), array_values( $aReplaceChars ), $sString );
00696 }
00697
00698
00699 $aReplaceWhat = array( '&', '"', ''', '<', '>' );
00700 return str_replace( $aReplaceWhat, '', $sString );
00701 }
00702
00710 public function setSeparator( $sSeparator = null )
00711 {
00712 self::$_sSeparator = $sSeparator;
00713 if ( !self::$_sSeparator ) {
00714 self::$_sSeparator = '-';
00715 }
00716 }
00717
00725 public function setPrefix( $sPrefix )
00726 {
00727 if ($sPrefix) {
00728 self::$_sPrefix = $sPrefix;
00729 } else {
00730 self::$_sPrefix = 'oxid';
00731 }
00732 }
00733
00741 public function setIdLength( $iIdlength = null )
00742 {
00743 if ( isset( $iIdlength ) ) {
00744 $this->_iIdLength = $iIdlength;
00745 }
00746 }
00747
00756 public function setReservedWords( $aReservedWords )
00757 {
00758 self::$_aReservedWords = array_merge( self::$_aReservedWords, $aReservedWords );
00759 }
00760
00761
00773 public function markAsExpired( $sId, $iShopId = null, $iExpStat = 1, $iLang = null, $sParams = null )
00774 {
00775 $oDb = oxDb::getDb();
00776 $sWhere = $sId ? "where oxobjectid = " . $oDb->quote( $sId ) : '';
00777 $sWhere .= isset( $iShopId ) ? ( $sWhere ? " and oxshopid = ". $oDb->quote( $iShopId ) : "where oxshopid = ". $oDb->quote( $iShopId ) ) : '';
00778 $sWhere .= $iLang ? ( $sWhere ? " and oxlang = '{$iLang}'" : "where oxlang = '{$iLang}'" ) : '';
00779 $sWhere .= $sParams ? ( $sWhere ? " and {$sParams}" : "where {$sParams}" ) : '';
00780
00781 $sQ = "update oxseo set oxexpired = " . $oDb->quote( $iExpStat ) . " $sWhere ";
00782 $oDb->execute( $sQ );
00783 }
00784
00798 protected function _getPageUri( $oObject, $sType, $sStdUrl, $sSeoUrl, $sParams, $iLang = null, $blFixed = false )
00799 {
00800 if ( !isset( $iLang ) ) {
00801 $iLang = $oObject->getLanguage();
00802 }
00803 $iShopId = $this->getConfig()->getShopId();
00804
00805
00806 $sOldSeoUrl = $this->_loadFromDb( $sType, $oObject->getId(), $iLang, $iShopId, $sParams );
00807 if ( !$sOldSeoUrl ) {
00808
00809 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl, $oObject->getId(), $iLang );
00810 $this->_saveToDb( $sType, $oObject->getId(), $sStdUrl, $sSeoUrl, $iLang, $iShopId, (int) $blFixed, $sParams );
00811 } else {
00812
00813 $sSeoUrl = $sOldSeoUrl;
00814 }
00815 return $sSeoUrl;
00816 }
00817
00826 protected function _getStaticObjectId( $iShopId, $sStdUrl )
00827 {
00828 return md5( strtolower ( $iShopId . $this->_trimUrl( $sStdUrl ) ) );
00829 }
00830
00840 public function encodeStaticUrls( $aStaticUrl, $iShopId, $iLang )
00841 {
00842 $oDb = oxDb::getDb();
00843 $sValues = '';
00844 $sOldObjectId = null;
00845
00846
00847 $sStdUrl = $this->_trimUrl( trim( $aStaticUrl['oxseo__oxstdurl'] ) );
00848 $sObjectId = $aStaticUrl['oxseo__oxobjectid'];
00849
00850 if ( !$sObjectId || $sObjectId == '-1' ) {
00851 $sObjectId = $this->_getStaticObjectId( $iShopId, $sStdUrl );
00852 } else {
00853
00854 $sOldObjectId = $sObjectId;
00855
00856
00857 if ( $this->_getStaticObjectId( $iShopId, $sStdUrl ) != $sObjectId ) {
00858 $sObjectId = $this->_getStaticObjectId( $iShopId, $sStdUrl );
00859 }
00860 }
00861
00862 foreach ( $aStaticUrl['oxseo__oxseourl'] as $iLang => $sSeoUrl ) {
00863
00864 $iLang = (int) $iLang;
00865
00866
00867 $sSeoUrl = $this->_trimUrl( $sSeoUrl );
00868 if ( $sSeoUrl ) {
00869 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl, $sObjectId, $iLang );
00870 }
00871
00872
00873 if ( $sOldObjectId ) {
00874
00875 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}' " ) ) {
00876 $this->_copyToHistory( $sOldObjectId, $iShopId, $iLang, 'static', $sObjectId );
00877 }
00878 }
00879
00880 if ( !$sSeoUrl || !$sStdUrl ) {
00881 continue;
00882 }
00883
00884 $sIdent = $this->_getSeoIdent( $sSeoUrl );
00885
00886 if ( $sValues ) {
00887 $sValues .= ', ';
00888 }
00889
00890 $sValues .= "( " . $oDb->quote( $sObjectId ) . ", " . $oDb->quote( $sIdent ) . ", " . $oDb->quote( $iShopId ).", '{$iLang}', " . $oDb->quote( $sStdUrl ) . ", " . $oDb->quote( $sSeoUrl ) . ", 'static' )";
00891 }
00892
00893
00894 if ( $sOldObjectId ) {
00895 $oDb->execute( "delete from oxseo where oxobjectid in ( " . $oDb->quote( $sOldObjectId ) . ", " . $oDb->quote( $sObjectId ) . " )" );
00896 }
00897
00898
00899 if ( $sValues ) {
00900
00901 $sQ = "insert into oxseo ( oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype ) values {$sValues} ";
00902 $oDb->execute( $sQ );
00903 }
00904
00905 return $sObjectId;
00906 }
00907
00915 public function copyStaticUrls( $iShopId )
00916 {
00917 $iBaseShopId = $this->getConfig()->getBaseShopId();
00918 if ( $iShopId != $iBaseShopId ) {
00919 $oDb = oxDb::getDb();
00920 foreach (array_keys(oxLang::getInstance()->getLanguageIds()) as $iLang) {
00921 $sQ = "insert into oxseo ( oxobjectid, oxident, oxshopid, oxlang, oxstdurl, oxseourl, oxtype )
00922 select MD5( LOWER( CONCAT( " . $oDb->quote( $iShopId ) . ", oxstdurl ) ) ), MD5( LOWER( oxseourl ) ),
00923 " . $oDb->quote( $iShopId ) . ", oxlang, oxstdurl, oxseourl, oxtype from oxseo where oxshopid = '{$iBaseShopId}' and oxtype = 'static' and oxlang='$iLang' ";
00924 $oDb->execute( $sQ );
00925 }
00926 }
00927 }
00928
00938 public function getStaticUrl( $sStdUrl, $iLang = null, $iShopId = null )
00939 {
00940 if (!isset($iShopId)) {
00941 $iShopId = $this->getConfig()->getShopId();
00942 }
00943 if (!isset($iLang)) {
00944 $iLang = oxLang::getInstance()->getEditLanguage();
00945 }
00946
00947 if ( isset($this->_aStaticUrlCache[$sStdUrl][$iLang][$iShopId])) {
00948 return $this->_aStaticUrlCache[$sStdUrl][$iLang][$iShopId];
00949 }
00950
00951 $sFullUrl = '';
00952 if ( ( $sSeoUrl = $this->_getStaticUri( $sStdUrl, $iShopId, $iLang ) ) ) {
00953 $sFullUrl = $this->_getFullUrl( $sSeoUrl, $iLang, strpos( $sStdUrl, "https:" ) === 0 );
00954 }
00955
00956
00957 $this->_aStaticUrlCache[$sStdUrl][$iLang][$iShopId] = $sFullUrl;
00958
00959 return $sFullUrl;
00960 }
00961
00980 public function addSeoEntry( $sObjectId, $iShopId, $iLang, $sStdUrl, $sSeoUrl, $sType, $blFixed = 1, $sKeywords = '', $sDescription = '', $sParams = '', $blExclude = false, $sAltObjectId = null )
00981 {
00982 $sSeoUrl = $this->_processSeoUrl( $this->_trimUrl( $sSeoUrl ? $sSeoUrl : $this->_getAltUri( $sAltObjectId ? $sAltObjectId : $sObjectId, $iLang ) ), $sObjectId, $iLang, $blExclude );
00983 if ( $this->_saveToDb( $sType, $sObjectId, $sStdUrl, $sSeoUrl, $iLang, $iShopId, $blFixed, $sParams ) ) {
00984
00985 $oDb = oxDb::getDb( true );
00986
00987
00988 $sQtedObjectId = $oDb->quote( $sAltObjectId ? $sAltObjectId : $sObjectId );
00989 $iQtedShopId = $oDb->quote( $iShopId );
00990
00991 $oStr = getStr();
00992 if ( $sKeywords !== false ) {
00993 $sKeywords = $oDb->quote( $oStr->htmlspecialchars( $this->encodeString( strip_tags( $sKeywords ), false ) ) );
00994 }
00995
00996 if ( $sDescription !== false ) {
00997 $sDescription = $oDb->quote( $oStr->htmlspecialchars( strip_tags( $sDescription ) ) );
00998 }
00999
01000 $sQ = "insert into oxobject2seodata
01001 ( oxobjectid, oxshopid, oxlang, oxkeywords, oxdescription )
01002 values
01003 ( {$sQtedObjectId}, {$iQtedShopId}, {$iLang}, ".( $sKeywords ? $sKeywords : "''" ).", ".( $sDescription ? $sDescription : "''" )." )
01004 on duplicate key update
01005 oxkeywords = ".( $sKeywords ? $sKeywords : "oxkeywords" ).", oxdescription = ".( $sDescription ? $sDescription : "oxdescription" );
01006 $oDb->execute( $sQ );
01007 }
01008 }
01009
01018 protected function _getAltUri( $sObjectId, $iLang )
01019 {
01020 }
01021
01032 public function deleteSeoEntry( $sObjectId, $iShopId, $iLang, $sType )
01033 {
01034 $oDb = oxDb::getDb();
01035 $sQ = "delete from oxseo where oxobjectid = " . $oDb->quote( $sObjectId ) . " and oxshopid = " . $oDb->quote( $iShopId ) . " and oxlang = " . $oDb->quote( $iLang ) . " and oxtype = " . $oDb->quote( $sType ) . " ";
01036 oxDb::getDb()->execute( $sQ );
01037 }
01038
01049 public function getMetaData( $sObjectId, $sMetaType, $iShopId = null, $iLang = null )
01050 {
01051 $oDb = oxDb::getDb();
01052
01053 $iShopId = ( !isset( $iShopId ) ) ? $this->getConfig()->getShopId():$iShopId;
01054 $iLang = ( !isset( $iLang ) ) ? oxLang::getInstance()->getObjectTplLanguage():((int) $iLang);
01055 return $oDb->getOne( "select {$sMetaType} from oxobject2seodata where oxobjectid = " . $oDb->quote( $sObjectId ) . " and oxshopid = " . $oDb->quote( $iShopId )." and oxlang = '{$iLang}'" );
01056 }
01057
01071 public function getDynamicUrl( $sStdUrl, $sSeoUrl, $iLang )
01072 {
01073 startProfile("getDynamicUrl");
01074 $sDynUrl = $this->_getFullUrl( $this->_getDynamicUri( $sStdUrl, $sSeoUrl, $iLang ), strpos( $sStdUrl, "https:" ) === 0 );
01075 stopProfile("getDynamicUrl");
01076 return $sDynUrl;
01077 }
01078
01087 public function fetchSeoUrl( $sStdUrl, $iLanguage = null )
01088 {
01089 $oDb = oxDb::getDb( true );
01090 $iLanguage = isset( $iLanguage ) ? ( (int) $iLanguage ) : oxLang::getInstance()->getBaseLanguage();
01091 $sSeoUrl = false;
01092
01093 $sShopId = $this->getConfig()->getShopId();
01094
01095 $sQ = "select oxseourl, oxlang from oxseo where oxstdurl = ".$oDb->quote( $sStdUrl )." and oxlang = '$iLanguage' and oxshopid = '$sShopId' limit 1";
01096 $oRs = $oDb->execute( $sQ );
01097 if ( !$oRs->EOF ) {
01098 $sSeoUrl = $oRs->fields['oxseourl'];
01099 }
01100
01101 return $sSeoUrl;
01102 }
01103 }