00001 <?php
00002
00007 class oxSeoEncoderArticle extends oxSeoEncoder
00008 {
00014 protected static $_instance = null;
00015
00021 protected static $_aTitleCache = array();
00022
00028 public static function getInstance()
00029 {
00030 if (!self::$_instance) {
00031 self::$_instance = oxNew("oxSeoEncoderArticle");
00032 }
00033
00034 if ( defined( 'OXID_PHP_UNIT' ) ) {
00035
00036 self::$_instance->_aSeoCache = array();
00037 }
00038
00039 return self::$_instance;
00040 }
00041
00051 protected function _getProductForLang( $oArticle, $iLang )
00052 {
00053 if ( isset( $iLang ) && $iLang != $oArticle->getLanguage() ) {
00054 $sId = $oArticle->getId();
00055 $oArticle = oxNew( 'oxarticle' );
00056 $oArticle->loadInLang( $iLang, $sId );
00057 }
00058
00059 return $oArticle;
00060 }
00061
00070 protected function _getArticleTagUri( $oArticle, $iLang = null )
00071 {
00072 $oView = $this->getConfig()->getActiveView();
00073
00074 $sTag = null;
00075 if ( $oView instanceof oxView ) {
00076 $sTag = $oView->getTag();
00077 }
00078
00079 $iShopId = $this->getConfig()->getShopId();
00080
00081 $sStdUrl = "index.php?cl=details&anid=".$oArticle->getId()."&listtype=tag&searchtag=".rawurlencode( $sTag );
00082 $sSeoUrl = $this->_loadFromDb( 'dynamic', $this->_getDynamicObjectId( $iShopId, $sStdUrl ), $iLang );
00083 if ( !$sSeoUrl ) {
00084
00085
00086 $sSeoUrl = oxSeoEncoderTag::getInstance()->getTagUri( $sTag, $iLang );
00087 $sSeoUrl .= $this->_prepareArticleTitle( $oArticle );
00088 $sSeoUrl = $this->_getUniqueSeoUrl( $sSeoUrl, '.html', $this->_getStaticObjectId( $iShopId, $sStdUrl ), $iLang );
00089
00090 $sSeoUrl = $this->_getDynamicUri( $sStdUrl, $sSeoUrl, $iLang );
00091 }
00092
00093 return $sSeoUrl;
00094 }
00095
00104 protected function _getArticlePriceCategoryUri( $oArticle, $iLang = null)
00105 {
00106 startProfile(__FUNCTION__);
00107 if (!isset($iLang)) {
00108 $iLang = $oArticle->getLanguage();
00109 }
00110
00111 $sActCatId = '';
00112 $oView = $this->getConfig()->getActiveView();
00113 $oCategory = null;
00114
00115 if ( $oView instanceof oxView ) {
00116 $oCategory = $oView->getActCategory();
00117 }
00118
00119 if ( $oCategory ) {
00120
00121 $sActCatId = $oCategory->getId();
00122 }
00123
00124
00125 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActCatId, true ) ) ) {
00126
00127 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00128
00129
00130 $sSeoUrl = oxSeoEncoderCategory::getInstance()->getCategoryUri( $oCategory );
00131 $sSeoUrl .= $this->_prepareArticleTitle( $oArticle );
00132 $sSeoUrl = $this->_getUniqueSeoUrl( $sSeoUrl, '.html', $oArticle->getId(), $iLang );
00133
00134 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang, null, 0, false, false, $sActCatId );
00135 }
00136
00137 stopProfile(__FUNCTION__);
00138
00139 return $sSeoUrl;
00140 }
00141
00150 protected function _getArticleUri( $oArticle, $iLang = null)
00151 {
00152 startProfile(__FUNCTION__);
00153 if (!isset($iLang)) {
00154 $iLang = $oArticle->getLanguage();
00155 }
00156
00157 $sActCatId = '';
00158 $oView = $this->getConfig()->getActiveView();
00159 $oActCat = null;
00160
00161 if ( $oView instanceof oxUBase ) {
00162 $oActCat = $oView->getActCategory();
00163 }
00164
00165 if ( $oActCat ) {
00166 $sActCatId = $oActCat->oxcategories__oxrootid->value;
00167 }
00168
00169
00170 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActCatId, false ) ) ) {
00171
00172 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00173
00174
00175 $sTitle = $this->_prepareArticleTitle( $oArticle );
00176
00177
00178 $oCategorys = $this->getSeoCategories( $oArticle, $iLang );
00179 if (!$oCategorys->count()) {
00180 $sSeoUrl = $this->_getUniqueSeoUrl( $sTitle, '.html', $oArticle->getId(), $iLang );
00181 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang );
00182 } else {
00183 $sTmpSeoUrl = '';
00184 $oEncoder = oxSeoEncoderCategory::getInstance();
00185 foreach ($oCategorys as $oCategory) {
00186
00187 $sTmpSeoUrl = $oEncoder->getCategoryUri( $oCategory );
00188 $sTmpSeoUrl .= $sTitle;
00189 $sTmpSeoUrl = $this->_getUniqueSeoUrl( $sTmpSeoUrl, '.html', $oArticle->getId(), $iLang );
00190
00191 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sTmpSeoUrl, $iLang, null, 0, false, false, $oCategory->oxcategories__oxrootid->value);
00192 if ($oCategory->oxcategories__oxrootid->value == $sActCatId) {
00193 $sSeoUrl = $sTmpSeoUrl;
00194 }
00195 }
00196 if (!$sSeoUrl) {
00197
00198 $sSeoUrl = $sTmpSeoUrl;
00199 }
00200 }
00201 }
00202
00203 stopProfile(__FUNCTION__);
00204
00205 return $sSeoUrl;
00206 }
00207
00216 protected function _prepareArticleTitle( $oArticle )
00217 {
00218 $sTitle = '';
00219
00220
00221 if ( !( $sTitle = $oArticle->oxarticles__oxtitle->value ) ) {
00222
00223 if ( ( $sParentId = $oArticle->oxarticles__oxparentid->value ) ) {
00224
00225
00226 if ( !isset( self::$_aTitleCache[$sParentId] ) ) {
00227 $sQ = "select oxtitle from oxarticles where oxid = '{$sParentId}'";
00228 self::$_aTitleCache[$sParentId] = oxDb::getDb()->getOne( $sQ );
00229 }
00230 $sTitle = self::$_aTitleCache[$sParentId];
00231 }
00232 }
00233
00234
00235 if ( $oArticle->oxarticles__oxvarselect->value ) {
00236 $sTitle .= ( $sTitle ? ' ' : '' ).$oArticle->oxarticles__oxvarselect->value . ' ';
00237 }
00238
00239
00240 if ( !$sTitle ) {
00241 $sTitle .= $oArticle->oxarticles__oxartnum->value;
00242 }
00243
00244 return $this->_prepareTitle( $sTitle . '.html' );
00245 }
00246
00255 protected function _getArticleVendorUri( $oArticle, $iLang = null )
00256 {
00257 startProfile(__FUNCTION__);
00258 if ( !isset( $iLang ) ) {
00259 $iLang = $oArticle->getLanguage();
00260 }
00261
00262 $sActVendorId = $oArticle->oxarticles__oxvendorid->value;
00263 $oVendor = oxNew( 'oxvendor' );
00264 if ( !$sActVendorId || !$oVendor->load( $sActVendorId ) ) {
00265 $oVendor = null;
00266 }
00267
00268
00269 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActVendorId, true ) ) ) {
00270
00271 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00272
00273
00274 $sTitle = $this->_prepareArticleTitle( $oArticle );
00275
00276
00277 if ( !$sActVendorId || !$oVendor ) {
00278 $sSeoUrl = $this->_getUniqueSeoUrl( $sTitle, '.html', $oArticle->getId(), $iLang );
00279 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang );
00280 } else {
00281 $sSeoUrl = oxSeoEncoderVendor::getInstance()->getVendorUri( $oVendor, $iLang );
00282 $sSeoUrl = $this->_getUniqueSeoUrl( $sSeoUrl . $sTitle, '.html', $oArticle->getId(), $iLang );
00283
00284 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang, null, 0, false, false, $sActVendorId );
00285 }
00286 }
00287
00288 stopProfile(__FUNCTION__);
00289
00290 return $sSeoUrl;
00291 }
00292
00301 protected function _getArticleManufacturerUri( $oArticle, $iLang = null )
00302 {
00303 startProfile(__FUNCTION__);
00304 if ( !isset( $iLang ) ) {
00305 $iLang = $oArticle->getLanguage();
00306 }
00307
00308 $sActManufacturerId = $oArticle->oxarticles__oxmanufacturerid->value;
00309 $oManufacturer = oxNew( 'oxmanufacturer' );
00310 if ( !$sActManufacturerId || !$oManufacturer->load( $sActManufacturerId ) ) {
00311 $oManufacturer = null;
00312 }
00313
00314
00315 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActManufacturerId, true ) ) ) {
00316
00317 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00318
00319
00320 $sTitle = $this->_prepareArticleTitle( $oArticle );
00321
00322
00323 if ( !$sActManufacturerId || !$oManufacturer ) {
00324 $sSeoUrl = $this->_getUniqueSeoUrl( $sTitle, '.html', $oArticle->getId(), $iLang );
00325 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang );
00326 } else {
00327 $sSeoUrl = oxSeoEncoderManufacturer::getInstance()->getManufacturerUri( $oManufacturer, $iLang );
00328 $sSeoUrl = $this->_getUniqueSeoUrl( $sSeoUrl . $sTitle, '.html', $oArticle->getId(), $iLang );
00329
00330 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang, null, 0, false, false, $sActManufacturerId );
00331 }
00332 }
00333
00334 stopProfile(__FUNCTION__);
00335
00336 return $sSeoUrl;
00337 }
00347 public function getArticleUrl( $oArticle, $iLang = null, $iType = 0 )
00348 {
00349 if (!isset($iLang)) {
00350 $iLang = $oArticle->getLanguage();
00351 }
00352
00353 $sUri = '';
00354 switch ( $iType ) {
00355 case 1 :
00356 $sUri = $this->_getArticleVendorUri( $oArticle, $iLang );
00357 break;
00358 case 2 :
00359 $sUri = $this->_getArticleManufacturerUri( $oArticle, $iLang );
00360 break;
00361 case 3 :
00362 $sUri = $this->_getArticlePriceCategoryUri( $oArticle, $iLang );
00363 break;
00364 case 4 :
00365 $sUri = $this->_getArticleTagUri( $oArticle, $iLang );
00366 break;
00367 default:
00368 $sUri = $this->_getArticleUri( $oArticle, $iLang );
00369 break;
00370 }
00371
00372 return $this->_getFullUrl( $sUri, $iLang );
00373
00374 }
00375
00384 public function getSeoCategories( $oArticle, $iLang = null)
00385 {
00386 if (!isset($iLang)) {
00387 $iLang = $oArticle->getLanguage();
00388 }
00389 $sArtId = $oArticle->getId();
00390 if ( isset( $oArticle->oxarticles__oxparentid->value ) && $oArticle->oxarticles__oxparentid->value ) {
00391 $sArtId = $oArticle->oxarticles__oxparentid->value;
00392 }
00393
00394
00395 $oDb = oxDb::getDb( false );
00396 $sCatTable = getViewName('oxcategories');
00397
00398 $sQ = "select distinct catroots.oxrootid
00399 from oxobject2category as o2c
00400 left join {$sCatTable} as catroots
00401 on o2c.oxcatnid=catroots.oxid
00402 where o2c.oxobjectid = '$sArtId'";
00403
00404 $aRoots = $oDb->getAll($sQ);
00405
00406 $oList = oxNew('oxList', 'oxcategory');
00407 foreach ($aRoots as $aRootId) {
00408 $sQ = "select node.* _depth from
00409 ( select oxcatnid from oxobject2category
00410 where oxobjectid = '$sArtId' order by oxtime
00411 ) as sub
00412 left join {$sCatTable} as node
00413 on sub.oxcatnid=node.oxid
00414 join {$sCatTable} as parent
00415 on node.oxrootid = parent.oxrootid
00416 where node.oxrootid = '{$aRootId[0]}'
00417 and node.oxleft between parent.oxleft and parent.oxright
00418 group by node.oxid order by (count( parent.oxid ) ) desc limit 1";
00419
00420 $oCat = oxNew('oxcategory');
00421 $oCat->setLanguage($iLang);
00422 if ($oCat->assignRecord($sQ)) {
00423 $oList[] = $oCat;
00424 }
00425 }
00426 return $oList;
00427 }
00428
00436 public function onDeleteArticle($oArticle)
00437 {
00438 $sId = oxDb::getDb()->quote($oArticle->getId());
00439 oxDb::getDb()->execute("delete from oxseo where oxobjectid = $sId and oxtype = 'oxarticle'");
00440 }
00441 }