oxtagcloud.php

Go to the documentation of this file.
00001 <?php
00002 
00003 if (!defined('OXTAGCLOUD_MINFONT')) {
00004     define('OXTAGCLOUD_MINFONT', 100);
00005     define('OXTAGCLOUD_MAXFONT', 400);
00006     define('OXTAGCLOUD_MINOCCURENCETOSHOW', 2);
00007     //depends on mysql server configuration
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         // collecting cloud info
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         // checking if current data is allready loaded
00174         $sCacheIdent = $this->_getCacheKey( $blExtended, $iLang )."_".$sProductId;
00175         if ( !isset( $this->_aCloudArray[$sCacheIdent] ) ) {
00176 
00177             $myUtils = oxUtils::getInstance();
00178 
00179             // checking cache
00180             $aCloudArray = ( !$sProductId ) ? $myUtils->fromFileCache( $sCacheIdent ) : null;
00181 
00182             // loading cloud info
00183             if ( $aCloudArray === null ) {
00184                 $aCloudArray = $this->getTags( $sProductId, $blExtended, $iLang );
00185                 // updating cache
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 ) . "&amp;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         // calculating min size
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         //taking only top tags
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             // forcing collation
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         //handling special case
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         // Remove meta chars
00406         $sText = str_replace($this->_aMetaChars, ' ', $sText);
00407 
00408         // Replace multiple spaces with single space
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 }