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
00179
00180 if ( !$sProductId ) {
00181 $myUtils->toFileCache( $sCacheIdent, $aCloudArray );
00182 }
00183
00184 $this->_aCloudArray[$sCacheIdent] = $aCloudArray;
00185 }
00186 return $this->_aCloudArray[$sCacheIdent];
00187 }
00188
00196 public function getTagLink( $sTag )
00197 {
00198 $oSeoEncoderTag = oxSeoEncoderTag::getInstance();
00199 $iLang = $this->getLanguageId();
00200
00201 if ( oxUtils::getInstance()->seoIsActive() ) {
00202 $sUrl = $oSeoEncoderTag->getTagUrl( $sTag, $iLang );
00203 } else {
00204 $sUrl = $this->getConfig()->getShopUrl() . $oSeoEncoderTag->getStdTagUri( $sTag ) . "&lang=" . $iLang;
00205 }
00206
00207 return $sUrl;
00208 }
00209
00217 public function getTagTitle( $sTag )
00218 {
00219 return getStr()->htmlentities( $sTag );
00220 }
00221
00227 protected function _getMaxHit()
00228 {
00229 if ( $this->_iMaxHit === null ) {
00230 $this->_iMaxHit = max( $this->getCloudArray() );
00231 }
00232 return $this->_iMaxHit;
00233 }
00234
00242 public function getTagSize( $sTag )
00243 {
00244 $aCloudArray = $this->getCloudArray();
00245 $iCurrSize = $this->_getFontSize( $aCloudArray[ $sTag ], $this->_getMaxHit() );
00246
00247
00248 return floor( $iCurrSize / OXTAGCLOUD_MINFONT ) * OXTAGCLOUD_MINFONT;
00249 }
00250
00251
00261 public function getTags( $sArtId = null, $blExtended = false, $iLang = null )
00262 {
00263 $oDb = oxDb::getDb(true);
00264 if ($blExtended) {
00265 $iAmount = OXTAGCLOUD_EXTENDEDCOUNT;
00266 } else {
00267 $iAmount = OXTAGCLOUD_STARTPAGECOUNT;
00268 }
00269
00270 $sArticleSelect = " 1 ";
00271 if ( $sArtId ) {
00272 $sArticleSelect = " oxarticles.oxid = ".$oDb->quote( $sArtId )." ";
00273 $iAmount = 0;
00274 }
00275
00276 $sField = "oxartextends.oxtags".oxLang::getInstance()->getLanguageTag( $iLang );
00277
00278 $sArtView = getViewName('oxarticles');
00279 $sQ = "select $sField as oxtags from $sArtView as oxarticles left join oxartextends on oxarticles.oxid=oxartextends.oxid where oxarticles.oxactive=1 AND $sArticleSelect";
00280
00281 $rs = $oDb->execute( $sQ );
00282 $aTags = array();
00283 while ( $rs && $rs->recordCount() && !$rs->EOF ) {
00284 $sTags = $this->trimTags( $rs->fields['oxtags'] );
00285 $aArticleTags = explode( $this->_sSeparator, $sTags );
00286 foreach ( $aArticleTags as $sTag ) {
00287 if ( trim( $sTag ) ) {
00288 ++$aTags[$sTag];
00289 }
00290 }
00291 $rs->moveNext();
00292 }
00293
00294
00295 if ( $iAmount ) {
00296 arsort( $aTags );
00297 $aTags = array_slice( $aTags, 0, $iAmount, true );
00298 }
00299
00300 $aTags = $this->_sortTags( $aTags );
00301 return $aTags;
00302 }
00303
00312 protected function _sortTags( $aTags, $iLang = null )
00313 {
00314 if ( is_array( $aTags ) && count( $aTags ) ) {
00315 $oDb = oxDb::getDb( true );
00316 $sSubQ = '';
00317 foreach ( $aTags as $sKey => $sTag ) {
00318 if ( $sSubQ ) {
00319 $sSubQ .= ' union all ';
00320 }
00321 $sSubQ .= 'select '.$oDb->quote( $sKey ).' as _oxsort, '.$oDb->quote( $sTag ).' as _oxval';
00322 }
00323
00324 $sField = "oxartextends.oxtags".oxLang::getInstance()->getLanguageTag( $iLang );
00325
00326
00327 $sSubQ = "select {$sField} as _oxsort, 'ox_skip' as _oxval from oxartextends limit 1 union $sSubQ";
00328
00329 $sQ = "select _oxtable._oxsort, _oxtable._oxval from ( {$sSubQ} ) as _oxtable order by _oxtable._oxsort desc";
00330
00331 $aTags = array();
00332 $oRs = $oDb->execute( $sQ );
00333 while ( $oRs && $oRs->recordCount() && !$oRs->EOF ) {
00334 if ( $oRs->fields['_oxval'] != 'ox_skip' ) {
00335 $aTags[$oRs->fields['_oxsort']] = $oRs->fields['_oxval'];
00336 }
00337 $oRs->moveNext();
00338 }
00339 }
00340 return $aTags;
00341 }
00342
00354 public function getTagCloud($sArtId = null, $blExtended = false, $iLang = null )
00355 {
00356 $myUtils = oxUtils::getInstance();
00357
00358 $sTagCloud = null;
00359 $sCacheKey = $this->_getCacheKey($blExtended, $iLang );
00360 if ( $this->_sCacheKey && !$sArtId ) {
00361 $sTagCloud = $myUtils->fromFileCache( $sCacheKey );
00362 }
00363
00364 if ( !is_null($sTagCloud) ) {
00365 return $sTagCloud;
00366 }
00367
00368 $aTags = $this->getTags($sArtId, $blExtended, $iLang);
00369 if (!count($aTags)) {
00370 if ($this->_sCacheKey && !$sArtId) {
00371 $sTagCloud = false;
00372 $myUtils->toFileCache($sCacheKey, $sTagCloud);
00373 }
00374 return $sTagCloud;
00375 }
00376
00377 $iMaxHit = max( $aTags);
00378 $blSeoIsActive = $myUtils->seoIsActive();
00379 $oSeoEncoderTag = oxSeoEncoderTag::getInstance();
00380
00381 $iLang = ( $iLang !== null ) ? $iLang : oxLang::getInstance()->getBaseLanguage();
00382 $sUrl = $this->getConfig()->getShopUrl();
00383 $oStr = getStr();
00384
00385 $sTagCloud = false;
00386 foreach ( $aTags as $sTag => $sRelevance ) {
00387 if ( $blSeoIsActive ) {
00388 $sLink = $oSeoEncoderTag->getTagUrl( $sTag, $iLang );
00389 } else {
00390 $sLink = $sUrl . $oSeoEncoderTag->getStdTagUri( $sTag ) . "&lang=" . $iLang;
00391 }
00392 $iFontSize = $this->_getFontSize( $sRelevance, $iMaxHit );
00393 $sTagCloud .= "<a style='font-size:". $iFontSize ."%;' class='tagitem_". $iFontSize . "' href='$sLink'>".$oStr->htmlentities($sTag)."</a> ";
00394 }
00395
00396 if ( $this->_sCacheKey && !$sArtId ) {
00397 $myUtils->toFileCache( $sCacheKey, $sTagCloud );
00398 }
00399
00400 return $sTagCloud;
00401 }
00402
00411 protected function _getFontSize( $iHit, $iMaxHit )
00412 {
00413
00414 if ($iMaxHit <= OXTAGCLOUD_MINOCCURENCETOSHOW || !$iMaxHit) {
00415 return OXTAGCLOUD_MINFONT;
00416 }
00417
00418 $iFontDiff = OXTAGCLOUD_MAXFONT - OXTAGCLOUD_MINFONT;
00419 $iMaxHitDiff = $iMaxHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00420 $iHitDiff = $iHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00421
00422 if ($iHitDiff < 0) {
00423 $iHitDiff = 0;
00424 }
00425
00426 $iSize = round($iHitDiff * $iFontDiff / $iMaxHitDiff) + OXTAGCLOUD_MINFONT;
00427
00428 return $iSize;
00429 }
00430
00439 public function prepareTags( $sTags )
00440 {
00441 $aTags = explode( $this->_sSeparator, $sTags );
00442 $sRes = '';
00443 $oStr = getStr();
00444 foreach ( $aTags as $sTag ) {
00445 $sTag = trim($sTag);
00446 if ( ( $iLen = $oStr->strlen( $sTag ) ) ) {
00447 if ( $iLen < OXTAGCLOUD_MINTAGLENGTH ) {
00448 $sTag .= str_repeat( '_', OXTAGCLOUD_MINTAGLENGTH - $iLen );
00449 }
00450
00451 $sRes .= trim($oStr->strtolower( $sTag )) . $this->_sSeparator;
00452 }
00453 }
00454
00455 return trim( $sRes, $this->_sSeparator);
00456 }
00457
00465 public function trimTags($sTags)
00466 {
00467 $aTags = explode($this->_sSeparator, $sTags);
00468 $sRes = '';
00469 $oStr = getStr();
00470 foreach ( $aTags as $sTag ) {
00471 $sTag = trim($sTag);
00472 if ( $oStr->strlen( $sTag ) ) {
00473 $sRes .= rtrim( trim($sTag), '_' ) . $this->_sSeparator;
00474 }
00475 }
00476
00477 return trim($sRes, $this->_sSeparator);
00478 }
00479
00487 public function resetTagCache( $iLang = null )
00488 {
00489 $myUtils = oxUtils::getInstance();
00490
00491 $sCacheKey1 = $this->_getCacheKey( true, $iLang );
00492 $myUtils->toFileCache( $sCacheKey1, null );
00493
00494 $sCacheKey2 = $this->_getCacheKey( false, $iLang );
00495 $myUtils->toFileCache( $sCacheKey2, null );
00496 }
00497
00506 protected function _getCacheKey( $blExtended, $iLang = null )
00507 {
00508 return $this->_sCacheKey."_".$this->getConfig()->getShopId()."_".( ( $iLang !== null ) ? $iLang : oxLang::getInstance()->getBaseLanguage() ) ."_".$blExtended;
00509 }
00510
00511 }