OXID eShop CE  4.8.12
 All Classes Files Functions Variables Pages
oxvarianthandler.php
Go to the documentation of this file.
1 <?php
2 
8 {
14  protected $_oArticles = null;
15 
21  protected $_sMdSeparator = " | ";
22 
28  protected $_oMdVariants = null;
29 
37  public function init( $oArticles )
38  {
39  $this->_oArticles = $oArticles;
40  }
41 
50  public function buildMdVariants( $oVariants, $sParentId )
51  {
52  $oMdVariants = oxNew( "OxMdVariant" );
53  $oMdVariants->setParentId( $sParentId );
54  $oMdVariants->setName( "_parent_product_" );
55  foreach ( $oVariants as $sKey => $oVariant ) {
56  $aNames = explode( trim( $this->_sMdSeparator ), $oVariant->oxarticles__oxvarselect->value );
57  foreach ( $aNames as $sNameKey => $sName ) {
58  $aNames[$sNameKey] = trim($sName);
59  }
60  $oMdVariants->addNames( $sKey,
61  $aNames,
62  ( $this->getConfig()->getConfigParam( 'bl_perfLoadPrice' ) ) ? $oVariant->getPrice()->getBruttoPrice() : null,
63  $oVariant->getLink() );
64  }
65 
66  return $oMdVariants;
67  }
68 
77  public function genVariantFromSell( $aSels, $oArticle )
78  {
79  $oVariants = $oArticle->getAdminVariants();
80  $myConfig = $this->getConfig();
81  $myUtils = oxRegistry::getUtils();
82  $myLang = oxRegistry::getLang();
83  $aConfLanguages = $myLang->getLanguageIds();
84 
85  foreach ($aSels as $sSelId) {
86  $oSel = oxNew("oxi18n");
87  $oSel->setEnableMultilang( false );
88  $oSel->init( 'oxselectlist' );
89  $oSel->load( $sSelId );
90  $sVarNameUpdate = "";
91  foreach ($aConfLanguages as $sKey => $sLang) {
92  $sPrefix = $myLang->getLanguageTag($sKey);
93  $aSelValues = $myUtils->assignValuesFromText($oSel->{"oxselectlist__oxvaldesc".$sPrefix}->value );
94  foreach ($aSelValues as $sI => $oValue ) {
95  $aValues[$sI][$sKey] = $oValue;
96  }
97  $aSelTitle[$sKey] = $oSel->{"oxselectlist__oxtitle".$sPrefix}->value;
98  $sMdSeparator = ($oArticle->oxarticles__oxvarname->value) ? $this->_sMdSeparator: '';
99  if ( $sVarNameUpdate ) {
100  $sVarNameUpdate .= ", ";
101  }
102  $sVarName = oxDb::getDb()->quote($sMdSeparator.$aSelTitle[$sKey]);
103  $sVarNameUpdate .= "oxvarname".$sPrefix." = CONCAT(oxvarname".$sPrefix.", ".$sVarName.")";
104  }
105  $oMDVariants = $this->_assignValues( $aValues, $oVariants, $oArticle, $aConfLanguages);
106  if ( $myConfig->getConfigParam( 'blUseMultidimensionVariants' ) ) {
107  $oAttribute = oxNew("oxattribute");
108  $oAttribute->assignVarToAttribute( $oMDVariants, $aSelTitle );
109  }
110  $this->_updateArticleVarName( $sVarNameUpdate, $oArticle->oxarticles__oxid->value );
111  }
112  }
113 
124  protected function _assignValues( $aValues, $oVariants, $oArticle, $aConfLanguages)
125  {
126  $myConfig = $this->getConfig();
127  $myLang = oxRegistry::getLang();
128  $iCounter = 0;
129  $aVarselect = array(); //multilanguage names of existing variants
130  //iterating through all select list values (eg. $oValue->name = S, M, X, XL)
131  for ( $i=0; $i<count($aValues); $i++ ) {
132  $oValue = $aValues[$i][0];
133  $dPriceMod = $this->_getValuePrice( $oValue, $oArticle->oxarticles__oxprice->value);
134  if ( $oVariants->count() > 0 ) {
135  //if we have any existing variants then copying each variant with $oValue->name
136  foreach ( $oVariants as $oSimpleVariant ) {
137  if ( !$iCounter ) {
138  //we just update the first variant
139  $oVariant = oxNew("oxarticle");
140  $oVariant->setEnableMultilang(false);
141  $oVariant->load($oSimpleVariant->oxarticles__oxid->value);
142  $oVariant->oxarticles__oxprice->setValue( $oVariant->oxarticles__oxprice->value + $dPriceMod );
143  //assign for all languages
144  foreach ( $aConfLanguages as $sKey => $sLang ) {
145  $oValue = $aValues[$i][$sKey];
146  $sPrefix = $myLang->getLanguageTag($sKey);
147  $aVarselect[$oSimpleVariant->oxarticles__oxid->value][$sKey] = $oVariant->{"oxarticles__oxvarselect".$sPrefix}->value;
148  $oVariant->{'oxarticles__oxvarselect'.$sPrefix}->setValue($oVariant->{"oxarticles__oxvarselect".$sPrefix}->value.$this->_sMdSeparator.$oValue->name);
149  }
150  $oVariant->oxarticles__oxsort->setValue($oVariant->oxarticles__oxsort->value * 10);
151  $oVariant->save();
152  $sVarId = $oSimpleVariant->oxarticles__oxid->value;
153  } else {
154  //we create new variants
155  foreach ($aVarselect[$oSimpleVariant->oxarticles__oxid->value] as $sKey => $sVarselect) {
156  $oValue = $aValues[$i][$sKey];
157  $sPrefix = $myLang->getLanguageTag($sKey);
158  $aParams['oxarticles__oxvarselect'.$sPrefix] = $sVarselect.$this->_sMdSeparator.$oValue->name;
159  }
160  $aParams['oxarticles__oxartnum'] = $oSimpleVariant->oxarticles__oxartnum->value . "-" . $iCounter;
161  $aParams['oxarticles__oxprice'] = $oSimpleVariant->oxarticles__oxprice->value + $dPriceMod;
162  $aParams['oxarticles__oxsort'] = $oSimpleVariant->oxarticles__oxsort->value*10 + 10*$iCounter;
163  $aParams['oxarticles__oxstock'] = 0;
164  $aParams['oxarticles__oxstockflag'] = $oSimpleVariant->oxarticles__oxstockflag->value;
165  $aParams['oxarticles__oxisconfigurable'] = $oSimpleVariant->oxarticles__oxisconfigurable->value;
166  $sVarId = $this->_createNewVariant( $aParams, $oArticle->oxarticles__oxid->value );
167  if ( $myConfig->getConfigParam( 'blUseMultidimensionVariants' ) ) {
168  $oAttrList = oxNew('oxattribute');
169  $aIds = $oAttrList->getAttributeAssigns( $oSimpleVariant->oxarticles__oxid->value);
170  $aMDVariants["mdvar_".$sVarId] = $aIds;
171  }
172  }
173  if ( $myConfig->getConfigParam( 'blUseMultidimensionVariants' ) ) {
174  $aMDVariants[$sVarId] = $aValues[$i];
175  }
176  }
177  $iCounter++;
178  } else {
179  //in case we don't have any variants then we just create variant(s) with $oValue->name
180  $iCounter++;
181  foreach ($aConfLanguages as $sKey => $sLang) {
182  $oValue = $aValues[$i][$sKey];
183  $sPrefix = $myLang->getLanguageTag($sKey);
184  $aParams['oxarticles__oxvarselect'.$sPrefix] = $oValue->name;
185  }
186  $aParams['oxarticles__oxartnum'] = $oArticle->oxarticles__oxartnum->value . "-" . $iCounter ;
187  $aParams['oxarticles__oxprice'] = $oArticle->oxarticles__oxprice->value + $dPriceMod;
188  $aParams['oxarticles__oxsort'] = $iCounter * 100; // reduction
189  $aParams['oxarticles__oxstock'] = 0;
190  $aParams['oxarticles__oxstockflag'] = $oArticle->oxarticles__oxstockflag->value;
191  $aParams['oxarticles__oxisconfigurable'] = $oArticle->oxarticles__oxisconfigurable->value;
192  $sVarId = $this->_createNewVariant( $aParams, $oArticle->oxarticles__oxid->value );
193  if ( $myConfig->getConfigParam( 'blUseMultidimensionVariants' ) ) {
194  $aMDVariants[$sVarId] = $aValues[$i];
195  }
196  }
197  }
198  return $aMDVariants;
199  }
200 
209  protected function _getValuePrice( $oValue, $dParentPrice)
210  {
211  $myConfig = $this->getConfig();
212  $dPriceMod = 0;
213  if ( $myConfig->getConfigParam( 'bl_perfLoadSelectLists' ) && $myConfig->getConfigParam( 'bl_perfUseSelectlistPrice' ) ) {
214  if ($oValue->priceUnit == 'abs') {
215  $dPriceMod = $oValue->price;
216  } elseif ($oValue->priceUnit == '%') {
217  $dPriceModPerc = abs($oValue->price)*$dParentPrice/100.0;
218  if (($oValue->price) >= 0.0) {
219  $dPriceMod = $dPriceModPerc;
220  } else {
221  $dPriceMod = -$dPriceModPerc;
222  }
223  }
224  }
225  return $dPriceMod;
226  }
227 
236  protected function _createNewVariant( $aParams = null, $sParentId = null)
237  {
238  // checkbox handling
239  $aParams['oxarticles__oxactive'] = 0;
240 
241  // shopid
242  $sShopID = oxSession::getVar( "actshop");
243  $aParams['oxarticles__oxshopid'] = $sShopID;
244 
245  // varianthandling
246  $aParams['oxarticles__oxparentid'] = $sParentId;
247 
248  $oArticle = oxNew("oxi18n");
249  $oArticle->setEnableMultilang(false);
250  $oArticle->init( 'oxarticles' );
251  $oArticle->assign( $aParams);
252 
253  //echo $aParams['oxarticles__oxartnum']."---";
254  $oArticle->save();
255 
256  return $oArticle->getId();
257  }
258 
267  protected function _updateArticleVarName( $sUpdate, $sArtId )
268  {
269  $oDb = oxDb::getDb();
270  $sUpdate = "update oxarticles set " . $sUpdate . " where oxid = " . $oDb->quote( $sArtId );
271  $oDb->Execute( $sUpdate );
272  }
273 
281  public function isMdVariant( $oArticle )
282  {
283  if ( $this->getConfig()->getConfigParam( 'blUseMultidimensionVariants' ) ) {
284  if ( strpos( $oArticle->oxarticles__oxvarselect->value, trim($this->_sMdSeparator) ) !== false ) {
285  return true;
286  }
287  }
288 
289  return false;
290  }
291 
302  protected function _fillVariantSelections( $oVariantList, $iVarSelCnt, &$aFilter, $sActVariantId )
303  {
304  $aSelections = array();
305 
306  // filling selections
307  foreach ( $oVariantList as $oVariant ) {
308 
309  $aNames = $this->_getSelections( $oVariant->oxarticles__oxvarselect->getRawValue() );
310  $blActive = ( $sActVariantId === $oVariant->getId() ) ? true : false;
311  for ( $i = 0; $i < $iVarSelCnt; $i++ ) {
312  $sName = isset( $aNames[$i] ) ? trim($aNames[$i]) : false;
313  if ($sName) {
314  $sHash = md5($sName );
315 
316  // filling up filter
317  if ( $blActive ) {
318  $aFilter[$i] = $sHash;
319  }
320 
321  $aSelections[$oVariant->getId()][$i] = array( 'name' => $sName, 'disabled' => null, 'active' => false, 'hash' => $sHash );
322  }
323  }
324  }
325  return $aSelections;
326  }
327 
335  protected function _cleanFilter( $aFilter )
336  {
337  $aCleanFilter = false;
338  if ( is_array( $aFilter ) && count( $aFilter ) ) {
339  foreach ( $aFilter as $iKey => $sFilter ) {
340  if ( $sFilter ) {
341  $aCleanFilter[$iKey] = $sFilter;
342  }
343  }
344  }
345 
346  return $aCleanFilter;
347  }
348 
357  protected function _applyVariantSelectionsFilter( $aSelections, $aFilter )
358  {
359  $iMaxActiveCount = 0;
360  $sMostSuitableVariantId = null;
361  $blPerfectFit = false;
362  // applying filters, disabling/activating items
363  if ( ( $aFilter = $this->_cleanFilter( $aFilter ) ) ) {
364  $aFilterKeys = array_keys( $aFilter );
365  $iFilterKeysCount = count( $aFilter );
366  foreach ( $aSelections as $sVariantId => &$aLineSelections ) {
367  $iActive = 0;
368  foreach ( $aFilter as $iKey => $sVal ) {
369  if ( strcmp( $aLineSelections[$iKey]['hash'], $sVal ) === 0 ) {
370  $aLineSelections[$iKey]['active'] = true;
371  $iActive++;
372  } else {
373  foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
374  if ( $iKey != $iOtherKey ) {
375  $aLineOtherVariant['disabled'] = true;
376  }
377  }
378  }
379  }
380  foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
381  if ( !in_array( $iOtherKey, $aFilterKeys ) ) {
382  $aLineOtherVariant['disabled'] = !($iFilterKeysCount == $iActive);
383  }
384  }
385 
386  $blFitsAll = $iActive && (count($aLineSelections) == $iActive) && ($iFilterKeysCount == $iActive);
387  if (($iActive > $iMaxActiveCount) || (!$blPerfectFit && $blFitsAll)) {
388  $blPerfectFit = $blFitsAll;
389  $sMostSuitableVariantId = $sVariantId;
390  $iMaxActiveCount = $iActive;
391  }
392 
393  unset( $aLineSelections );
394  }
395  }
396  return array($aSelections, $sMostSuitableVariantId, $blPerfectFit);
397  }
398 
407  protected function _buildVariantSelectionsList( $aVarSelects, $aSelections )
408  {
409  // creating selection lists
410  foreach ( $aVarSelects as $iKey => $sLabel ) {
411  $aVariantSelections[$iKey] = oxNew( "oxVariantSelectList", $sLabel, $iKey );
412  }
413 
414  // building variant selections
415  foreach ( $aSelections as $aLineSelections ) {
416  foreach ( $aLineSelections as $oPos => $aLine ) {
417  $aVariantSelections[$oPos]->addVariant( $aLine['name'], $aLine['hash'], $aLine['disabled'], $aLine['active'] );
418  }
419  }
420 
421  return $aVariantSelections;
422  }
423 
432  protected function _getSelections( $sTitle )
433  {
434 
435  if ( $this->getConfig()->getConfigParam( 'blUseMultidimensionVariants' ) ) {
436  $aSelections = explode( $this->_sMdSeparator, $sTitle );
437  } else {
438  $aSelections = array( $sTitle );
439  }
440 
441  return $aSelections;
442  }
443 
455  public function buildVariantSelections( $sVarName, $oVariantList, $aFilter, $sActVariantId, $iLimit = 0 )
456  {
457  $aReturn = false;
458 
459 
460  // assigning variants
461  $aVarSelects = $this->_getSelections( $sVarName );
462 
463  if ($iLimit) {
464  $aVarSelects = array_slice($aVarSelects, 0, $iLimit);
465  }
466  if ( ( $iVarSelCnt = count( $aVarSelects ) ) ) {
467 
468  // filling selections
469  $aRawVariantSelections = $this->_fillVariantSelections( $oVariantList, $iVarSelCnt, $aFilter, $sActVariantId );
470 
471  // applying filters, disabling/activating items
472  list($aRawVariantSelections, $sActVariantId, $blPerfectFit) = $this->_applyVariantSelectionsFilter( $aRawVariantSelections, $aFilter );
473  // creating selection lists
474  $aVariantSelections = $this->_buildVariantSelectionsList( $aVarSelects, $aRawVariantSelections );
475 
476  $oCurrentVariant = null;
477  if ($sActVariantId) {
478  $oCurrentVariant = $oVariantList[$sActVariantId];
479  }
480 
481 
482 
483  return array(
484  'selections' => $aVariantSelections,
485  'rawselections' => $aRawVariantSelections,
486  'oActiveVariant' => $oCurrentVariant,
487  'blPerfectFit' => $blPerfectFit
488  );
489  }
490  return false;
491  }
492 }