00001 <?php
00002
00007 class oxVariantHandler extends oxSuperCfg
00008 {
00009
00015 protected $_oArticles = null;
00016
00022 protected $_sMdSeparator = " | ";
00023
00029 protected $_oMdVariants = null;
00030
00036 public function init($oArticles)
00037 {
00038 $this->_oArticles = $oArticles;
00039 }
00040
00049 public function buildMdVariants($oVariants, $sParentId)
00050 {
00051 $oMdVariants = oxNew("OxMdVariant");
00052 $oMdVariants->setParentId($sParentId);
00053 $oMdVariants->setName("_parent_product_");
00054 foreach ($oVariants as $sKey => $oVariant) {
00055 $aNames = explode(trim($this->_sMdSeparator), $oVariant->oxarticles__oxvarselect->value);
00056 foreach ($aNames as $sNameKey => $sName) {
00057 $aNames[$sNameKey] = trim($sName);
00058 }
00059 $oMdVariants->addNames(
00060 $sKey,
00061 $aNames,
00062 ($this->getConfig()->getConfigParam('bl_perfLoadPrice')) ? $oVariant->getPrice()->getBruttoPrice() : null,
00063 $oVariant->getLink()
00064 );
00065 }
00066
00067 return $oMdVariants;
00068 }
00069
00076 public function genVariantFromSell($aSels, $oArticle)
00077 {
00078 $oVariants = $oArticle->getAdminVariants();
00079 $myConfig = $this->getConfig();
00080 $myUtils = oxRegistry::getUtils();
00081 $myLang = oxRegistry::getLang();
00082 $aConfLanguages = $myLang->getLanguageIds();
00083
00084 foreach ($aSels as $sSelId) {
00085 $oSel = oxNew("oxi18n");
00086 $oSel->setEnableMultilang(false);
00087 $oSel->init('oxselectlist');
00088 $oSel->load($sSelId);
00089 $sVarNameUpdate = "";
00090 foreach ($aConfLanguages as $sKey => $sLang) {
00091 $sPrefix = $myLang->getLanguageTag($sKey);
00092 $aSelValues = $myUtils->assignValuesFromText($oSel->{"oxselectlist__oxvaldesc" . $sPrefix}->value);
00093 foreach ($aSelValues as $sI => $oValue) {
00094 $aValues[$sI][$sKey] = $oValue;
00095 }
00096 $aSelTitle[$sKey] = $oSel->{"oxselectlist__oxtitle" . $sPrefix}->value;
00097 $sMdSeparator = ($oArticle->oxarticles__oxvarname->value) ? $this->_sMdSeparator : '';
00098 if ($sVarNameUpdate) {
00099 $sVarNameUpdate .= ", ";
00100 }
00101 $sVarName = oxDb::getDb()->quote($sMdSeparator . $aSelTitle[$sKey]);
00102 $sVarNameUpdate .= "oxvarname" . $sPrefix . " = CONCAT(oxvarname" . $sPrefix . ", " . $sVarName . ")";
00103 }
00104 $oMDVariants = $this->_assignValues($aValues, $oVariants, $oArticle, $aConfLanguages);
00105 if ($myConfig->getConfigParam('blUseMultidimensionVariants')) {
00106 $oAttribute = oxNew("oxattribute");
00107 $oAttribute->assignVarToAttribute($oMDVariants, $aSelTitle);
00108 }
00109 $this->_updateArticleVarName($sVarNameUpdate, $oArticle->oxarticles__oxid->value);
00110 }
00111 }
00112
00123 protected function _assignValues($aValues, $oVariants, $oArticle, $aConfLanguages)
00124 {
00125 $myConfig = $this->getConfig();
00126 $myLang = oxRegistry::getLang();
00127 $iCounter = 0;
00128 $aVarselect = array();
00129
00130 for ($i = 0; $i < count($aValues); $i++) {
00131 $oValue = $aValues[$i][0];
00132 $dPriceMod = $this->_getValuePrice($oValue, $oArticle->oxarticles__oxprice->value);
00133 if ($oVariants->count() > 0) {
00134
00135 foreach ($oVariants as $oSimpleVariant) {
00136 if (!$iCounter) {
00137
00138 $oVariant = oxNew("oxarticle");
00139 $oVariant->setEnableMultilang(false);
00140 $oVariant->load($oSimpleVariant->oxarticles__oxid->value);
00141 $oVariant->oxarticles__oxprice->setValue($oVariant->oxarticles__oxprice->value + $dPriceMod);
00142
00143 foreach ($aConfLanguages as $sKey => $sLang) {
00144 $oValue = $aValues[$i][$sKey];
00145 $sPrefix = $myLang->getLanguageTag($sKey);
00146 $aVarselect[$oSimpleVariant->oxarticles__oxid->value][$sKey] = $oVariant->{"oxarticles__oxvarselect" . $sPrefix}->value;
00147 $oVariant->{'oxarticles__oxvarselect' . $sPrefix}->setValue($oVariant->{"oxarticles__oxvarselect" . $sPrefix}->value . $this->_sMdSeparator . $oValue->name);
00148 }
00149 $oVariant->oxarticles__oxsort->setValue($oVariant->oxarticles__oxsort->value * 10);
00150 $oVariant->save();
00151 $sVarId = $oSimpleVariant->oxarticles__oxid->value;
00152 } else {
00153
00154 foreach ($aVarselect[$oSimpleVariant->oxarticles__oxid->value] as $sKey => $sVarselect) {
00155 $oValue = $aValues[$i][$sKey];
00156 $sPrefix = $myLang->getLanguageTag($sKey);
00157 $aParams['oxarticles__oxvarselect' . $sPrefix] = $sVarselect . $this->_sMdSeparator . $oValue->name;
00158 }
00159 $aParams['oxarticles__oxartnum'] = $oSimpleVariant->oxarticles__oxartnum->value . "-" . $iCounter;
00160 $aParams['oxarticles__oxprice'] = $oSimpleVariant->oxarticles__oxprice->value + $dPriceMod;
00161 $aParams['oxarticles__oxsort'] = $oSimpleVariant->oxarticles__oxsort->value * 10 + 10 * $iCounter;
00162 $aParams['oxarticles__oxstock'] = 0;
00163 $aParams['oxarticles__oxstockflag'] = $oSimpleVariant->oxarticles__oxstockflag->value;
00164 $aParams['oxarticles__oxisconfigurable'] = $oSimpleVariant->oxarticles__oxisconfigurable->value;
00165 $sVarId = $this->_createNewVariant($aParams, $oArticle->oxarticles__oxid->value);
00166 if ($myConfig->getConfigParam('blUseMultidimensionVariants')) {
00167 $oAttrList = oxNew('oxattribute');
00168 $aIds = $oAttrList->getAttributeAssigns($oSimpleVariant->oxarticles__oxid->value);
00169 $aMDVariants["mdvar_" . $sVarId] = $aIds;
00170 }
00171 }
00172 if ($myConfig->getConfigParam('blUseMultidimensionVariants')) {
00173 $aMDVariants[$sVarId] = $aValues[$i];
00174 }
00175 }
00176 $iCounter++;
00177 } else {
00178
00179 $iCounter++;
00180 foreach ($aConfLanguages as $sKey => $sLang) {
00181 $oValue = $aValues[$i][$sKey];
00182 $sPrefix = $myLang->getLanguageTag($sKey);
00183 $aParams['oxarticles__oxvarselect' . $sPrefix] = $oValue->name;
00184 }
00185 $aParams['oxarticles__oxartnum'] = $oArticle->oxarticles__oxartnum->value . "-" . $iCounter;
00186 $aParams['oxarticles__oxprice'] = $oArticle->oxarticles__oxprice->value + $dPriceMod;
00187 $aParams['oxarticles__oxsort'] = $iCounter * 100;
00188 $aParams['oxarticles__oxstock'] = 0;
00189 $aParams['oxarticles__oxstockflag'] = $oArticle->oxarticles__oxstockflag->value;
00190 $aParams['oxarticles__oxisconfigurable'] = $oArticle->oxarticles__oxisconfigurable->value;
00191 $sVarId = $this->_createNewVariant($aParams, $oArticle->oxarticles__oxid->value);
00192 if ($myConfig->getConfigParam('blUseMultidimensionVariants')) {
00193 $aMDVariants[$sVarId] = $aValues[$i];
00194 }
00195 }
00196 }
00197
00198 return $aMDVariants;
00199 }
00200
00209 protected function _getValuePrice($oValue, $dParentPrice)
00210 {
00211 $myConfig = $this->getConfig();
00212 $dPriceMod = 0;
00213 if ($myConfig->getConfigParam('bl_perfLoadSelectLists') && $myConfig->getConfigParam('bl_perfUseSelectlistPrice')) {
00214 if ($oValue->priceUnit == 'abs') {
00215 $dPriceMod = $oValue->price;
00216 } elseif ($oValue->priceUnit == '%') {
00217 $dPriceModPerc = abs($oValue->price) * $dParentPrice / 100.0;
00218 if (($oValue->price) >= 0.0) {
00219 $dPriceMod = $dPriceModPerc;
00220 } else {
00221 $dPriceMod = -$dPriceModPerc;
00222 }
00223 }
00224 }
00225
00226 return $dPriceMod;
00227 }
00228
00237 protected function _createNewVariant($aParams = null, $sParentId = null)
00238 {
00239
00240 $aParams['oxarticles__oxactive'] = 0;
00241
00242
00243 $sShopID = oxRegistry::getSession()->getVariable("actshop");
00244 $aParams['oxarticles__oxshopid'] = $sShopID;
00245
00246
00247 $aParams['oxarticles__oxparentid'] = $sParentId;
00248
00249 $oArticle = oxNew("oxArticle");
00250 $oArticle->setEnableMultilang(false);
00251 $oArticle->assign($aParams);
00252 $oArticle->save();
00253
00254 return $oArticle->getId();
00255 }
00256
00263 protected function _updateArticleVarName($sUpdate, $sArtId)
00264 {
00265 $oDb = oxDb::getDb();
00266 $sUpdate = "update oxarticles set " . $sUpdate . " where oxid = " . $oDb->quote($sArtId);
00267 $oDb->Execute($sUpdate);
00268 }
00269
00277 public function isMdVariant($oArticle)
00278 {
00279 if ($this->getConfig()->getConfigParam('blUseMultidimensionVariants')) {
00280 if (strpos($oArticle->oxarticles__oxvarselect->value, trim($this->_sMdSeparator)) !== false) {
00281 return true;
00282 }
00283 }
00284
00285 return false;
00286 }
00287
00298 protected function _fillVariantSelections($oVariantList, $iVarSelCnt, &$aFilter, $sActVariantId)
00299 {
00300 $aSelections = array();
00301
00302
00303 foreach ($oVariantList as $oVariant) {
00304
00305 $aNames = $this->_getSelections($oVariant->oxarticles__oxvarselect->getRawValue());
00306 $blActive = ($sActVariantId === $oVariant->getId()) ? true : false;
00307 for ($i = 0; $i < $iVarSelCnt; $i++) {
00308 $sName = isset($aNames[$i]) ? trim($aNames[$i]) : false;
00309 if ($sName) {
00310 $sHash = md5($sName);
00311
00312
00313 if ($blActive) {
00314 $aFilter[$i] = $sHash;
00315 }
00316
00317 $aSelections[$oVariant->getId()][$i] = array('name' => $sName, 'disabled' => null, 'active' => false, 'hash' => $sHash);
00318 }
00319 }
00320 }
00321
00322 return $aSelections;
00323 }
00324
00332 protected function _cleanFilter($aFilter)
00333 {
00334 $aCleanFilter = false;
00335 if (is_array($aFilter) && count($aFilter)) {
00336 foreach ($aFilter as $iKey => $sFilter) {
00337 if ($sFilter) {
00338 $aCleanFilter[$iKey] = $sFilter;
00339 }
00340 }
00341 }
00342
00343 return $aCleanFilter;
00344 }
00345
00354 protected function _applyVariantSelectionsFilter($aSelections, $aFilter)
00355 {
00356 $iMaxActiveCount = 0;
00357 $sMostSuitableVariantId = null;
00358 $blPerfectFit = false;
00359
00360 if (($aFilter = $this->_cleanFilter($aFilter))) {
00361 $aFilterKeys = array_keys($aFilter);
00362 $iFilterKeysCount = count($aFilter);
00363 foreach ($aSelections as $sVariantId => &$aLineSelections) {
00364 $iActive = 0;
00365 foreach ($aFilter as $iKey => $sVal) {
00366 if (strcmp($aLineSelections[$iKey]['hash'], $sVal) === 0) {
00367 $aLineSelections[$iKey]['active'] = true;
00368 $iActive++;
00369 } else {
00370 foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
00371 if ($iKey != $iOtherKey) {
00372 $aLineOtherVariant['disabled'] = true;
00373 }
00374 }
00375 }
00376 }
00377 foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
00378 if (!in_array($iOtherKey, $aFilterKeys)) {
00379 $aLineOtherVariant['disabled'] = !($iFilterKeysCount == $iActive);
00380 }
00381 }
00382
00383 $blFitsAll = $iActive && (count($aLineSelections) == $iActive) && ($iFilterKeysCount == $iActive);
00384 if (($iActive > $iMaxActiveCount) || (!$blPerfectFit && $blFitsAll)) {
00385 $blPerfectFit = $blFitsAll;
00386 $sMostSuitableVariantId = $sVariantId;
00387 $iMaxActiveCount = $iActive;
00388 }
00389
00390 unset($aLineSelections);
00391 }
00392 }
00393
00394 return array($aSelections, $sMostSuitableVariantId, $blPerfectFit);
00395 }
00396
00405 protected function _buildVariantSelectionsList($aVarSelects, $aSelections)
00406 {
00407
00408 foreach ($aVarSelects as $iKey => $sLabel) {
00409 $aVariantSelections[$iKey] = oxNew("oxVariantSelectList", $sLabel, $iKey);
00410 }
00411
00412
00413 foreach ($aSelections as $aLineSelections) {
00414 foreach ($aLineSelections as $oPos => $aLine) {
00415 $aVariantSelections[$oPos]->addVariant($aLine['name'], $aLine['hash'], $aLine['disabled'], $aLine['active']);
00416 }
00417 }
00418
00419 return $aVariantSelections;
00420 }
00421
00430 protected function _getSelections($sTitle)
00431 {
00432
00433 if ($this->getConfig()->getConfigParam('blUseMultidimensionVariants')) {
00434 $aSelections = explode($this->_sMdSeparator, $sTitle);
00435 } else {
00436 $aSelections = array($sTitle);
00437 }
00438
00439 return $aSelections;
00440 }
00441
00453 public function buildVariantSelections($sVarName, $oVariantList, $aFilter, $sActVariantId, $iLimit = 0)
00454 {
00455 $aReturn = false;
00456
00457
00458
00459 $aVarSelects = $this->_getSelections($sVarName);
00460
00461 if ($iLimit) {
00462 $aVarSelects = array_slice($aVarSelects, 0, $iLimit);
00463 }
00464 if (($iVarSelCnt = count($aVarSelects))) {
00465
00466
00467 $aRawVariantSelections = $this->_fillVariantSelections($oVariantList, $iVarSelCnt, $aFilter, $sActVariantId);
00468
00469
00470 list($aRawVariantSelections, $sActVariantId, $blPerfectFit) = $this->_applyVariantSelectionsFilter($aRawVariantSelections, $aFilter);
00471
00472 $aVariantSelections = $this->_buildVariantSelectionsList($aVarSelects, $aRawVariantSelections);
00473
00474 $oCurrentVariant = null;
00475 if ($sActVariantId) {
00476 $oCurrentVariant = $oVariantList[$sActVariantId];
00477 }
00478
00479
00480 return array(
00481 'selections' => $aVariantSelections,
00482 'rawselections' => $aRawVariantSelections,
00483 'oActiveVariant' => $oCurrentVariant,
00484 'blPerfectFit' => $blPerfectFit
00485 );
00486 }
00487
00488 return false;
00489 }
00490 }