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 $sQ = "select oxtitle from oxarticles where oxid = '{$sParentId}'";
00237 self::$_aTitleCache[$sParentId] = oxDb::getDb()->getOne( $sQ );
00238 }
00239 $sTitle = self::$_aTitleCache[$sParentId];
00240 }
00241 }
00242
00243
00244 if ( $oArticle->oxarticles__oxvarselect->value ) {
00245 $sTitle .= ( $sTitle ? ' ' : '' ).$oArticle->oxarticles__oxvarselect->value . ' ';
00246 }
00247
00248
00249 if ( !$sTitle ) {
00250 $sTitle .= $oArticle->oxarticles__oxartnum->value;
00251 }
00252
00253 return $this->_prepareTitle( $sTitle . '.html' );
00254 }
00255
00264 protected function _getArticleVendorUri( $oArticle, $iLang = null )
00265 {
00266 startProfile(__FUNCTION__);
00267 if ( !isset( $iLang ) ) {
00268 $iLang = $oArticle->getLanguage();
00269 }
00270
00271 $sActVendorId = $oArticle->oxarticles__oxvendorid->value;
00272 $oVendor = oxNew( 'oxvendor' );
00273 if ( !$sActVendorId || !$oVendor->load( $sActVendorId ) ) {
00274 $oVendor = null;
00275 }
00276
00277
00278 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActVendorId, true ) ) ) {
00279
00280 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00281
00282
00283 $sTitle = $this->_prepareArticleTitle( $oArticle );
00284
00285
00286 if ( !$sActVendorId || !$oVendor ) {
00287 $sSeoUrl = $this->_processSeoUrl( $sTitle, $oArticle->getId(), $iLang );
00288 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang );
00289 } else {
00290 $sSeoUrl = oxSeoEncoderVendor::getInstance()->getVendorUri( $oVendor, $iLang );
00291 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl . $sTitle, $oArticle->getId(), $iLang );
00292
00293 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang, null, 0, false, false, $sActVendorId );
00294 }
00295 }
00296
00297 stopProfile(__FUNCTION__);
00298
00299 return $sSeoUrl;
00300 }
00301
00310 protected function _getArticleManufacturerUri( $oArticle, $iLang = null )
00311 {
00312 startProfile(__FUNCTION__);
00313 if ( !isset( $iLang ) ) {
00314 $iLang = $oArticle->getLanguage();
00315 }
00316
00317 $sActManufacturerId = $oArticle->oxarticles__oxmanufacturerid->value;
00318 $oManufacturer = oxNew( 'oxmanufacturer' );
00319 if ( !$sActManufacturerId || !$oManufacturer->load( $sActManufacturerId ) ) {
00320 $oManufacturer = null;
00321 }
00322
00323
00324 if ( !( $sSeoUrl = $this->_loadFromDb( 'oxarticle', $oArticle->getId(), $iLang, null, $sActManufacturerId, true ) ) ) {
00325
00326 $oArticle = $this->_getProductForLang( $oArticle, $iLang );
00327
00328
00329 $sTitle = $this->_prepareArticleTitle( $oArticle );
00330
00331
00332 if ( !$sActManufacturerId || !$oManufacturer ) {
00333 $sSeoUrl = $this->_processSeoUrl( $sTitle, $oArticle->getId(), $iLang );
00334 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang );
00335 } else {
00336 $sSeoUrl = oxSeoEncoderManufacturer::getInstance()->getManufacturerUri( $oManufacturer, $iLang );
00337 $sSeoUrl = $this->_processSeoUrl( $sSeoUrl . $sTitle, $oArticle->getId(), $iLang );
00338
00339 $this->_saveToDb( 'oxarticle', $oArticle->getId(), $oArticle->getStdLink(), $sSeoUrl, $iLang, null, 0, false, false, $sActManufacturerId );
00340 }
00341 }
00342
00343 stopProfile(__FUNCTION__);
00344
00345 return $sSeoUrl;
00346 }
00356 public function getArticleUrl( $oArticle, $iLang = null, $iType = 0 )
00357 {
00358 if (!isset($iLang)) {
00359 $iLang = $oArticle->getLanguage();
00360 }
00361
00362 $sUri = '';
00363 switch ( $iType ) {
00364 case 1 :
00365 $sUri = $this->_getArticleVendorUri( $oArticle, $iLang );
00366 break;
00367 case 2 :
00368 $sUri = $this->_getArticleManufacturerUri( $oArticle, $iLang );
00369 break;
00370 case 3 :
00371 $sUri = $this->_getArticlePriceCategoryUri( $oArticle, $iLang );
00372 break;
00373 case 4 :
00374 $sUri = $this->_getArticleTagUri( $oArticle, $iLang );
00375 break;
00376 default:
00377 $sUri = $this->_getArticleUri( $oArticle, $iLang );
00378 break;
00379 }
00380
00381 return $this->_getFullUrl( $sUri, $iLang );
00382
00383 }
00384
00393 public function getSeoCategories( $oArticle, $iLang = null)
00394 {
00395 if (!isset($iLang)) {
00396 $iLang = $oArticle->getLanguage();
00397 }
00398 $sArtId = $oArticle->getId();
00399 if ( isset( $oArticle->oxarticles__oxparentid->value ) && $oArticle->oxarticles__oxparentid->value ) {
00400 $sArtId = $oArticle->oxarticles__oxparentid->value;
00401 }
00402
00403
00404 $oDb = oxDb::getDb( false );
00405 $sCatTable = getViewName('oxcategories');
00406
00407 $sQ = "select distinct catroots.oxrootid
00408 from oxobject2category as o2c
00409 left join {$sCatTable} as catroots
00410 on o2c.oxcatnid=catroots.oxid
00411 where o2c.oxobjectid = '$sArtId'
00412 order by o2c.oxtime";
00413
00414 $aRoots = $oDb->getAll($sQ);
00415
00416 $oList = oxNew('oxList', 'oxcategory');
00417 foreach ($aRoots as $aRootId) {
00418 $sQ = "select node.* _depth from
00419 ( select oxcatnid from oxobject2category
00420 where oxobjectid = '$sArtId' order by oxtime
00421 ) as sub
00422 left join {$sCatTable} as node
00423 on sub.oxcatnid=node.oxid
00424 join {$sCatTable} as parent
00425 on node.oxrootid = parent.oxrootid
00426 where node.oxrootid = '{$aRootId[0]}'
00427 and node.oxleft between parent.oxleft and parent.oxright
00428 group by node.oxid order by (count( parent.oxid ) ) desc limit 1";
00429
00430 $oCat = oxNew('oxcategory');
00431 $oCat->setLanguage($iLang);
00432 if ($oCat->assignRecord($sQ)) {
00433 $oList[] = $oCat;
00434 }
00435 }
00436 return $oList;
00437 }
00438
00446 public function onDeleteArticle($oArticle)
00447 {
00448 $sId = oxDb::getDb()->quote($oArticle->getId());
00449 oxDb::getDb()->execute("delete from oxseo where oxobjectid = $sId and oxtype = 'oxarticle'");
00450 }
00451 }