oxvarianthandler.php

Go to the documentation of this file.
00001 <?php
00002 
00007 class oxVariantHandler extends oxSuperCfg
00008 {
00014     protected $_oArticles = null;
00015 
00021     protected $_sMdSeparator = " | ";
00022 
00028     protected $_oMdVariants = null;
00029 
00037     public function init( $oArticles )
00038     {
00039         $this->_oArticles = $oArticles;
00040     }
00041 
00050     public function buildMdVariants( $oVariants, $sParentId )
00051     {
00052         $oMdVariants = oxNew( "OxMdVariant" );
00053         $oMdVariants->setParentId( $sParentId );
00054         $oMdVariants->setName( "_parent_product_" );
00055         foreach ( $oVariants as $sKey => $oVariant ) {
00056             $aNames = explode( trim( $this->_sMdSeparator ), $oVariant->oxarticles__oxvarselect->value );
00057             foreach ( $aNames as $sNameKey => $sName ) {
00058                 $aNames[$sNameKey] = trim($sName);
00059             }
00060             $oMdVariants->addNames( $sKey,
00061                                     $aNames,
00062                                     ( $this->getConfig()->getConfigParam( 'bl_perfLoadPrice' ) ) ? $oVariant->getPrice()->getBruttoPrice() : null,
00063                                     $oVariant->getLink() );
00064         }
00065 
00066         return $oMdVariants;
00067     }
00068 
00077     public function genVariantFromSell( $aSels, $oArticle )
00078     {
00079         $oVariants = $oArticle->getAdminVariants();
00080         $myConfig  = $this->getConfig();
00081         $myUtils   = oxUtils::getInstance();
00082         $myLang    = oxLang::getInstance();
00083         $aConfLanguages = $myLang->getLanguageIds();
00084 
00085         foreach ($aSels as $sSelId) {
00086             $oSel = oxNew("oxi18n");
00087             $oSel->setEnableMultilang( false );
00088             $oSel->init( 'oxselectlist' );
00089             $oSel->load( $sSelId );
00090             $sVarNameUpdate = "";
00091             foreach ($aConfLanguages as $sKey => $sLang) {
00092                 $sPrefix = $myLang->getLanguageTag($sKey);
00093                 $aSelValues = $myUtils->assignValuesFromText($oSel->{"oxselectlist__oxvaldesc".$sPrefix}->value );
00094                 foreach ($aSelValues as $sI => $oValue ) {
00095                     $aValues[$sI][$sKey] = $oValue;
00096                 }
00097                 $aSelTitle[$sKey] = $oSel->{"oxselectlist__oxtitle".$sPrefix}->value;
00098                 $sMdSeparator = ($oArticle->oxarticles__oxvarname->value) ? $this->_sMdSeparator: '';
00099                 if ( $sVarNameUpdate ) {
00100                     $sVarNameUpdate .= ", ";
00101                 }
00102                 $sVarName = oxDb::getDb()->quote($sMdSeparator.$aSelTitle[$sKey]);
00103                 $sVarNameUpdate .= "oxvarname".$sPrefix." = CONCAT(oxvarname".$sPrefix.", ".$sVarName.")";
00104             }
00105             $oMDVariants = $this->_assignValues( $aValues, $oVariants, $oArticle, $aConfLanguages);
00106             if ( $myConfig->getConfigParam( 'blUseMultidimensionVariants' ) ) {
00107                 $oAttribute = oxNew("oxattribute");
00108                 $oAttribute->assignVarToAttribute( $oMDVariants, $aSelTitle );
00109             }
00110             $this->_updateArticleVarName( $sVarNameUpdate, $oArticle->oxarticles__oxid->value );
00111         }
00112     }
00113 
00124     protected function _assignValues( $aValues, $oVariants, $oArticle, $aConfLanguages)
00125     {
00126         $myConfig = $this->getConfig();
00127         $myLang    = oxLang::getInstance();
00128         $iCounter = 0;
00129         $aVarselect = array(); //multilanguage names of existing variants
00130         //iterating through all select list values (eg. $oValue->name = S, M, X, XL)
00131         for ( $i=0; $i<count($aValues); $i++ ) {
00132             $oValue = $aValues[$i][0];
00133             $dPriceMod = $this->_getValuePrice( $oValue, $oArticle->oxarticles__oxprice->value);
00134             if ( $oVariants->count() > 0 ) {
00135                 //if we have any existing variants then copying each variant with $oValue->name
00136                 foreach ( $oVariants as $oSimpleVariant ) {
00137                     if ( !$iCounter ) {
00138                         //we just update the first variant
00139                         $oVariant = oxNew("oxarticle");
00140                         $oVariant->setEnableMultilang(false);
00141                         $oVariant->load($oSimpleVariant->oxarticles__oxid->value);
00142                         $oVariant->oxarticles__oxprice->setValue( $oVariant->oxarticles__oxprice->value + $dPriceMod );
00143                         //assign for all languages
00144                         foreach ( $aConfLanguages as $sKey => $sLang ) {
00145                             $oValue = $aValues[$i][$sKey];
00146                             $sPrefix = $myLang->getLanguageTag($sKey);
00147                             $aVarselect[$oSimpleVariant->oxarticles__oxid->value][$sKey] = $oVariant->{"oxarticles__oxvarselect".$sPrefix}->value;
00148                             $oVariant->{'oxarticles__oxvarselect'.$sPrefix}->setValue($oVariant->{"oxarticles__oxvarselect".$sPrefix}->value.$this->_sMdSeparator.$oValue->name);
00149                         }
00150                         $oVariant->oxarticles__oxsort->setValue($oVariant->oxarticles__oxsort->value * 10);
00151                         $oVariant->save();
00152                         $sVarId = $oSimpleVariant->oxarticles__oxid->value;
00153                     } else {
00154                         //we create new variants
00155                         foreach ($aVarselect[$oSimpleVariant->oxarticles__oxid->value] as $sKey => $sVarselect) {
00156                             $oValue = $aValues[$i][$sKey];
00157                             $sPrefix = $myLang->getLanguageTag($sKey);
00158                             $aParams['oxarticles__oxvarselect'.$sPrefix] = $sVarselect.$this->_sMdSeparator.$oValue->name;
00159                         }
00160                         $aParams['oxarticles__oxartnum'] = $oSimpleVariant->oxarticles__oxartnum->value . "-" . $iCounter;
00161                         $aParams['oxarticles__oxprice'] = $oSimpleVariant->oxarticles__oxprice->value + $dPriceMod;
00162                         $aParams['oxarticles__oxsort'] = $oSimpleVariant->oxarticles__oxsort->value*10 + 10*$iCounter;
00163                         $aParams['oxarticles__oxstock'] = 0;
00164                         $aParams['oxarticles__oxstockflag'] = $oSimpleVariant->oxarticles__oxstockflag->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'] = 5000 + $iCounter * 1000;
00188                 $aParams['oxarticles__oxstock'] = 0;
00189                 $aParams['oxarticles__oxstockflag'] = $oArticle->oxarticles__oxstockflag->value;
00190                 $sVarId = $this->_createNewVariant( $aParams, $oArticle->oxarticles__oxid->value );
00191                 if ( $myConfig->getConfigParam( 'blUseMultidimensionVariants' ) ) {
00192                     $aMDVariants[$sVarId] = $aValues[$i];
00193                 }
00194             }
00195         }
00196         return $aMDVariants;
00197     }
00198 
00207     protected function _getValuePrice( $oValue, $dParentPrice)
00208     {
00209         $myConfig = $this->getConfig();
00210         $dPriceMod = 0;
00211         if ( $myConfig->getConfigParam( 'bl_perfLoadSelectLists' ) && $myConfig->getConfigParam( 'bl_perfUseSelectlistPrice' ) ) {
00212             if ($oValue->priceUnit == 'abs') {
00213                 $dPriceMod = $oValue->price;
00214             } elseif ($oValue->priceUnit == '%') {
00215                 $dPriceModPerc = abs($oValue->price)*$dParentPrice/100.0;
00216                 if (($oValue->price) >= 0.0) {
00217                     $dPriceMod = $dPriceModPerc;
00218                 } else {
00219                     $dPriceMod = -$dPriceModPerc;
00220                 }
00221             }
00222         }
00223         return $dPriceMod;
00224     }
00225 
00234     protected function _createNewVariant( $aParams = null, $sParentId = null)
00235     {
00236         // checkbox handling
00237         $aParams['oxarticles__oxactive'] = 0;
00238 
00239             // shopid
00240             $sShopID = oxSession::getVar( "actshop");
00241             $aParams['oxarticles__oxshopid'] = $sShopID;
00242 
00243         // varianthandling
00244         $aParams['oxarticles__oxparentid'] = $sParentId;
00245 
00246         $oArticle = oxNew("oxi18n");
00247         $oArticle->setEnableMultilang(false);
00248         $oArticle->init( 'oxarticles' );
00249         $oArticle->assign( $aParams);
00250 
00251             //echo $aParams['oxarticles__oxartnum']."---";
00252             $oArticle->save();
00253 
00254         return $oArticle->getId();
00255     }
00256 
00265     protected function _updateArticleVarName( $sUpdate, $sArtId )
00266     {
00267         $oDb = oxDb::getDb();
00268         $sUpdate = "update oxarticles set " . $sUpdate . " where oxid = " . $oDb->quote( $sArtId );
00269         $oDb->Execute( $sUpdate );
00270     }
00271 
00279     public function isMdVariant( $oArticle )
00280     {
00281         if ( $this->getConfig()->getConfigParam( 'blUseMultidimensionVariants' ) ) {
00282             if ( strpos( $oArticle->oxarticles__oxvarselect->value, trim($this->_sMdSeparator) ) !== false ) {
00283                 return true;
00284             }
00285         }
00286 
00287         return false;
00288     }
00289 
00300     protected function _fillVariantSelections( $oVariantList, $iVarSelCnt, &$aFilter, $sActVariantId )
00301     {
00302         $aSelections = array();
00303 
00304         // filling selections
00305         foreach ( $oVariantList as $oVariant ) {
00306 
00307             $aNames = $this->_getSelections( $oVariant->oxarticles__oxvarselect->getRawValue() );
00308             $blActive = ( $sActVariantId === $oVariant->getId() ) ? true : false;
00309             for ( $i = 0; $i < $iVarSelCnt; $i++ ) {
00310                 $sName = isset( $aNames[$i] ) ? trim($aNames[$i]) : false;
00311                 if ($sName) {
00312                     $sHash = md5($sName );
00313 
00314                     // filling up filter
00315                     if ( $blActive ) {
00316                         $aFilter[$i] = $sHash;
00317                     }
00318 
00319                     $aSelections[$oVariant->getId()][$i] = array( 'name' => $sName, 'disabled' => null, 'active' => false, 'hash' => $sHash );
00320                 }
00321             }
00322         }
00323 
00324         return $aSelections;
00325     }
00326 
00334     protected function _cleanFilter( $aFilter )
00335     {
00336         $aCleanFilter = false;
00337         if ( is_array( $aFilter ) && count( $aFilter ) ) {
00338             foreach ( $aFilter as $iKey => $sFilter ) {
00339                 if ( $sFilter ) {
00340                     $aCleanFilter[$iKey] = $sFilter;
00341                 }
00342             }
00343         }
00344 
00345         return $aCleanFilter;
00346     }
00347 
00356     protected function _applyVariantSelectionsFilter( $aSelections, $aFilter )
00357     {
00358         $iMaxActiveCount = 0;
00359         $sMostSuitableVariantId = null;
00360         $blPerfectFit = false;
00361         // applying filters, disabling/activating items
00362         if ( ( $aFilter = $this->_cleanFilter( $aFilter ) ) ) {
00363             foreach ( $aSelections as $sVariantId => &$aLineSelections ) {
00364                 $iActive = 0;
00365                 foreach ( $aFilter as $iKey => $sVal ) {
00366 
00367                     if ( strcmp( $aLineSelections[$iKey]['hash'], $sVal ) === 0 ) {
00368                         $aLineSelections[$iKey]['active'] = true;
00369                         $iActive++;
00370                         foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
00371                             if ( $iKey != $iOtherKey ) {
00372                                 $aLineOtherVariant['disabled'] = false;
00373                             }
00374                         }
00375                         unset($aLineOtherVariant);
00376                     } else {
00377                         foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
00378                             if ( $iKey != $iOtherKey ) {
00379                                 $aLineOtherVariant['disabled'] = true;
00380                             }
00381                         }
00382                     }
00383                 }
00384 
00385                 $blFitsAll = $iActive && (count($aLineSelections) == $iActive) && (count($aFilter) == $iActive);
00386                 if (($iActive > $iMaxActiveCount) || (!$blPerfectFit && $blFitsAll)) {
00387                     $blPerfectFit = $blFitsAll;
00388                     $sMostSuitableVariantId = $sVariantId;
00389                     $iMaxActiveCount = $iActive;
00390                 }
00391 
00392                 unset( $aLineSelections );
00393             }
00394         }
00395         return array($aSelections, $sMostSuitableVariantId, $blPerfectFit);
00396     }
00397 
00406     protected function _buildVariantSelectionsList( $aVarSelects, $aSelections )
00407     {
00408         // creating selection lists
00409         foreach ( $aVarSelects as $iKey => $sLabel ) {
00410             $aVariantSelections[$iKey] = oxNew( "oxVariantSelectList", $sLabel, $iKey );
00411         }
00412 
00413         // building variant selections
00414         foreach ( $aSelections as $aLineSelections ) {
00415             foreach ( $aLineSelections as $oPos => $aLine ) {
00416                 $aVariantSelections[$oPos]->addVariant( $aLine['name'], $aLine['hash'], $aLine['disabled'], $aLine['active'] );
00417             }
00418         }
00419 
00420         return $aVariantSelections;
00421     }
00422 
00431     protected function _getSelections( $sTitle )
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         // assigning variants
00458         $aVarSelects = $this->_getSelections( $sVarName );
00459         if ($iLimit) {
00460             $aVarSelects = array_slice($aVarSelects, 0, $iLimit);
00461         }
00462         if ( ( $iVarSelCnt = count( $aVarSelects ) ) ) {
00463 
00464             // filling selections
00465             $aRawVariantSelections = $this->_fillVariantSelections( $oVariantList, $iVarSelCnt, $aFilter, $sActVariantId );
00466 
00467             // applying filters, disabling/activating items
00468             list($aRawVariantSelections, $sActVariantId, $blPerfectFit) = $this->_applyVariantSelectionsFilter( $aRawVariantSelections, $aFilter );
00469 
00470             // creating selection lists
00471             $aVariantSelections = $this->_buildVariantSelectionsList( $aVarSelects, $aRawVariantSelections );
00472 
00473             $oCurrentVariant = null;
00474             if ($sActVariantId) {
00475                 $oCurrentVariant = $oVariantList[$sActVariantId];
00476             }
00477 
00478             return array(
00479                 'selections' => $aVariantSelections,
00480                 'rawselections' => $aRawVariantSelections,
00481                 'oActiveVariant' => $oCurrentVariant,
00482                 'blPerfectFit' => $blPerfectFit
00483             );
00484         }
00485         return false;
00486     }
00487 }