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