00001 <?php
00002
00003 if (!defined('OXTAGCLOUD_MINFONT')) {
00004 define('OXTAGCLOUD_MINFONT', 100);
00005 define('OXTAGCLOUD_MAXFONT', 400);
00006 define('OXTAGCLOUD_MINOCCURENCETOSHOW', 2);
00007 define('OXTAGCLOUD_STARTPAGECOUNT', 20);
00008 define('OXTAGCLOUD_EXTENDEDCOUNT', 200);
00009 }
00010
00015 class oxTagCloud extends oxSuperCfg
00016 {
00022 protected $_sCacheKey = "tagcloud";
00023
00029 protected $_iMaxHit = null;
00030
00036 protected $_aCloudArray = null;
00037
00043 protected $_blExtended = false;
00044
00052 protected $_sSeparator = ',';
00053
00062 protected $_iTagMaxLength = 60;
00063
00071 protected $_sProductId = null;
00072
00080 protected $_iLangId = null;
00081
00090 protected $_aMetaChars = array('+','-','>','<','(',')','~','*','"','\'','\\','[',']','{','}',';',':','.','/','|','!','@','#','$','%','^','&','?','=','`');
00091
00095 public function __construct()
00096 {
00097 }
00098
00108 public function setProductId( $sProductId )
00109 {
00110 $this->_sProductId = $sProductId;
00111 $oTagList = oxNew('oxarticletaglist');
00112 $oTagList->setArticleId( $sProductId );
00113 $oTagList->setLanguage( $this->getLanguageId() );
00114 $this->setTagList($oTagList);
00115 }
00116
00124 public function getProductId()
00125 {
00126 return $this->_sProductId;
00127 }
00128
00138 public function setLanguageId( $iLangId )
00139 {
00140 $this->_iLangId = $iLangId;
00141 }
00142
00150 public function getLanguageId()
00151 {
00152 if ( $this->_iLangId === null ) {
00153 $this->_iLangId = oxRegistry::getLang()->getBaseLanguage();
00154 }
00155 return $this->_iLangId;
00156 }
00157
00165 public function setExtendedMode( $blExtended )
00166 {
00167 $this->_blExtended = $blExtended;
00168 }
00169
00175 public function isExtended()
00176 {
00177 return $this->_blExtended;
00178 }
00179
00187 public function setTagList( oxITagList $oTagList )
00188 {
00189 $this->_oTagList = $oTagList;
00190 }
00191
00197 public function getTagList()
00198 {
00199 return $this->_oTagList;
00200 }
00201
00209 public function setCloudArray( $aTagCloudArray )
00210 {
00211 $sCacheIdent = $this->_formCacheKey();
00212 $this->_aCloudArray[$sCacheIdent] = $aTagCloudArray;
00213 }
00214
00224 public function getCloudArray( $sProductId = null, $blExtended = null, $iLang = null )
00225 {
00226
00227 if ( $iLang !== null ) {
00228 $this->setLanguageId( $iLang );
00229 }
00230
00231 if ( $sProductId !== null ) {
00232 $this->setProductId( $sProductId );
00233 }
00234
00235 if ( $blExtended !== null ) {
00236 $this->setExtendedMode($blExtended);
00237 }
00238 $sCacheIdent = $this->_formCacheKey();
00239 if ( !isset( $this->_aCloudArray[ $sCacheIdent ] ) ) {
00240 $oTagList = $this->getTagList();
00241
00242 if ( $oTagList === null ) {
00243 $oTagList = oxNew('oxTagList');
00244 $oTagList->setLanguage( $this->getLanguageId() );
00245 }
00246 $this->_aCloudArray[$sCacheIdent] = $this->formCloudArray( $oTagList );
00247 }
00248 return $this->_aCloudArray[$sCacheIdent];
00249 }
00250
00258 public function formCloudArray( oxITagList $oTagList )
00259 {
00260
00261 if ( $oTagList->getCacheId() ) {
00262 $sCacheIdent = $this->_formCacheKey( $oTagList->getCacheId() );
00263 $myUtils = oxRegistry::getUtils();
00264
00265 $aCloudArray = $myUtils->fromFileCache( $sCacheIdent );
00266 }
00267
00268
00269 if ( $aCloudArray === null ) {
00270 $oTagList->loadList();
00271 $oTagSet = $oTagList->get();
00272 if ( count( $oTagSet->get() ) > $this->getMaxAmount() ) {
00273 $oTagSet->sortByHitCount();
00274 $oTagSet->slice( 0, $this->getMaxAmount() );
00275 }
00276 $oTagSet->sort();
00277 $aCloudArray = $oTagSet->get();
00278
00279 if ( $sCacheIdent ) {
00280 $myUtils->toFileCache( $sCacheIdent, $aCloudArray );
00281 }
00282 }
00283
00284 return $aCloudArray;
00285 }
00286
00294 public function getTagSize( $sTag )
00295 {
00296 $aCloudArray = $this->getCloudArray();
00297 if ( is_null($aCloudArray[$sTag]) ) {
00298 return 1;
00299 }
00300 $iCurrSize = $this->_getFontSize( $aCloudArray[$sTag]->getHitCount(), $this->_getMaxHit() );
00301
00302
00303 return floor( $iCurrSize / OXTAGCLOUD_MINFONT ) * OXTAGCLOUD_MINFONT;
00304 }
00305
00311 public function getMaxAmount()
00312 {
00313 if ( $this->isExtended() ) {
00314 return OXTAGCLOUD_EXTENDEDCOUNT;
00315 } else {
00316 return OXTAGCLOUD_STARTPAGECOUNT;
00317 }
00318 }
00319
00327 public function resetTagCache( $iLang = null )
00328 {
00329 if ( $iLang ) {
00330 $this->setLanguageId( $iLang );
00331 }
00332 $this->resetCache();
00333 }
00334
00340 public function resetCache()
00341 {
00342 $myUtils = oxRegistry::getUtils();
00343
00344 $sCacheId = null;
00345 if ( ( $oTagList = $this->getTagList() ) !== null ) {
00346 $sCacheId = $oTagList->getCacheId();
00347 }
00348
00349 $myUtils->toFileCache( $this->_formCacheKey( $sCacheId ), null );
00350
00351 $this->_aCloudArray = null;
00352 }
00353
00365 public function getTags( $sArtId = null, $blExtended = false, $iLang = null )
00366 {
00367 if ( $iLang !== null ) {
00368 $this->setLanguageId( $iLang );
00369 }
00370
00371 if ( $sArtId !== null ) {
00372 $this->setProductId( $sArtId );
00373 $oTagList = $this->getTagList();
00374 } else {
00375 $oTagList = oxNew('oxTagList');
00376 }
00377
00378 if ( $blExtended !== null ) {
00379 $this->setExtendedMode($blExtended);
00380 }
00381 $oTagList->load();
00382 $oTagSet = $oTagList->get();
00383 $oTagSet->sort();
00384
00385 $aTags = array();
00386 foreach ( $oTagSet->get() as $sKey => $oTag ) {
00387 $aTags[$sKey] = $oTag->getHitCount();
00388 }
00389
00390 return $aTags;
00391 }
00392
00404 public function prepareTags( $sTags )
00405 {
00406 $sTags = $this->stripMetaChars($sTags);
00407 $aTags = explode( $this->_sSeparator, $sTags );
00408 $aRes = array();
00409 $oStr = getStr();
00410
00411 foreach ( $aTags as $sTag ) {
00412 if ( ( $sTag = trim( $sTag ) ) ) {
00413 $sRes = '';
00414 $iLen = $oStr->strlen( $sTag );
00415 if ( $iLen > $this->_iTagMaxLength ) {
00416 $sTag = $oStr->substr($sTag, 0, $this->_iTagMaxLength);
00417 }
00418 $sTag = trim( $sTag );
00419 $aMatches = explode(' ', $sTag);
00420 foreach ( $aMatches as $iKey => $sMatch ) {
00421 $sRes .= $oStr->strtolower( $this->_fixTagLength($sMatch ) )." ";
00422 }
00423 $aRes[] = trim( $sRes );
00424 }
00425 }
00426
00427 return implode( $this->_sSeparator, $aRes );
00428 }
00429
00439 public function trimTags( $sTags )
00440 {
00441 $oStr = getStr();
00442 $sTags = $oStr->preg_replace( "/(\s*\,+\s*)+/", ",", trim( $sTags ) );
00443 $sRes = '';
00444
00445 if ( $oStr->preg_match_all( "/([\s\,\-]?)([^\s\,\-]+)([\s\,\-]?)/", $sTags, $aMatches ) ) {
00446 foreach ( $aMatches[0] as $iKey => $sMatch ) {
00447 $sProc = $aMatches[2][$iKey];
00448 if ( $oStr->strlen( $sProc ) <= OXTAGCLOUD_MINTAGLENGTH ) {
00449 $sProc = rtrim( $sProc, "_" );
00450 }
00451 $sRes .= $aMatches[1][$iKey] . $sProc . $aMatches[3][$iKey];
00452 }
00453 }
00454
00455 return trim( $sRes, $this->_sSeparator );
00456 }
00457
00467 public function stripMetaChars( $sText )
00468 {
00469 $oStr = getStr();
00470
00471
00472 $sText = str_replace($this->_aMetaChars, ' ', $sText);
00473
00474
00475 $sText = $oStr->preg_replace( "/\s+/", " ", trim( $sText ) );
00476
00477 return $sText;
00478 }
00479
00487 public function getTagMaxLength()
00488 {
00489 $oTags = oxNew( 'oxtag' );
00490 return $oTags->getMaxLength();
00491 }
00492
00502 public function getTagLink( $sTag )
00503 {
00504 $aCloudArray = $this->getCloudArray();
00505 return $aCloudArray[$sTag]->getLink();
00506 }
00507
00517 public function getTagTitle( $sTag )
00518 {
00519 $aCloudArray = $this->getCloudArray();
00520 return $aCloudArray[$sTag]->getTitle();
00521 }
00522
00532 public function canBeTagged( $sTagTitle )
00533 {
00534 $oTags = oxNew( 'oxarticletaglist' );
00535 $oTags->load($this->getProductId());
00536 return $oTags->canBeTagged($sTagTitle);
00537 }
00538
00548 public function _fixTagLength( $sTag )
00549 {
00550 $oStr = getStr();
00551 $sTag = trim( $sTag );
00552 $iLen = $oStr->strlen( $sTag );
00553
00554 if ( $iLen < OXTAGCLOUD_MINTAGLENGTH ) {
00555 $sTag .= str_repeat( '_', OXTAGCLOUD_MINTAGLENGTH - $iLen );
00556 }
00557
00558 return $sTag;
00559 }
00560
00571 protected function _getCacheKey( $blExtended, $iLang = null )
00572 {
00573 return $this->_sCacheKey."_".$this->getConfig()->getShopId()."_".( ( $iLang !== null ) ? $iLang : oxRegistry::getLang()->getBaseLanguage() ) ."_".($blExtended?1:0);
00574 }
00575
00583 protected function _formCacheKey( $sTagListCacheId = null )
00584 {
00585 $sExtended = $this->isExtended()? '1' : '0';
00586 return $this->_sCacheKey."_".$this->getConfig()->getShopId()."_".$sExtended."_".$sTagListCacheId;
00587 }
00588
00594 protected function _getMaxHit()
00595 {
00596 if ( $this->_iMaxHit === null ) {
00597 $aHits = array_map( array($this, '_getTagHitCount'), $this->getCloudArray());
00598 $this->_iMaxHit = max( $aHits );
00599 }
00600 return $this->_iMaxHit;
00601 }
00602
00610 protected function _getTagHitCount( $oTag )
00611 {
00612 return $oTag->getHitCount();
00613 }
00614
00623 protected function _getFontSize( $iHit, $iMaxHit )
00624 {
00625
00626 if ($iMaxHit <= OXTAGCLOUD_MINOCCURENCETOSHOW || !$iMaxHit) {
00627 return OXTAGCLOUD_MINFONT;
00628 }
00629
00630 $iFontDiff = OXTAGCLOUD_MAXFONT - OXTAGCLOUD_MINFONT;
00631 $iMaxHitDiff = $iMaxHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00632 $iHitDiff = $iHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00633
00634 if ($iHitDiff < 0) {
00635 $iHitDiff = 0;
00636 }
00637
00638 $iSize = round($iHitDiff * $iFontDiff / $iMaxHitDiff) + OXTAGCLOUD_MINFONT;
00639
00640 return $iSize;
00641 }
00642
00653 protected function _sortTags( $aTags, $iLang = null )
00654 {
00655 if ( is_array( $aTags ) && count( $aTags ) ) {
00656 $oDb = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
00657 $sSubQ = '';
00658 foreach ( $aTags as $sKey => $sTag ) {
00659 if ( $sSubQ ) {
00660 $sSubQ .= ' union all ';
00661 }
00662 $sSubQ .= 'select '.$oDb->quote( $sKey ).' as _oxsort, '.$oDb->quote( $sTag ).' as _oxval';
00663 }
00664
00665 $sViewName = getViewName( "oxartextends", $iLang );
00666
00667
00668 $sSubQ = "select {$sViewName}.oxtags as _oxsort, 'ox_skip' as _oxval from {$sViewName} limit 1 union $sSubQ";
00669 $sQ = "select _oxtable._oxsort, _oxtable._oxval from ( {$sSubQ} ) as _oxtable order by _oxtable._oxsort desc";
00670
00671 $aTags = array();
00672 $oDb->setFetchMode( oxDb::FETCH_MODE_ASSOC );
00673 $oRs = $oDb->select( $sQ );
00674 while ( $oRs && $oRs->recordCount() && !$oRs->EOF ) {
00675 if ( $oRs->fields['_oxval'] != 'ox_skip' ) {
00676 $aTags[$oRs->fields['_oxsort']] = $oRs->fields['_oxval'];
00677 }
00678 $oRs->moveNext();
00679 }
00680 }
00681 return $aTags;
00682 }
00683
00684 }