oxvarianthandler.php

Go to the documentation of this file.
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(); //multilanguage names of existing variants
00129         //iterating through all select list values (eg. $oValue->name = S, M, X, XL)
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                 //if we have any existing variants then copying each variant with $oValue->name
00135                 foreach ($oVariants as $oSimpleVariant) {
00136                     if (!$iCounter) {
00137                         //we just update the first variant
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                         //assign for all languages
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                         //we create new variants
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                 //in case we don't have any variants then we just create variant(s) with $oValue->name
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; // reduction
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         // checkbox handling
00240         $aParams['oxarticles__oxactive'] = 0;
00241 
00242         // shopid
00243         $sShopID = oxRegistry::getSession()->getVariable("actshop");
00244         $aParams['oxarticles__oxshopid'] = $sShopID;
00245 
00246         // varianthandling
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         // filling selections
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                     // filling up filter
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         // applying filters, disabling/activating items
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         // creating selection lists
00408         foreach ($aVarSelects as $iKey => $sLabel) {
00409             $aVariantSelections[$iKey] = oxNew("oxVariantSelectList", $sLabel, $iKey);
00410         }
00411 
00412         // building variant selections
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         // assigning variants
00459         $aVarSelects = $this->_getSelections($sVarName);
00460 
00461         if ($iLimit) {
00462             $aVarSelects = array_slice($aVarSelects, 0, $iLimit);
00463         }
00464         if (($iVarSelCnt = count($aVarSelects))) {
00465 
00466             // filling selections
00467             $aRawVariantSelections = $this->_fillVariantSelections($oVariantList, $iVarSelCnt, $aFilter, $sActVariantId);
00468 
00469             // applying filters, disabling/activating items
00470             list($aRawVariantSelections, $sActVariantId, $blPerfectFit) = $this->_applyVariantSelectionsFilter($aRawVariantSelections, $aFilter);
00471             // creating selection lists
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 }