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
00047 protected function _getUrlExtension()
00048 {
00049 return '.html';
00050 }
00051
00061 protected function _getProductForLang( $oArticle, $iLang )
00062 {
00063 if ( isset( $iLang ) && $iLang != $oArticle->getLanguage() ) {
00064 $sId = $oArticle->getId();
00065 $oArticle = oxNew( 'oxarticle' );
00066 $oArticle->loadInLang( $iLang, $sId );
00067 }
00068
00069 return $oArticle;
00070 }
00071
00080 protected function _getArticleTagUri( $oArticle, $iLang = null )
00081 {
00082 $oView = $this->getConfig()->getActiveView();
00083
00084 $sTag = null;
00085 if ( $oView instanceof oxView ) {
00086 $sTag = $oView->getTag();
00087 }
00088
00089 $iShopId = $this->getConfig()->getShopId();
00090 $sStdUrl = $oArticle->getStdTagLink( $sTag );
00091 $sSeoUrl = $this->_loadFromDb( 'dynamic', $this->getDynamicObjectId( $iShopId, $sStdUrl ), $iLang );
00092 if ( !$sSeoUrl ) {
00093
00094
00095 $sSeoUrl = oxSeoEncoderTag::getInstance()->getTagUri( $sTag, $iLang );
00096 $sSeoUrl .= $this->_prepareArticleTitle( $oArticle );
00097 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl, $this->_getStaticObjectId( $iShopId, $sStdUrl ), $iLang );
00098
00099 $sSeoUrl = $this->_getDynamicUri( $sStdUrl, $sSeoUrl, $iLang );
00100 }
00101
00102 return $sSeoUrl;
00103 }
00104
00113 protected function _getArticlePriceCategoryUri( $oArticle, $iLang = null)
00114 {
00115 startProfile(__FUNCTION__);
00116 if (!isset($iLang)) {
00117 $iLang = $oArticle->getLanguage();
00118 }
00119
00120 $sActCatId = '';
00121 $oView = $this->getConfig()->getActiveView();
00122 $oCategory = null;
00123
00124 if ( $oView instanceof oxView ) {
00125 $oCategory = $oView->getActCategory();
00126 }
00127
00128 if ( $oCategory ) {
00129
00130 $sActCatId = $oCategory->getId();
00131 }
00132
00133
00134 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActCatId, true ) ) ) {
00135
00136 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00137
00138
00139 $sSeoUrl = oxSeoEncoderCategory::getInstance()->getCategoryUri( $oCategory );
00140 $sSeoUrl .= $this->_prepareArticleTitle( $oArticle );
00141 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl, $oArticle->getId(), $iLang );
00142
00143 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang, null, 0, false, false, $sActCatId );
00144 }
00145
00146 stopProfile(__FUNCTION__);
00147
00148 return $sSeoUrl;
00149 }
00150
00159 protected function _getArticleUri( $oArticle, $iLang = null)
00160 {
00161 startProfile(__FUNCTION__);
00162 if (!isset($iLang)) {
00163 $iLang = $oArticle->getLanguage();
00164 }
00165
00166 $sActCatId = '';
00167 $oView = $this->getConfig()->getActiveView();
00168 $oActCat = null;
00169
00170 if ( $oView instanceof oxview ) {
00171 $oActCat = $oView->getActCategory();
00172 }
00173
00174 if ( $oActCat ) {
00175 $sActCatId = $oActCat->oxcategories__oxrootid->value;
00176 }
00177
00178
00179 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActCatId, $sActCatId ? true : false ) ) ) {
00180
00181 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00182
00183
00184 $sTitle = $this->_prepareArticleTitle( $oArticle );
00185
00186
00187 $oCategorys = $this->getSeoCategories( $oArticle, $iLang );
00188 if (!$oCategorys->count()) {
00189 $sSeoUrl = $this->_processSeoUrl( $sTitle, $oArticle->getId(), $iLang );
00190 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang );
00191 } else {
00192 $sTmpSeoUrl = '';
00193 $oEncoder = oxSeoEncoderCategory::getInstance();
00194 foreach ($oCategorys as $oCategory) {
00195
00196 $sTmpSeoUrl = $oEncoder->getCategoryUri( $oCategory );
00197 $sTmpSeoUrl .= $sTitle;
00198 $sTmpSeoUrl = $this->_processSeoUrl( $sTmpSeoUrl, $oArticle->getId(), $iLang );
00199
00200 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sTmpSeoUrl, $iLang, null, 0, false, false, $oCategory->oxcategories__oxrootid->value);
00201 if ($oCategory->oxcategories__oxrootid->value == $sActCatId) {
00202 $sSeoUrl = $sTmpSeoUrl;
00203 }
00204 }
00205 if (!$sSeoUrl) {
00206
00207 $sSeoUrl = $sTmpSeoUrl;
00208 }
00209 }
00210 }
00211
00212 stopProfile(__FUNCTION__);
00213
00214 return $sSeoUrl;
00215 }
00216
00225 protected function _prepareArticleTitle( $oArticle )
00226 {
00227 $sTitle = '';
00228
00229
00230 if ( !( $sTitle = $oArticle->oxarticles__oxtitle->value ) ) {
00231
00232 if ( ( $sParentId = $oArticle->oxarticles__oxparentid->value ) ) {
00233
00234
00235 if ( !isset( self::$_aTitleCache[$sParentId] ) ) {
00236 $oDb = oxDb::getDb();
00237 $sQ = "select oxtitle from oxarticles where oxid = ".$oDb->quote( $sParentId );
00238 self::$_aTitleCache[$sParentId] = $oDb->getOne( $sQ );
00239 }
00240 $sTitle = self::$_aTitleCache[$sParentId];
00241 }
00242 }
00243
00244
00245 if ( $oArticle->oxarticles__oxvarselect->value ) {
00246 $sTitle .= ( $sTitle ? ' ' : '' ).$oArticle->oxarticles__oxvarselect->value . ' ';
00247 }
00248
00249
00250 if ( !$sTitle ) {
00251 $sTitle .= $oArticle->oxarticles__oxartnum->value;
00252 }
00253
00254 return $this->_prepareTitle( $sTitle . '.html' );
00255 }
00256
00265 protected function _getArticleVendorUri( $oArticle, $iLang = null )
00266 {
00267 startProfile(__FUNCTION__);
00268 if ( !isset( $iLang ) ) {
00269 $iLang = $oArticle->getLanguage();
00270 }
00271
00272 $sActVendorId = $oArticle->oxarticles__oxvendorid->value;
00273 $oVendor = oxNew( 'oxvendor' );
00274 if ( !$sActVendorId || !$oVendor->load( $sActVendorId ) ) {
00275 $oVendor = null;
00276 }
00277
00278
00279 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActVendorId, true ) ) ) {
00280
00281 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00282
00283
00284 $sTitle = $this->_prepareArticleTitle( $oArticle );
00285
00286
00287 if ( !$sActVendorId || !$oVendor ) {
00288 $sSeoUrl = $this->_processSeoUrl( $sTitle, $oArticle->getId(), $iLang );
00289 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang );
00290 } else {
00291 $sSeoUrl = oxSeoEncoderVendor::getInstance()->getVendorUri( $oVendor, $iLang );
00292 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl . $sTitle, $oArticle->getId(), $iLang );
00293
00294 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang, null, 0, false, false, $sActVendorId );
00295 }
00296 }
00297
00298 stopProfile(__FUNCTION__);
00299
00300 return $sSeoUrl;
00301 }
00302
00311 protected function _getArticleManufacturerUri( $oArticle, $iLang = null )
00312 {
00313 startProfile(__FUNCTION__);
00314 if ( !isset( $iLang ) ) {
00315 $iLang = $oArticle->getLanguage();
00316 }
00317
00318 $sActManufacturerId = $oArticle->oxarticles__oxmanufacturerid->value;
00319 $oManufacturer = oxNew( 'oxmanufacturer' );
00320 if ( !$sActManufacturerId || !$oManufacturer->load( $sActManufacturerId ) ) {
00321 $oManufacturer = null;
00322 }
00323
00324
00325 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActManufacturerId, true ) ) ) {
00326
00327 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00328
00329
00330 $sTitle = $this->_prepareArticleTitle( $oArticle );
00331
00332
00333 if ( !$sActManufacturerId || !$oManufacturer ) {
00334 $sSeoUrl = $this->_processSeoUrl( $sTitle, $oArticle->getId(), $iLang );
00335 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang );
00336 } else {
00337 $sSeoUrl = oxSeoEncoderManufacturer::getInstance()->getManufacturerUri( $oManufacturer, $iLang );
00338 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl . $sTitle, $oArticle->getId(), $iLang );
00339
00340 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang, null, 0, false, false, $sActManufacturerId );
00341 }
00342 }
00343
00344 stopProfile(__FUNCTION__);
00345
00346 return $sSeoUrl;
00347 }
00357 public function getArticleUrl( $oArticle, $iLang = null, $iType = 0 )
00358 {
00359 if (!isset($iLang)) {
00360 $iLang = $oArticle->getLanguage();
00361 }
00362
00363 $sUri = '';
00364 switch ( $iType ) {
00365 case 1 :
00366 $sUri = $this->_getArticleVendorUri( $oArticle, $iLang );
00367 break;
00368 case 2 :
00369 $sUri = $this->_getArticleManufacturerUri( $oArticle, $iLang );
00370 break;
00371 case 3 :
00372 $sUri = $this->_getArticlePriceCategoryUri( $oArticle, $iLang );
00373 break;
00374 case 4 :
00375 $sUri = $this->_getArticleTagUri( $oArticle, $iLang );
00376 break;
00377 default:
00378 $sUri = $this->_getArticleUri( $oArticle, $iLang );
00379 break;
00380 }
00381
00382 return $this->_getFullUrl( $sUri, $iLang );
00383
00384 }
00385
00394 public function getSeoCategories( $oArticle, $iLang = null)
00395 {
00396 if (!isset($iLang)) {
00397 $iLang = $oArticle->getLanguage();
00398 }
00399 $sArtId = $oArticle->getId();
00400 if ( isset( $oArticle->oxarticles__oxparentid->value ) && $oArticle->oxarticles__oxparentid->value ) {
00401 $sArtId = $oArticle->oxarticles__oxparentid->value;
00402 }
00403
00404 $oDb = oxDb::getDb( false );
00405 $sArtIdQuoted = $oDb->quote( $sArtId );
00406
00407
00408 $sCatTable = getViewName('oxcategories');
00409
00410 $sQ = "select distinct catroots.oxrootid
00411 from oxobject2category as o2c
00412 left join {$sCatTable} as catroots
00413 on o2c.oxcatnid=catroots.oxid
00414 where o2c.oxobjectid = $sArtIdQuoted
00415 order by o2c.oxtime";
00416
00417 $aRoots = $oDb->getAll($sQ);
00418
00419 $oList = oxNew('oxList', 'oxcategory');
00420 foreach ($aRoots as $aRootId) {
00421 $sQ = "select node.* _depth from
00422 ( select oxcatnid from oxobject2category
00423 where oxobjectid = $sArtIdQuoted order by oxtime
00424 ) as sub
00425 left join {$sCatTable} as node
00426 on sub.oxcatnid=node.oxid
00427 join {$sCatTable} as parent
00428 on node.oxrootid = parent.oxrootid
00429 where node.oxrootid = ".$oDb->quote( $aRootId[0] )."
00430 and node.oxleft between parent.oxleft and parent.oxright
00431 group by node.oxid order by (count( parent.oxid ) ) desc limit 1";
00432
00433 $oCat = oxNew('oxcategory');
00434 $oCat->setLanguage($iLang);
00435 if ($oCat->assignRecord($sQ)) {
00436 $oList[] = $oCat;
00437 }
00438 }
00439 return $oList;
00440 }
00441
00449 public function onDeleteArticle($oArticle)
00450 {
00451 $sIdQuoted = oxDb::getDb()->quote($oArticle->getId());
00452 oxDb::getDb()->execute("delete from oxseo where oxobjectid = $sIdQuoted and oxtype = 'oxarticle'");
00453 }
00454 }