OXID eShop CE  4.8.12
 All Classes Files Functions Variables Pages
oxtagcloud.php
Go to the documentation of this file.
1 <?php
2 
3 if (!defined('OXTAGCLOUD_MINFONT')) {
4  define('OXTAGCLOUD_MINFONT', 100);
5  define('OXTAGCLOUD_MAXFONT', 400);
6  define('OXTAGCLOUD_MINOCCURENCETOSHOW', 2);
7  define('OXTAGCLOUD_STARTPAGECOUNT', 20);
8  define('OXTAGCLOUD_EXTENDEDCOUNT', 200);
9 }
10 
15 class oxTagCloud extends oxSuperCfg
16 {
22  protected $_sCacheKey = "tagcloud";
23 
29  protected $_iMaxHit = null;
30 
36  protected $_aCloudArray = null;
37 
43  protected $_blExtended = false;
44 
52  protected $_sSeparator = ',';
53 
62  protected $_iTagMaxLength = 60;
63 
71  protected $_sProductId = null;
72 
80  protected $_iLangId = null;
81 
90  protected $_aMetaChars = array('+','-','>','<','(',')','~','*','"','\'','\\','[',']','{','}',';',':','.','/','|','!','@','#','$','%','^','&','?','=','`');
91 
95  public function __construct()
96  {
97  }
98 
108  public function setProductId( $sProductId )
109  {
110  $this->_sProductId = $sProductId;
111  $oTagList = oxNew('oxarticletaglist');
112  $oTagList->setArticleId( $sProductId );
113  $oTagList->setLanguage( $this->getLanguageId() );
114  $this->setTagList($oTagList);
115  }
116 
124  public function getProductId()
125  {
126  return $this->_sProductId;
127  }
128 
138  public function setLanguageId( $iLangId )
139  {
140  $this->_iLangId = $iLangId;
141  }
142 
150  public function getLanguageId()
151  {
152  if ( $this->_iLangId === null ) {
153  $this->_iLangId = oxRegistry::getLang()->getBaseLanguage();
154  }
155  return $this->_iLangId;
156  }
157 
165  public function setExtendedMode( $blExtended )
166  {
167  $this->_blExtended = $blExtended;
168  }
169 
175  public function isExtended()
176  {
177  return $this->_blExtended;
178  }
179 
187  public function setTagList( oxITagList $oTagList )
188  {
189  $this->_oTagList = $oTagList;
190  }
191 
197  public function getTagList()
198  {
199  return $this->_oTagList;
200  }
201 
209  public function setCloudArray( $aTagCloudArray )
210  {
211  $sCacheIdent = $this->_formCacheKey();
212  $this->_aCloudArray[$sCacheIdent] = $aTagCloudArray;
213  }
214 
224  public function getCloudArray( $sProductId = null, $blExtended = null, $iLang = null )
225  {
226  // used to make deprecated functionality working
227  if ( $iLang !== null ) {
228  $this->setLanguageId( $iLang );
229  }
230  // used to make deprecated functionality working
231  if ( $sProductId !== null ) {
232  $this->setProductId( $sProductId );
233  }
234  // used to make deprecated functionality working
235  if ( $blExtended !== null ) {
236  $this->setExtendedMode($blExtended);
237  }
238  $sCacheIdent = $this->_formCacheKey();
239  if ( !isset( $this->_aCloudArray[ $sCacheIdent ] ) ) {
240  $oTagList = $this->getTagList();
241  // used to make deprecated functionality working
242  if ( $oTagList === null ) {
243  $oTagList = oxNew('oxTagList');
244  $oTagList->setLanguage( $this->getLanguageId() );
245  }
246  $this->_aCloudArray[$sCacheIdent] = $this->formCloudArray( $oTagList );
247  }
248  return $this->_aCloudArray[$sCacheIdent];
249  }
250 
258  public function formCloudArray( oxITagList $oTagList )
259  {
260  // checking if current data is allready loaded
261  if ( $oTagList->getCacheId() ) {
262  $sCacheIdent = $this->_formCacheKey( $oTagList->getCacheId() );
263  $myUtils = oxRegistry::getUtils();
264  // checking cache
265  $aCloudArray = $myUtils->fromFileCache( $sCacheIdent );
266  }
267 
268  // loading cloud info
269  if ( $aCloudArray === null ) {
270  $oTagList->loadList();
271  $oTagSet = $oTagList->get();
272  if ( count( $oTagSet->get() ) > $this->getMaxAmount() ) {
273  $oTagSet->sortByHitCount();
274  $oTagSet->slice( 0, $this->getMaxAmount() );
275  }
276  $oTagSet->sort();
277  $aCloudArray = $oTagSet->get();
278  // updating cache
279  if ( $sCacheIdent ) {
280  $myUtils->toFileCache( $sCacheIdent, $aCloudArray );
281  }
282  }
283 
284  return $aCloudArray;
285  }
286 
294  public function getTagSize( $sTag )
295  {
296  $aCloudArray = $this->getCloudArray();
297  if ( is_null($aCloudArray[$sTag]) ) {
298  return 1;
299  }
300  $iCurrSize = $this->_getFontSize( $aCloudArray[$sTag]->getHitCount(), $this->_getMaxHit() );
301 
302  // calculating min size
303  return floor( $iCurrSize / OXTAGCLOUD_MINFONT ) * OXTAGCLOUD_MINFONT;
304  }
305 
311  public function getMaxAmount()
312  {
313  if ( $this->isExtended() ) {
314  return OXTAGCLOUD_EXTENDEDCOUNT;
315  } else {
316  return OXTAGCLOUD_STARTPAGECOUNT;
317  }
318  }
319 
327  public function resetTagCache( $iLang = null )
328  {
329  if ( $iLang ) {
330  $this->setLanguageId( $iLang );
331  }
332  $this->resetCache();
333  }
334 
340  public function resetCache()
341  {
342  $myUtils = oxRegistry::getUtils();
343 
344  $sCacheId = null;
345  if ( ( $oTagList = $this->getTagList() ) !== null ) {
346  $sCacheId = $oTagList->getCacheId();
347  }
348 
349  $myUtils->toFileCache( $this->_formCacheKey( $sCacheId ), null );
350 
351  $this->_aCloudArray = null;
352  }
353 
365  public function getTags( $sArtId = null, $blExtended = false, $iLang = null )
366  {
367  if ( $iLang !== null ) {
368  $this->setLanguageId( $iLang );
369  }
370  // used to make deprecated functionality working
371  if ( $sArtId !== null ) {
372  $this->setProductId( $sArtId );
373  $oTagList = $this->getTagList();
374  } else {
375  $oTagList = oxNew('oxTagList');
376  }
377  // used to make deprecated functionality working
378  if ( $blExtended !== null ) {
379  $this->setExtendedMode($blExtended);
380  }
381  $oTagList->load();
382  $oTagSet = $oTagList->get();
383  $oTagSet->sort();
384 
385  $aTags = array();
386  foreach ( $oTagSet->get() as $sKey => $oTag ) {
387  $aTags[$sKey] = $oTag->getHitCount();
388  }
389 
390  return $aTags;
391  }
392 
404  public function prepareTags( $sTags )
405  {
406  $sTags = $this->stripMetaChars($sTags);
407  $aTags = explode( $this->_sSeparator, $sTags );
408  $aRes = array();
409  $oStr = getStr();
410 
411  foreach ( $aTags as $sTag ) {
412  if ( ( $sTag = trim( $sTag ) ) ) {
413  $sRes = '';
414  $iLen = $oStr->strlen( $sTag );
415  if ( $iLen > $this->_iTagMaxLength ) {
416  $sTag = $oStr->substr($sTag, 0, $this->_iTagMaxLength);
417  }
418  $sTag = trim( $sTag );
419  $aMatches = explode(' ', $sTag);
420  foreach ( $aMatches as $iKey => $sMatch ) {
421  $sRes .= $oStr->strtolower( $this->_fixTagLength($sMatch ) )." ";
422  }
423  $aRes[] = trim( $sRes );
424  }
425  }
426 
427  return implode( $this->_sSeparator, $aRes );
428  }
429 
439  public function trimTags( $sTags )
440  {
441  $oStr = getStr();
442  $sTags = $oStr->preg_replace( "/(\s*\,+\s*)+/", ",", trim( $sTags ) );
443  $sRes = '';
444 
445  if ( $oStr->preg_match_all( "/([\s\,\-]?)([^\s\,\-]+)([\s\,\-]?)/", $sTags, $aMatches ) ) {
446  foreach ( $aMatches[0] as $iKey => $sMatch ) {
447  $sProc = $aMatches[2][$iKey];
448  if ( $oStr->strlen( $sProc ) <= OXTAGCLOUD_MINTAGLENGTH ) {
449  $sProc = rtrim( $sProc, "_" );
450  }
451  $sRes .= $aMatches[1][$iKey] . $sProc . $aMatches[3][$iKey];
452  }
453  }
454 
455  return trim( $sRes, $this->_sSeparator );
456  }
457 
467  public function stripMetaChars( $sText )
468  {
469  $oStr = getStr();
470 
471  // Remove meta chars
472  $sText = str_replace($this->_aMetaChars, ' ', $sText);
473 
474  // Replace multiple spaces with single space
475  $sText = $oStr->preg_replace( "/\s+/", " ", trim( $sText ) );
476 
477  return $sText;
478  }
479 
487  public function getTagMaxLength()
488  {
489  $oTags = oxNew( 'oxtag' );
490  return $oTags->getMaxLength();
491  }
492 
502  public function getTagLink( $sTag )
503  {
504  $aCloudArray = $this->getCloudArray();
505  return $aCloudArray[$sTag]->getLink();
506  }
507 
517  public function getTagTitle( $sTag )
518  {
519  $aCloudArray = $this->getCloudArray();
520  return $aCloudArray[$sTag]->getTitle();
521  }
522 
532  public function canBeTagged( $sTagTitle )
533  {
534  $oTags = oxNew( 'oxarticletaglist' );
535  $oTags->load($this->getProductId());
536  return $oTags->canBeTagged($sTagTitle);
537  }
538 
548  public function _fixTagLength( $sTag )
549  {
550  $oStr = getStr();
551  $sTag = trim( $sTag );
552  $iLen = $oStr->strlen( $sTag );
553 
554  if ( $iLen < OXTAGCLOUD_MINTAGLENGTH ) {
555  $sTag .= str_repeat( '_', OXTAGCLOUD_MINTAGLENGTH - $iLen );
556  }
557 
558  return $sTag;
559  }
560 
571  protected function _getCacheKey( $blExtended, $iLang = null )
572  {
573  return $this->_sCacheKey."_".$this->getConfig()->getShopId()."_".( ( $iLang !== null ) ? $iLang : oxRegistry::getLang()->getBaseLanguage() ) ."_".($blExtended?1:0);
574  }
575 
583  protected function _formCacheKey( $sTagListCacheId = null )
584  {
585  $sExtended = $this->isExtended()? '1' : '0';
586  return $this->_sCacheKey."_".$this->getConfig()->getShopId()."_".$sExtended."_".$sTagListCacheId;
587  }
588 
594  protected function _getMaxHit()
595  {
596  if ( $this->_iMaxHit === null ) {
597  $aHits = array_map( array($this, '_getTagHitCount'), $this->getCloudArray());
598  $this->_iMaxHit = max( $aHits );
599  }
600  return $this->_iMaxHit;
601  }
602 
610  protected function _getTagHitCount( $oTag )
611  {
612  return $oTag->getHitCount();
613  }
614 
623  protected function _getFontSize( $iHit, $iMaxHit )
624  {
625  //handling special case
626  if ($iMaxHit <= OXTAGCLOUD_MINOCCURENCETOSHOW || !$iMaxHit) {
627  return OXTAGCLOUD_MINFONT;
628  }
629 
630  $iFontDiff = OXTAGCLOUD_MAXFONT - OXTAGCLOUD_MINFONT;
631  $iMaxHitDiff = $iMaxHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
632  $iHitDiff = $iHit - OXTAGCLOUD_MINOCCURENCETOSHOW;
633 
634  if ($iHitDiff < 0) {
635  $iHitDiff = 0;
636  }
637 
638  $iSize = round($iHitDiff * $iFontDiff / $iMaxHitDiff) + OXTAGCLOUD_MINFONT;
639 
640  return $iSize;
641  }
642 
653  protected function _sortTags( $aTags, $iLang = null )
654  {
655  if ( is_array( $aTags ) && count( $aTags ) ) {
657  $sSubQ = '';
658  foreach ( $aTags as $sKey => $sTag ) {
659  if ( $sSubQ ) {
660  $sSubQ .= ' union all ';
661  }
662  $sSubQ .= 'select '.$oDb->quote( $sKey ).' as _oxsort, '.$oDb->quote( $sTag ).' as _oxval';
663  }
664 
665  $sViewName = getViewName( "oxartextends", $iLang );
666 
667  // forcing collation
668  $sSubQ = "select {$sViewName}.oxtags as _oxsort, 'ox_skip' as _oxval from {$sViewName} limit 1 union $sSubQ";
669  $sQ = "select _oxtable._oxsort, _oxtable._oxval from ( {$sSubQ} ) as _oxtable order by _oxtable._oxsort desc";
670 
671  $aTags = array();
672  $oDb->setFetchMode( oxDb::FETCH_MODE_ASSOC );
673  $oRs = $oDb->select( $sQ );
674  while ( $oRs && $oRs->recordCount() && !$oRs->EOF ) {
675  if ( $oRs->fields['_oxval'] != 'ox_skip' ) {
676  $aTags[$oRs->fields['_oxsort']] = $oRs->fields['_oxval'];
677  }
678  $oRs->moveNext();
679  }
680  }
681  return $aTags;
682  }
683 
684 }