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     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         // used to make deprecated functionality working
00227         if ( $iLang !== null ) {
00228             $this->setLanguageId( $iLang );
00229         }
00230         // used to make deprecated functionality working
00231         if ( $sProductId !== null ) {
00232             $this->setProductId( $sProductId );
00233         }
00234         // used to make deprecated functionality working
00235         if ( $blExtended !== null ) {
00236             $this->setExtendedMode($blExtended);
00237         }
00238         $sCacheIdent = $this->_formCacheKey();
00239         if ( !isset( $this->_aCloudArray[ $sCacheIdent ] ) ) {
00240             $oTagList = $this->getTagList();
00241             // used to make deprecated functionality working
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         // checking if current data is allready loaded
00261         if ( $oTagList->getCacheId() ) {
00262             $sCacheIdent = $this->_formCacheKey( $oTagList->getCacheId() );
00263             $myUtils = oxRegistry::getUtils();
00264             // checking cache
00265             $aCloudArray = $myUtils->fromFileCache( $sCacheIdent );
00266         }
00267 
00268         // loading cloud info
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             // updating cache
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         // calculating min size
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         // used to make deprecated functionality working
00371         if ( $sArtId !== null ) {
00372             $this->setProductId( $sArtId );
00373             $oTagList = $this->getTagList();
00374         } else {
00375             $oTagList = oxNew('oxTagList');
00376         }
00377         // used to make deprecated functionality working
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         // Remove meta chars
00472         $sText = str_replace($this->_aMetaChars, ' ', $sText);
00473 
00474         // Replace multiple spaces with single space
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         //handling special case
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             // forcing collation
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 }