00001 <?php
00002
00003 if (!defined('OXTAGCLOUD_MINFONT')) {
00004 define('OXTAGCLOUD_MINFONT', 100);
00005 define('OXTAGCLOUD_MAXFONT', 400);
00006 define('OXTAGCLOUD_MINOCCURENCETOSHOW', 2);
00007
00008 define('OXTAGCLOUD_MINTAGLENGTH', 4);
00009 define('OXTAGCLOUD_STARTPAGECOUNT', 20);
00010 define('OXTAGCLOUD_EXTENDEDCOUNT', 200);
00011 }
00012
00017 class oxTagCloud extends oxSuperCfg
00018 {
00024 protected $_sCacheKey = "tagcloud_";
00025
00031 protected $_blExtended = false;
00032
00038 protected $_sProductId = null;
00039
00045 protected $_iLangId = null;
00046
00052 protected $_iMaxHit = null;
00053
00059 protected $_aCloudArray = null;
00060
00067 protected $_sSeparator = ' ';
00068
00073 public function __construct()
00074 {
00075 $sSeparator = $this->getConfig()->getConfigParam("sTagSeparator");
00076 if ($sSeparator)
00077 $this->_sSeparator = $sSeparator;
00078 }
00079
00087 public function setProductId( $sProductId )
00088 {
00089 $this->_sProductId = $sProductId;
00090 }
00091
00099 public function setLanguageId( $iLangId )
00100 {
00101 $this->_iLangId = $iLangId;
00102 }
00103
00111 public function setExtendedMode( $blExtended )
00112 {
00113 $this->_blExtended = $blExtended;
00114 }
00115
00121 public function getLanguageId()
00122 {
00123 if ( $this->_iLangId === null ) {
00124 $this->_iLangId = oxLang::getInstance()->getBaseLanguage();
00125 }
00126 return $this->_iLangId;
00127 }
00128
00134 public function getProductId()
00135 {
00136 return $this->_sProductId;
00137 }
00138
00144 public function isExtended()
00145 {
00146 return $this->_blExtended;
00147 }
00148
00158 public function getCloudArray( $sProductId = null, $blExtended = null, $iLang = null )
00159 {
00160
00161 $iLang = ( $iLang === null ) ? (int) $this->getLanguageId() : $iLang;
00162 $blExtended = ( $blExtended === null ) ? $this->isExtended() : $blExtended;
00163 $sProductId = ( $sProductId === null ) ? (string) $this->getProductId() : $sProductId;
00164
00165
00166 $sCacheIdent = $this->_getCacheKey( $blExtended, $iLang )."_".$sProductId;
00167 if ( !isset( $this->_aCloudArray[$sCacheIdent] ) ) {
00168
00169 $myUtils = oxUtils::getInstance();
00170
00171
00172 $aCloudArray = ( !$sProductId ) ? $myUtils->fromFileCache( $sCacheIdent ) : null;
00173
00174
00175 if ( $aCloudArray === null ) {
00176 $aCloudArray = $this->getTags( $sProductId, $blExtended, $iLang );
00177
00178 if ( !$sProductId ) {
00179 $myUtils->toFileCache( $sCacheIdent, $aCloudArray );
00180 }
00181 }
00182
00183 $this->_aCloudArray[$sCacheIdent] = $aCloudArray;
00184 }
00185 return $this->_aCloudArray[$sCacheIdent];
00186 }
00187
00195 public function getTagLink( $sTag )
00196 {
00197 $oSeoEncoderTag = oxSeoEncoderTag::getInstance();
00198 $iLang = $this->getLanguageId();
00199
00200 if ( oxUtils::getInstance()->seoIsActive() ) {
00201 $sUrl = $oSeoEncoderTag->getTagUrl( $sTag, $iLang );
00202 } else {
00203 $sUrl = $this->getConfig()->getShopUrl() . $oSeoEncoderTag->getStdTagUri( $sTag ) . "&lang=" . $iLang;
00204 }
00205
00206 return $sUrl;
00207 }
00208
00216 public function getTagTitle( $sTag )
00217 {
00218 return getStr()->htmlentities( $sTag );
00219 }
00220
00226 protected function _getMaxHit()
00227 {
00228 if ( $this->_iMaxHit === null ) {
00229 $this->_iMaxHit = max( $this->getCloudArray() );
00230 }
00231 return $this->_iMaxHit;
00232 }
00233
00241 public function getTagSize( $sTag )
00242 {
00243 $aCloudArray = $this->getCloudArray();
00244 $iCurrSize = $this->_getFontSize( $aCloudArray[ $sTag ], $this->_getMaxHit() );
00245
00246
00247 return floor( $iCurrSize / OXTAGCLOUD_MINFONT ) * OXTAGCLOUD_MINFONT;
00248 }
00249
00250
00260 public function getTags( $sArtId = null, $blExtended = false, $iLang = null )
00261 {
00262 $oDb = oxDb::getDb(true);
00263 if ($blExtended) {
00264 $iAmount = OXTAGCLOUD_EXTENDEDCOUNT;
00265 } else {
00266 $iAmount = OXTAGCLOUD_STARTPAGECOUNT;
00267 }
00268
00269 $sArticleSelect = " 1 ";
00270 if ( $sArtId ) {
00271 $sArticleSelect = " oxarticles.oxid = ".$oDb->quote( $sArtId )." ";
00272 $iAmount = 0;
00273 }
00274
00275 $sField = "oxartextends.oxtags".oxLang::getInstance()->getLanguageTag( $iLang );
00276
00277 $sArtView = getViewName('oxarticles');
00278 $sQ = "select $sField as oxtags from $sArtView as oxarticles left join oxartextends on oxarticles.oxid=oxartextends.oxid where oxarticles.oxactive=1 AND $sArticleSelect";
00279
00280 $rs = $oDb->execute( $sQ );
00281 $aTags = array();
00282 while ( $rs && $rs->recordCount() && !$rs->EOF ) {
00283 $sTags = $this->trimTags( $rs->fields['oxtags'] );
00284 $aArticleTags = explode( $this->_sSeparator, $sTags );
00285 foreach ( $aArticleTags as $sTag ) {
00286 if ( trim( $sTag ) ) {
00287 ++$aTags[$sTag];
00288 }
00289 }
00290 $rs->moveNext();
00291 }
00292
00293
00294 if ( $iAmount ) {
00295 arsort( $aTags );
00296 $aTags = array_slice( $aTags, 0, $iAmount, true );
00297 }
00298
00299 $aTags = $this->_sortTags( $aTags );
00300 return $aTags;
00301 }
00302
00311 protected function _sortTags( $aTags, $iLang = null )
00312 {
00313 if ( is_array( $aTags ) && count( $aTags ) ) {
00314 $oDb = oxDb::getDb( true );
00315 $sSubQ = '';
00316 foreach ( $aTags as $sKey => $sTag ) {
00317 if ( $sSubQ ) {
00318 $sSubQ .= ' union all ';
00319 }
00320 $sSubQ .= 'select '.$oDb->quote( $sKey ).' as _oxsort, '.$oDb->quote( $sTag ).' as _oxval';
00321 }
00322
00323 $sField = "oxartextends.oxtags".oxLang::getInstance()->getLanguageTag( $iLang );
00324
00325
00326 $sSubQ = "select {$sField} as _oxsort, 'ox_skip' as _oxval from oxartextends limit 1 union $sSubQ";
00327
00328 $sQ = "select _oxtable._oxsort, _oxtable._oxval from ( {$sSubQ} ) as _oxtable order by _oxtable._oxsort desc";
00329
00330 $aTags = array();
00331 $oRs = $oDb->execute( $sQ );
00332 while ( $oRs && $oRs->recordCount() && !$oRs->EOF ) {
00333 if ( $oRs->fields['_oxval'] != 'ox_skip' ) {
00334 $aTags[$oRs->fields['_oxsort']] = $oRs->fields['_oxval'];
00335 }
00336 $oRs->moveNext();
00337 }
00338 }
00339 return $aTags;
00340 }
00341
00353 public function getTagCloud($sArtId = null, $blExtended = false, $iLang = null )
00354 {
00355 $myUtils = oxUtils::getInstance();
00356
00357 $sTagCloud = null;
00358 $sCacheKey = $this->_getCacheKey($blExtended, $iLang );
00359 if ( $this->_sCacheKey && !$sArtId ) {
00360 $sTagCloud = $myUtils->fromFileCache( $sCacheKey );
00361 }
00362
00363 if ( !is_null($sTagCloud) ) {
00364 return $sTagCloud;
00365 }
00366
00367 $aTags = $this->getTags($sArtId, $blExtended, $iLang);
00368 if (!count($aTags)) {
00369 if ($this->_sCacheKey && !$sArtId) {
00370 $sTagCloud = false;
00371 $myUtils->toFileCache($sCacheKey, $sTagCloud);
00372 }
00373 return $sTagCloud;
00374 }
00375
00376 $iMaxHit = max( $aTags);
00377 $blSeoIsActive = $myUtils->seoIsActive();
00378 $oSeoEncoderTag = oxSeoEncoderTag::getInstance();
00379
00380 $iLang = ( $iLang !== null ) ? $iLang : oxLang::getInstance()->getBaseLanguage();
00381 $sUrl = $this->getConfig()->getShopUrl();
00382 $oStr = getStr();
00383
00384 $sTagCloud = false;
00385 foreach ( $aTags as $sTag => $sRelevance ) {
00386 if ( $blSeoIsActive ) {
00387 $sLink = $oSeoEncoderTag->getTagUrl( $sTag, $iLang );
00388 } else {
00389 $sLink = $sUrl . $oSeoEncoderTag->getStdTagUri( $sTag ) . "&lang=" . $iLang;
00390 }
00391 $iFontSize = $this->_getFontSize( $sRelevance, $iMaxHit );
00392 $sTagCloud .= "<a style='font-size:". $iFontSize ."%;' class='tagitem_". $iFontSize . "' href='$sLink'>".$oStr->htmlentities($sTag)."</a> ";
00393 }
00394
00395 if ( $this->_sCacheKey && !$sArtId ) {
00396 $myUtils->toFileCache( $sCacheKey, $sTagCloud );
00397 }
00398
00399 return $sTagCloud;
00400 }
00401
00410 protected function _getFontSize( $iHit, $iMaxHit )
00411 {
00412
00413 if ($iMaxHit <= OXTAGCLOUD_MINOCCURENCETOSHOW || !$iMaxHit) {
00414 return OXTAGCLOUD_MINFONT;
00415 }
00416
00417 $iFontDiff = OXTAGCLOUD_MAXFONT - OXTAGCLOUD_MINFONT;
00418 $iMaxHitDiff = $iMaxHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00419 $iHitDiff = $iHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00420
00421 if ($iHitDiff < 0) {
00422 $iHitDiff = 0;
00423 }
00424
00425 $iSize = round($iHitDiff * $iFontDiff / $iMaxHitDiff) + OXTAGCLOUD_MINFONT;
00426
00427 return $iSize;
00428 }
00429
00438 public function prepareTags( $sTags )
00439 {
00440 $aTags = explode( $this->_sSeparator, $sTags );
00441 $sRes = '';
00442 $oStr = getStr();
00443 foreach ( $aTags as $sTag ) {
00444 $sTag = trim($sTag);
00445 if ( ( $iLen = $oStr->strlen( $sTag ) ) ) {
00446 if ( $iLen < OXTAGCLOUD_MINTAGLENGTH ) {
00447 $sTag .= str_repeat( '_', OXTAGCLOUD_MINTAGLENGTH - $iLen );
00448 }
00449
00450 $sRes .= trim($oStr->strtolower( $sTag )) . $this->_sSeparator;
00451 }
00452 }
00453
00454 return trim( $sRes, $this->_sSeparator);
00455 }
00456
00464 public function trimTags($sTags)
00465 {
00466 $aTags = explode($this->_sSeparator, $sTags);
00467 $sRes = '';
00468 $oStr = getStr();
00469 foreach ( $aTags as $sTag ) {
00470 $sTag = trim($sTag);
00471 if ( $oStr->strlen( $sTag ) ) {
00472 $sRes .= rtrim( trim($sTag), '_' ) . $this->_sSeparator;
00473 }
00474 }
00475
00476 return trim($sRes, $this->_sSeparator);
00477 }
00478
00486 public function resetTagCache( $iLang = null )
00487 {
00488 $myUtils = oxUtils::getInstance();
00489
00490 $sCacheKey1 = $this->_getCacheKey( true, $iLang );
00491 $myUtils->toFileCache( $sCacheKey1, null );
00492
00493 $sCacheKey2 = $this->_getCacheKey( false, $iLang );
00494 $myUtils->toFileCache( $sCacheKey2, null );
00495 }
00496
00505 protected function _getCacheKey( $blExtended, $iLang = null )
00506 {
00507 return $this->_sCacheKey."_".$this->getConfig()->getShopId()."_".( ( $iLang !== null ) ? $iLang : oxLang::getInstance()->getBaseLanguage() ) ."_".$blExtended;
00508 }
00509
00510 }