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
00075 protected $_aMetaChars = array('+','-','>','<','(',')','~','*','"','\'','\\');
00076
00081 public function __construct()
00082 {
00083 $sSeparator = $this->getConfig()->getConfigParam("sTagSeparator");
00084 if ($sSeparator)
00085 $this->_sSeparator = $sSeparator;
00086 }
00087
00095 public function setProductId( $sProductId )
00096 {
00097 $this->_sProductId = $sProductId;
00098 }
00099
00107 public function setLanguageId( $iLangId )
00108 {
00109 $this->_iLangId = $iLangId;
00110 }
00111
00119 public function setExtendedMode( $blExtended )
00120 {
00121 $this->_blExtended = $blExtended;
00122 }
00123
00129 public function getLanguageId()
00130 {
00131 if ( $this->_iLangId === null ) {
00132 $this->_iLangId = oxLang::getInstance()->getBaseLanguage();
00133 }
00134 return $this->_iLangId;
00135 }
00136
00142 public function getProductId()
00143 {
00144 return $this->_sProductId;
00145 }
00146
00152 public function isExtended()
00153 {
00154 return $this->_blExtended;
00155 }
00156
00166 public function getCloudArray( $sProductId = null, $blExtended = null, $iLang = null )
00167 {
00168
00169 $iLang = ( $iLang === null ) ? (int) $this->getLanguageId() : $iLang;
00170 $blExtended = ( $blExtended === null ) ? $this->isExtended() : $blExtended;
00171 $sProductId = ( $sProductId === null ) ? (string) $this->getProductId() : $sProductId;
00172
00173
00174 $sCacheIdent = $this->_getCacheKey( $blExtended, $iLang )."_".$sProductId;
00175 if ( !isset( $this->_aCloudArray[$sCacheIdent] ) ) {
00176
00177 $myUtils = oxUtils::getInstance();
00178
00179
00180 $aCloudArray = ( !$sProductId ) ? $myUtils->fromFileCache( $sCacheIdent ) : null;
00181
00182
00183 if ( $aCloudArray === null ) {
00184 $aCloudArray = $this->getTags( $sProductId, $blExtended, $iLang );
00185
00186 if ( !$sProductId ) {
00187 $myUtils->toFileCache( $sCacheIdent, $aCloudArray );
00188 }
00189 }
00190
00191 $this->_aCloudArray[$sCacheIdent] = $aCloudArray;
00192 }
00193 return $this->_aCloudArray[$sCacheIdent];
00194 }
00195
00203 public function getTagLink( $sTag )
00204 {
00205 $oSeoEncoderTag = oxSeoEncoderTag::getInstance();
00206 $iLang = $this->getLanguageId();
00207
00208 $sUrl = false;
00209 if ( oxUtils::getInstance()->seoIsActive() ) {
00210 $sUrl = $oSeoEncoderTag->getTagUrl( $sTag, $iLang );
00211 }
00212 return $sUrl ? $sUrl : $this->getConfig()->getShopUrl() . $oSeoEncoderTag->getStdTagUri( $sTag ) . "&lang=" . $iLang;
00213 }
00214
00222 public function getTagTitle( $sTag )
00223 {
00224 return getStr()->htmlentities( $sTag );
00225 }
00226
00232 protected function _getMaxHit()
00233 {
00234 if ( $this->_iMaxHit === null ) {
00235 $this->_iMaxHit = max( $this->getCloudArray() );
00236 }
00237 return $this->_iMaxHit;
00238 }
00239
00247 public function getTagSize( $sTag )
00248 {
00249 $aCloudArray = $this->getCloudArray();
00250 $iCurrSize = $this->_getFontSize( $aCloudArray[ $sTag ], $this->_getMaxHit() );
00251
00252
00253 return floor( $iCurrSize / OXTAGCLOUD_MINFONT ) * OXTAGCLOUD_MINFONT;
00254 }
00255
00256
00266 public function getTags( $sArtId = null, $blExtended = false, $iLang = null )
00267 {
00268 $oDb = oxDb::getDb(true);
00269 if ($blExtended) {
00270 $iAmount = OXTAGCLOUD_EXTENDEDCOUNT;
00271 } else {
00272 $iAmount = OXTAGCLOUD_STARTPAGECOUNT;
00273 }
00274
00275 $sArtView = getViewName( 'oxarticles', $iLang );
00276 $sViewName = getViewName( 'oxartextends', $iLang );
00277
00278 $sArticleSelect = " 1 ";
00279 if ( $sArtId ) {
00280 $sArticleSelect = " oxarticles.oxid = ".$oDb->quote( $sArtId )." ";
00281 $iAmount = 0;
00282 }
00283
00284 $sQ = "select {$sViewName}.oxtags as oxtags from $sArtView as oxarticles left join {$sViewName} on oxarticles.oxid={$sViewName}.oxid where oxarticles.oxactive=1 AND $sArticleSelect";
00285 $rs = $oDb->execute( $sQ );
00286 $aTags = array();
00287 while ( $rs && $rs->recordCount() && !$rs->EOF ) {
00288 $sTags = $this->trimTags( $rs->fields['oxtags'] );
00289 $aArticleTags = explode( $this->_sSeparator, $sTags );
00290 foreach ( $aArticleTags as $sTag ) {
00291 if ( trim( $sTag ) ) {
00292 ++$aTags[$sTag];
00293 }
00294 }
00295 $rs->moveNext();
00296 }
00297
00298
00299 if ( $iAmount ) {
00300 arsort( $aTags );
00301 $aTags = array_slice( $aTags, 0, $iAmount, true );
00302 }
00303
00304 $aTags = $this->_sortTags( $aTags );
00305 return $aTags;
00306 }
00307
00316 protected function _sortTags( $aTags, $iLang = null )
00317 {
00318 if ( is_array( $aTags ) && count( $aTags ) ) {
00319 $oDb = oxDb::getDb( true );
00320 $sSubQ = '';
00321 foreach ( $aTags as $sKey => $sTag ) {
00322 if ( $sSubQ ) {
00323 $sSubQ .= ' union all ';
00324 }
00325 $sSubQ .= 'select '.$oDb->quote( $sKey ).' as _oxsort, '.$oDb->quote( $sTag ).' as _oxval';
00326 }
00327
00328 $sViewName = getViewName( "oxartextends", $iLang );
00329
00330
00331 $sSubQ = "select {$sViewName}.oxtags as _oxsort, 'ox_skip' as _oxval from {$sViewName} limit 1 union $sSubQ";
00332 $sQ = "select _oxtable._oxsort, _oxtable._oxval from ( {$sSubQ} ) as _oxtable order by _oxtable._oxsort desc";
00333
00334 $aTags = array();
00335 $oRs = $oDb->execute( $sQ );
00336 while ( $oRs && $oRs->recordCount() && !$oRs->EOF ) {
00337 if ( $oRs->fields['_oxval'] != 'ox_skip' ) {
00338 $aTags[$oRs->fields['_oxsort']] = $oRs->fields['_oxval'];
00339 }
00340 $oRs->moveNext();
00341 }
00342 }
00343 return $aTags;
00344 }
00345
00354 protected function _getFontSize( $iHit, $iMaxHit )
00355 {
00356
00357 if ($iMaxHit <= OXTAGCLOUD_MINOCCURENCETOSHOW || !$iMaxHit) {
00358 return OXTAGCLOUD_MINFONT;
00359 }
00360
00361 $iFontDiff = OXTAGCLOUD_MAXFONT - OXTAGCLOUD_MINFONT;
00362 $iMaxHitDiff = $iMaxHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00363 $iHitDiff = $iHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00364
00365 if ($iHitDiff < 0) {
00366 $iHitDiff = 0;
00367 }
00368
00369 $iSize = round($iHitDiff * $iFontDiff / $iMaxHitDiff) + OXTAGCLOUD_MINFONT;
00370
00371 return $iSize;
00372 }
00373
00381 public function _fixTagLength( $sTag )
00382 {
00383 $oStr = getStr();
00384 $sTag = trim( $sTag );
00385 $iLen = $oStr->strlen( $sTag );
00386
00387 if ( $iLen < OXTAGCLOUD_MINTAGLENGTH ) {
00388 $sTag .= str_repeat( '_', OXTAGCLOUD_MINTAGLENGTH - $iLen );
00389 }
00390
00391 return $sTag;
00392 }
00393
00401 public function stripMetaChars( $sText )
00402 {
00403 $oStr = getStr();
00404
00405
00406 $sText = str_replace($this->_aMetaChars, ' ', $sText);
00407
00408
00409 $sText = $oStr->preg_replace( "/\s+/", " ", trim( $sText ) );
00410
00411 return $sText;
00412 }
00413
00422 public function prepareTags( $sTags )
00423 {
00424 $sTags = $this->stripMetaChars($sTags);
00425 $aTags = explode( $this->_sSeparator, $sTags );
00426 $aRes = array();
00427 $oStr = getStr();
00428
00429 foreach ( $aTags as $sTag ) {
00430 if ( ( $sTag = trim( $sTag ) ) ) {
00431 $sRes = '';
00432 $aMatches = explode(' ', $sTag);
00433 foreach ( $aMatches as $iKey => $sMatch ) {
00434 $sRes .= $oStr->strtolower( $this->_fixTagLength($sMatch ) )." ";
00435 }
00436 $aRes[] = trim( $sRes );
00437 }
00438 }
00439
00440 return implode( $this->_sSeparator, $aRes );
00441 }
00442
00450 public function trimTags( $sTags )
00451 {
00452 $oStr = getStr();
00453 $sTags = $oStr->preg_replace( "/(\s*\,+\s*)+/", ",", trim( $sTags ) );
00454 $sRes = '';
00455
00456 if ( $oStr->preg_match_all( "/([\s\,\-]?)([^\s\,\-]+)([\s\,\-]?)/", $sTags, $aMatches ) ) {
00457 foreach ( $aMatches[0] as $iKey => $sMatch ) {
00458 $sProc = $aMatches[2][$iKey];
00459 if ( $oStr->strlen( $sProc ) <= OXTAGCLOUD_MINTAGLENGTH ) {
00460 $sProc = rtrim( $sProc, "_" );
00461
00462 }
00463 $sRes .= $aMatches[1][$iKey] . $sProc . $aMatches[3][$iKey];
00464 }
00465 }
00466
00467 return trim( $sRes, $this->_sSeparator );
00468 }
00469
00477 public function resetTagCache( $iLang = null )
00478 {
00479 $myUtils = oxUtils::getInstance();
00480
00481 $sCacheKey1 = $this->_getCacheKey( true, $iLang );
00482 $myUtils->toFileCache( $sCacheKey1, null );
00483
00484 $sCacheKey2 = $this->_getCacheKey( false, $iLang );
00485 $myUtils->toFileCache( $sCacheKey2, null );
00486 }
00487
00496 protected function _getCacheKey( $blExtended, $iLang = null )
00497 {
00498 return $this->_sCacheKey."_".$this->getConfig()->getShopId()."_".( ( $iLang !== null ) ? $iLang : oxLang::getInstance()->getBaseLanguage() ) ."_".$blExtended;
00499 }
00500
00508 public function canBeTagged( $sTagTitle )
00509 {
00510 $aProducts = oxSession::getVar("aTaggedProducts");
00511 if ( isset($aProducts) && $aTags = $aProducts[$this->getProductId()]) {
00512 if ( $aTags[$sTagTitle] == 1 ) {
00513 return false;
00514 }
00515 }
00516 return true;
00517 }
00518
00519 }