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
00285 $oArticle = oxNew( 'oxarticle' );
00286 $oArticle->setLanguage( $iLang );
00287 $sArtActive = $oArticle->getActiveCheckQuery(true);
00288
00289 $sQ = "select {$sViewName}.oxtags as oxtags from $sArtView as oxarticles left join {$sViewName} on oxarticles.oxid={$sViewName}.oxid where $sArtActive AND $sArticleSelect";
00290 $rs = $oDb->execute( $sQ );
00291 $aTags = array();
00292 while ( $rs && $rs->recordCount() && !$rs->EOF ) {
00293 $sTags = $this->trimTags( $rs->fields['oxtags'] );
00294 $aArticleTags = explode( $this->_sSeparator, $sTags );
00295 foreach ( $aArticleTags as $sTag ) {
00296 if ( trim( $sTag ) ) {
00297 ++$aTags[$sTag];
00298 }
00299 }
00300 $rs->moveNext();
00301 }
00302
00303
00304 if ( $iAmount ) {
00305 arsort( $aTags );
00306 $aTags = array_slice( $aTags, 0, $iAmount, true );
00307 }
00308
00309 $aTags = $this->_sortTags( $aTags );
00310 return $aTags;
00311 }
00312
00321 protected function _sortTags( $aTags, $iLang = null )
00322 {
00323 if ( is_array( $aTags ) && count( $aTags ) ) {
00324 $oDb = oxDb::getDb( true );
00325 $sSubQ = '';
00326 foreach ( $aTags as $sKey => $sTag ) {
00327 if ( $sSubQ ) {
00328 $sSubQ .= ' union all ';
00329 }
00330 $sSubQ .= 'select '.$oDb->quote( $sKey ).' as _oxsort, '.$oDb->quote( $sTag ).' as _oxval';
00331 }
00332
00333 $sViewName = getViewName( "oxartextends", $iLang );
00334
00335
00336 $sSubQ = "select {$sViewName}.oxtags as _oxsort, 'ox_skip' as _oxval from {$sViewName} limit 1 union $sSubQ";
00337 $sQ = "select _oxtable._oxsort, _oxtable._oxval from ( {$sSubQ} ) as _oxtable order by _oxtable._oxsort desc";
00338
00339 $aTags = array();
00340 $oRs = $oDb->execute( $sQ );
00341 while ( $oRs && $oRs->recordCount() && !$oRs->EOF ) {
00342 if ( $oRs->fields['_oxval'] != 'ox_skip' ) {
00343 $aTags[$oRs->fields['_oxsort']] = $oRs->fields['_oxval'];
00344 }
00345 $oRs->moveNext();
00346 }
00347 }
00348 return $aTags;
00349 }
00350
00359 protected function _getFontSize( $iHit, $iMaxHit )
00360 {
00361
00362 if ($iMaxHit <= OXTAGCLOUD_MINOCCURENCETOSHOW || !$iMaxHit) {
00363 return OXTAGCLOUD_MINFONT;
00364 }
00365
00366 $iFontDiff = OXTAGCLOUD_MAXFONT - OXTAGCLOUD_MINFONT;
00367 $iMaxHitDiff = $iMaxHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00368 $iHitDiff = $iHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00369
00370 if ($iHitDiff < 0) {
00371 $iHitDiff = 0;
00372 }
00373
00374 $iSize = round($iHitDiff * $iFontDiff / $iMaxHitDiff) + OXTAGCLOUD_MINFONT;
00375
00376 return $iSize;
00377 }
00378
00386 public function _fixTagLength( $sTag )
00387 {
00388 $oStr = getStr();
00389 $sTag = trim( $sTag );
00390 $iLen = $oStr->strlen( $sTag );
00391
00392 if ( $iLen < OXTAGCLOUD_MINTAGLENGTH ) {
00393 $sTag .= str_repeat( '_', OXTAGCLOUD_MINTAGLENGTH - $iLen );
00394 }
00395
00396 return $sTag;
00397 }
00398
00406 public function stripMetaChars( $sText )
00407 {
00408 $oStr = getStr();
00409
00410
00411 $sText = str_replace($this->_aMetaChars, ' ', $sText);
00412
00413
00414 $sText = $oStr->preg_replace( "/\s+/", " ", trim( $sText ) );
00415
00416 return $sText;
00417 }
00418
00427 public function prepareTags( $sTags )
00428 {
00429 $sTags = $this->stripMetaChars($sTags);
00430 $aTags = explode( $this->_sSeparator, $sTags );
00431 $aRes = array();
00432 $oStr = getStr();
00433
00434 foreach ( $aTags as $sTag ) {
00435 if ( ( $sTag = trim( $sTag ) ) ) {
00436 $sRes = '';
00437 $aMatches = explode(' ', $sTag);
00438 foreach ( $aMatches as $iKey => $sMatch ) {
00439 $sRes .= $oStr->strtolower( $this->_fixTagLength($sMatch ) )." ";
00440 }
00441 $aRes[] = trim( $sRes );
00442 }
00443 }
00444
00445 return implode( $this->_sSeparator, $aRes );
00446 }
00447
00455 public function trimTags( $sTags )
00456 {
00457 $oStr = getStr();
00458 $sTags = $oStr->preg_replace( "/(\s*\,+\s*)+/", ",", trim( $sTags ) );
00459 $sRes = '';
00460
00461 if ( $oStr->preg_match_all( "/([\s\,\-]?)([^\s\,\-]+)([\s\,\-]?)/", $sTags, $aMatches ) ) {
00462 foreach ( $aMatches[0] as $iKey => $sMatch ) {
00463 $sProc = $aMatches[2][$iKey];
00464 if ( $oStr->strlen( $sProc ) <= OXTAGCLOUD_MINTAGLENGTH ) {
00465 $sProc = rtrim( $sProc, "_" );
00466
00467 }
00468 $sRes .= $aMatches[1][$iKey] . $sProc . $aMatches[3][$iKey];
00469 }
00470 }
00471
00472 return trim( $sRes, $this->_sSeparator );
00473 }
00474
00482 public function resetTagCache( $iLang = null )
00483 {
00484 $myUtils = oxUtils::getInstance();
00485
00486 $sCacheKey1 = $this->_getCacheKey( true, $iLang );
00487 $myUtils->toFileCache( $sCacheKey1, null );
00488
00489 $sCacheKey2 = $this->_getCacheKey( false, $iLang );
00490 $myUtils->toFileCache( $sCacheKey2, null );
00491 }
00492
00501 protected function _getCacheKey( $blExtended, $iLang = null )
00502 {
00503 return $this->_sCacheKey."_".$this->getConfig()->getShopId()."_".( ( $iLang !== null ) ? $iLang : oxLang::getInstance()->getBaseLanguage() ) ."_".$blExtended;
00504 }
00505
00513 public function canBeTagged( $sTagTitle )
00514 {
00515 $aProducts = oxSession::getVar("aTaggedProducts");
00516 if ( isset($aProducts) && $aTags = $aProducts[$this->getProductId()]) {
00517 if ( $aTags[$sTagTitle] == 1 ) {
00518 return false;
00519 }
00520 }
00521 return true;
00522 }
00523
00524 }