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 
00066     protected $_sSeparator = ',';
00067 
00074     protected $_iTagMaxLength = 60;
00075 
00083     protected $_aMetaChars = array('+','-','>','<','(',')','~','*','"','\'','\\','[',']','{','}',';',':','.','/','|','!','@','#','$','%','^','&','?','=','`');
00084 
00089     public function __construct()
00090     {
00091         $sSeparator = $this->getConfig()->getConfigParam("sTagSeparator");
00092         if ($sSeparator)
00093             $this->_sSeparator = $sSeparator;
00094     }
00095 
00103     public function setProductId( $sProductId )
00104     {
00105         $this->_sProductId = $sProductId;
00106     }
00107 
00115     public function setLanguageId( $iLangId )
00116     {
00117         $this->_iLangId = $iLangId;
00118     }
00119 
00127     public function setExtendedMode( $blExtended )
00128     {
00129         $this->_blExtended = $blExtended;
00130     }
00131 
00137     public function getLanguageId()
00138     {
00139         if ( $this->_iLangId === null ) {
00140             $this->_iLangId = oxRegistry::getLang()->getBaseLanguage();
00141         }
00142         return $this->_iLangId;
00143     }
00144 
00150     public function getProductId()
00151     {
00152         return $this->_sProductId;
00153     }
00154 
00160     public function getTagMaxLength()
00161     {
00162         return $this->_iTagMaxLength;
00163     }
00164 
00170     public function isExtended()
00171     {
00172         return $this->_blExtended;
00173     }
00174 
00184     public function getCloudArray( $sProductId = null, $blExtended = null, $iLang = null )
00185     {
00186         // collecting cloud info
00187         $iLang      = ( $iLang === null ) ? (int) $this->getLanguageId() : $iLang;
00188         $blExtended = ( $blExtended === null ) ? $this->isExtended() : $blExtended;
00189         $sProductId = ( $sProductId === null ) ? (string) $this->getProductId() : $sProductId;
00190 
00191         // checking if current data is allready loaded
00192         $sCacheIdent = $this->_getCacheKey( $blExtended, $iLang )."_".$sProductId;
00193         if ( !isset( $this->_aCloudArray[$sCacheIdent] ) ) {
00194 
00195             $myUtils = oxRegistry::getUtils();
00196 
00197             // checking cache
00198             $aCloudArray = ( !$sProductId ) ? $myUtils->fromFileCache( $sCacheIdent ) : null;
00199 
00200             // loading cloud info
00201             if ( $aCloudArray === null ) {
00202                 $aCloudArray = $this->getTags( $sProductId, $blExtended, $iLang );
00203                 // updating cache
00204                 if ( !$sProductId ) {
00205                     $myUtils->toFileCache( $sCacheIdent, $aCloudArray );
00206                 }
00207             }
00208 
00209             $this->_aCloudArray[$sCacheIdent] = $aCloudArray;
00210         }
00211         return $this->_aCloudArray[$sCacheIdent];
00212     }
00213 
00221     public function getTagLink( $sTag )
00222     {
00223         $oSeoEncoderTag = oxRegistry::get("oxSeoEncoderTag");
00224         $iLang = $this->getLanguageId();
00225 
00226         $sUrl = false;
00227         if ( oxRegistry::getUtils()->seoIsActive() ) {
00228             $sUrl = $oSeoEncoderTag->getTagUrl( $sTag, $iLang );
00229         }
00230         return $sUrl ? $sUrl : $this->getConfig()->getShopUrl() . $oSeoEncoderTag->getStdTagUri( $sTag ) . "&amp;lang=" . $iLang;
00231     }
00232 
00240     public function getTagTitle( $sTag )
00241     {
00242         return getStr()->htmlentities( $sTag );
00243     }
00244 
00250     protected function _getMaxHit()
00251     {
00252         if ( $this->_iMaxHit === null ) {
00253             $this->_iMaxHit = max( $this->getCloudArray() );
00254         }
00255         return $this->_iMaxHit;
00256     }
00257 
00265     public function getTagSize( $sTag )
00266     {
00267         $aCloudArray = $this->getCloudArray();
00268         $iCurrSize = $this->_getFontSize( $aCloudArray[ $sTag ], $this->_getMaxHit() );
00269 
00270         // calculating min size
00271         return floor( $iCurrSize / OXTAGCLOUD_MINFONT ) * OXTAGCLOUD_MINFONT;
00272     }
00273 
00274 
00284     public function getTags( $sArtId = null, $blExtended = false, $iLang = null )
00285     {
00286         $oDb = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
00287 
00288         if ($blExtended) {
00289             $iAmount = OXTAGCLOUD_EXTENDEDCOUNT;
00290         } else {
00291             $iAmount = OXTAGCLOUD_STARTPAGECOUNT;
00292         }
00293 
00294         $sArtView  = getViewName( 'oxarticles', $iLang );
00295         $sViewName = getViewName( 'oxartextends', $iLang );
00296 
00297         // check if article is still active
00298         $oArticle   = oxNew( 'oxarticle' );
00299         $oArticle->setLanguage( $iLang );
00300         $sArtActive = $oArticle->getActiveCheckQuery(true);
00301 
00302 
00303         $sQ = "SELECT {$sViewName}.`oxtags` AS `oxtags`
00304             FROM {$sArtView} AS `oxarticles`
00305                 LEFT JOIN {$sViewName} ON `oxarticles`.`oxid` = {$sViewName}.`oxid`
00306             WHERE `oxarticles`.`oxactive` = 1 AND $sArtActive";
00307 
00308         if ( $sArtId ) {
00309             $sQ = "SELECT {$sViewName}.`oxtags` AS `oxtags` FROM {$sViewName} WHERE `oxid` = " . $oDb->quote( $sArtId );
00310             $iAmount = 0;
00311         }
00312 
00313         $oDb->setFetchMode( oxDb::FETCH_MODE_ASSOC );
00314         $rs = $oDb->select( $sQ );
00315         $aTags = array();
00316         while ( $rs && $rs->recordCount() && !$rs->EOF ) {
00317             $sTags = $this->trimTags( $rs->fields['oxtags'] );
00318             $aArticleTags = explode( $this->_sSeparator, $sTags );
00319             foreach ( $aArticleTags as $sTag ) {
00320                 if ( trim( $sTag ) ) {
00321                     ++$aTags[$sTag];
00322                 }
00323             }
00324             $rs->moveNext();
00325         }
00326 
00327         //taking only top tags
00328         if ( $iAmount ) {
00329             arsort( $aTags );
00330             $aTags = array_slice( $aTags, 0, $iAmount, true );
00331         }
00332 
00333         $aTags = $this->_sortTags( $aTags );
00334         return $aTags;
00335     }
00336 
00345     protected function _sortTags( $aTags, $iLang = null )
00346     {
00347         if ( is_array( $aTags ) && count( $aTags ) ) {
00348             $oDb = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
00349             $sSubQ = '';
00350             foreach ( $aTags as $sKey => $sTag ) {
00351                 if ( $sSubQ ) {
00352                     $sSubQ .= ' union all ';
00353                 }
00354                 $sSubQ .= 'select '.$oDb->quote( $sKey ).' as _oxsort, '.$oDb->quote( $sTag ).' as _oxval';
00355             }
00356 
00357             $sViewName = getViewName( "oxartextends", $iLang );
00358 
00359             // forcing collation
00360             $sSubQ = "select {$sViewName}.oxtags as _oxsort, 'ox_skip' as _oxval from {$sViewName} limit 1 union $sSubQ";
00361             $sQ = "select _oxtable._oxsort, _oxtable._oxval from ( {$sSubQ} ) as _oxtable order by _oxtable._oxsort desc";
00362 
00363             $aTags = array();
00364             $oDb->setFetchMode( oxDb::FETCH_MODE_ASSOC );
00365             $oRs = $oDb->select( $sQ );
00366             while ( $oRs && $oRs->recordCount() && !$oRs->EOF ) {
00367                 if ( $oRs->fields['_oxval'] != 'ox_skip' ) {
00368                     $aTags[$oRs->fields['_oxsort']] = $oRs->fields['_oxval'];
00369                 }
00370                 $oRs->moveNext();
00371             }
00372         }
00373         return $aTags;
00374     }
00375 
00384     protected function _getFontSize( $iHit, $iMaxHit )
00385     {
00386         //handling special case
00387         if ($iMaxHit <= OXTAGCLOUD_MINOCCURENCETOSHOW || !$iMaxHit) {
00388             return OXTAGCLOUD_MINFONT;
00389         }
00390 
00391         $iFontDiff = OXTAGCLOUD_MAXFONT - OXTAGCLOUD_MINFONT;
00392         $iMaxHitDiff = $iMaxHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00393         $iHitDiff = $iHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
00394 
00395         if ($iHitDiff < 0) {
00396             $iHitDiff = 0;
00397         }
00398 
00399         $iSize = round($iHitDiff * $iFontDiff / $iMaxHitDiff) + OXTAGCLOUD_MINFONT;
00400 
00401         return $iSize;
00402     }
00403 
00411     public function _fixTagLength( $sTag )
00412     {
00413         $oStr = getStr();
00414         $sTag = trim( $sTag );
00415         $iLen = $oStr->strlen( $sTag );
00416 
00417         if ( $iLen < OXTAGCLOUD_MINTAGLENGTH ) {
00418             $sTag .= str_repeat( '_', OXTAGCLOUD_MINTAGLENGTH - $iLen );
00419         }
00420 
00421         return $sTag;
00422     }
00423 
00431     public function stripMetaChars( $sText )
00432     {
00433         $oStr  = getStr();
00434 
00435         // Remove meta chars
00436         $sText = str_replace($this->_aMetaChars, ' ', $sText);
00437 
00438         // Replace multiple spaces with single space
00439         $sText = $oStr->preg_replace( "/\s+/", " ", trim( $sText ) );
00440 
00441         return $sText;
00442     }
00443 
00453     public function prepareTags( $sTags )
00454     {
00455         $sTags = $this->stripMetaChars($sTags);
00456         $aTags = explode( $this->_sSeparator, $sTags );
00457         $aRes = array();
00458         $oStr = getStr();
00459 
00460         foreach ( $aTags as $sTag ) {
00461             if ( ( $sTag = trim( $sTag ) ) ) {
00462                 $sRes = '';
00463                 $iLen = $oStr->strlen( $sTag );
00464                 if ( $iLen > $this->_iTagMaxLength ) {
00465                     $sTag = $oStr->substr($sTag, 0, $this->_iTagMaxLength);
00466                 }
00467                 $sTag = trim( $sTag );
00468                 $aMatches = explode(' ', $sTag);
00469                 foreach ( $aMatches as $iKey => $sMatch ) {
00470                     $sRes .= $oStr->strtolower( $this->_fixTagLength($sMatch ) )." ";
00471                 }
00472                 $aRes[] = trim( $sRes );
00473             }
00474         }
00475 
00476         return implode( $this->_sSeparator, $aRes );
00477     }
00478 
00486     public function trimTags( $sTags )
00487     {
00488         $oStr = getStr();
00489         $sTags = $oStr->preg_replace( "/(\s*\,+\s*)+/", ",", trim( $sTags ) );
00490         $sRes = '';
00491 
00492         if ( $oStr->preg_match_all( "/([\s\,\-]?)([^\s\,\-]+)([\s\,\-]?)/", $sTags, $aMatches ) ) {
00493             foreach ( $aMatches[0] as $iKey => $sMatch ) {
00494                 $sProc = $aMatches[2][$iKey];
00495                 if ( $oStr->strlen( $sProc ) <= OXTAGCLOUD_MINTAGLENGTH ) {
00496                     $sProc = rtrim( $sProc, "_" );
00497 
00498                 }
00499                 $sRes .= $aMatches[1][$iKey] . $sProc . $aMatches[3][$iKey];
00500             }
00501         }
00502 
00503         return trim( $sRes, $this->_sSeparator );
00504     }
00505 
00513     public function resetTagCache( $iLang = null )
00514     {
00515         $myUtils = oxRegistry::getUtils();
00516 
00517         $sCacheKey1 = $this->_getCacheKey( true, $iLang );
00518         $myUtils->toFileCache( $sCacheKey1, null );
00519 
00520         $sCacheKey2 = $this->_getCacheKey( false, $iLang );
00521         $myUtils->toFileCache( $sCacheKey2, null );
00522     }
00523 
00532     protected function _getCacheKey( $blExtended, $iLang = null )
00533     {
00534         return $this->_sCacheKey."_".$this->getConfig()->getShopId()."_".( ( $iLang !== null ) ? $iLang : oxRegistry::getLang()->getBaseLanguage() ) ."_".$blExtended;
00535     }
00536 
00544     public function canBeTagged( $sTagTitle )
00545     {
00546         $aProducts = oxSession::getVar("aTaggedProducts");
00547         if ( isset($aProducts) && $aTags = $aProducts[$this->getProductId()]) {
00548             if ( $aTags[$sTagTitle] == 1 ) {
00549                 return false;
00550             }
00551         }
00552         return true;
00553     }
00554 
00555 }