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   = oxRegistry::getUtils();
00082         $myLang    = oxRegistry::getLang();
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    = oxRegistry::getLang();
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                         $aParams['oxarticles__oxisconfigurable'] = $oSimpleVariant->oxarticles__oxisconfigurable->value;
00166                         $sVarId = $this->_createNewVariant( $aParams, $oArticle->oxarticles__oxid->value );
00167                         if ( $myConfig->getConfigParam( 'blUseMultidimensionVariants' ) ) {
00168                             $oAttrList = oxNew('oxattribute');
00169                             $aIds = $oAttrList->getAttributeAssigns( $oSimpleVariant->oxarticles__oxid->value);
00170                             $aMDVariants["mdvar_".$sVarId] = $aIds;
00171                         }
00172                     }
00173                     if ( $myConfig->getConfigParam( 'blUseMultidimensionVariants' ) ) {
00174                         $aMDVariants[$sVarId] = $aValues[$i];
00175                     }
00176                 }
00177                 $iCounter++;
00178             } else {
00179                 //in case we don't have any variants then we just create variant(s) with $oValue->name
00180                 $iCounter++;
00181                 foreach ($aConfLanguages as $sKey => $sLang) {
00182                     $oValue = $aValues[$i][$sKey];
00183                     $sPrefix = $myLang->getLanguageTag($sKey);
00184                     $aParams['oxarticles__oxvarselect'.$sPrefix] = $oValue->name;
00185                 }
00186                 $aParams['oxarticles__oxartnum'] = $oArticle->oxarticles__oxartnum->value . "-" . $iCounter ;
00187                 $aParams['oxarticles__oxprice'] = $oArticle->oxarticles__oxprice->value + $dPriceMod;
00188                 $aParams['oxarticles__oxsort'] = $iCounter * 100; // reduction
00189                 $aParams['oxarticles__oxstock'] = 0;
00190                 $aParams['oxarticles__oxstockflag'] = $oArticle->oxarticles__oxstockflag->value;
00191                 $aParams['oxarticles__oxisconfigurable'] = $oArticle->oxarticles__oxisconfigurable->value;
00192                 $sVarId = $this->_createNewVariant( $aParams, $oArticle->oxarticles__oxid->value );
00193                 if ( $myConfig->getConfigParam( 'blUseMultidimensionVariants' ) ) {
00194                     $aMDVariants[$sVarId] = $aValues[$i];
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         return $dPriceMod;
00226     }
00227 
00236     protected function _createNewVariant( $aParams = null, $sParentId = null)
00237     {
00238         // checkbox handling
00239         $aParams['oxarticles__oxactive'] = 0;
00240 
00241             // shopid
00242             $sShopID = oxSession::getVar( "actshop");
00243             $aParams['oxarticles__oxshopid'] = $sShopID;
00244 
00245         // varianthandling
00246         $aParams['oxarticles__oxparentid'] = $sParentId;
00247 
00248         $oArticle = oxNew("oxi18n");
00249         $oArticle->setEnableMultilang(false);
00250         $oArticle->init( 'oxarticles' );
00251         $oArticle->assign( $aParams);
00252 
00253             //echo $aParams['oxarticles__oxartnum']."---";
00254             $oArticle->save();
00255 
00256         return $oArticle->getId();
00257     }
00258 
00267     protected function _updateArticleVarName( $sUpdate, $sArtId )
00268     {
00269         $oDb = oxDb::getDb();
00270         $sUpdate = "update oxarticles set " . $sUpdate . " where oxid = " . $oDb->quote( $sArtId );
00271         $oDb->Execute( $sUpdate );
00272     }
00273 
00281     public function isMdVariant( $oArticle )
00282     {
00283         if ( $this->getConfig()->getConfigParam( 'blUseMultidimensionVariants' ) ) {
00284             if ( strpos( $oArticle->oxarticles__oxvarselect->value, trim($this->_sMdSeparator) ) !== false ) {
00285                 return true;
00286             }
00287         }
00288 
00289         return false;
00290     }
00291 
00302     protected function _fillVariantSelections( $oVariantList, $iVarSelCnt, &$aFilter, $sActVariantId )
00303     {
00304         $aSelections = array();
00305 
00306         // filling selections
00307         foreach ( $oVariantList as $oVariant ) {
00308 
00309             $aNames = $this->_getSelections( $oVariant->oxarticles__oxvarselect->getRawValue() );
00310             $blActive = ( $sActVariantId === $oVariant->getId() ) ? true : false;
00311             for ( $i = 0; $i < $iVarSelCnt; $i++ ) {
00312                 $sName = isset( $aNames[$i] ) ? trim($aNames[$i]) : false;
00313                 if ($sName) {
00314                     $sHash = md5($sName );
00315 
00316                     // filling up filter
00317                     if ( $blActive ) {
00318                         $aFilter[$i] = $sHash;
00319                     }
00320 
00321                     $aSelections[$oVariant->getId()][$i] = array( 'name' => $sName, 'disabled' => null, 'active' => false, 'hash' => $sHash );
00322                 }
00323             }
00324         }
00325         return $aSelections;
00326     }
00327 
00335     protected function _cleanFilter( $aFilter )
00336     {
00337         $aCleanFilter = false;
00338         if ( is_array( $aFilter ) && count( $aFilter ) ) {
00339             foreach ( $aFilter as $iKey => $sFilter ) {
00340                 if ( $sFilter ) {
00341                     $aCleanFilter[$iKey] = $sFilter;
00342                 }
00343             }
00344         }
00345 
00346         return $aCleanFilter;
00347     }
00348 
00357     protected function _applyVariantSelectionsFilter( $aSelections, $aFilter )
00358     {
00359         $iMaxActiveCount = 0;
00360         $sMostSuitableVariantId = null;
00361         $blPerfectFit = false;
00362         // applying filters, disabling/activating items
00363         if ( ( $aFilter = $this->_cleanFilter( $aFilter ) ) ) {
00364             $aFilterKeys = array_keys( $aFilter );
00365             $iFilterKeysCount = count( $aFilter );
00366             foreach ( $aSelections as $sVariantId => &$aLineSelections ) {
00367                 $iActive = 0;
00368                 foreach ( $aFilter as $iKey => $sVal ) {
00369                     if ( strcmp( $aLineSelections[$iKey]['hash'], $sVal ) === 0 ) {
00370                         $aLineSelections[$iKey]['active'] = true;
00371                         $iActive++;
00372                     } else {
00373                         foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
00374                             if ( $iKey != $iOtherKey ) {
00375                                 $aLineOtherVariant['disabled'] = true;
00376                             }
00377                         }
00378                     }
00379                 }
00380                 foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
00381                     if ( !in_array( $iOtherKey, $aFilterKeys ) ) {
00382                         $aLineOtherVariant['disabled'] = !($iFilterKeysCount == $iActive);
00383                     }
00384                 }
00385 
00386                 $blFitsAll = $iActive && (count($aLineSelections) == $iActive) && ($iFilterKeysCount == $iActive);
00387                 if (($iActive > $iMaxActiveCount) || (!$blPerfectFit && $blFitsAll)) {
00388                     $blPerfectFit = $blFitsAll;
00389                     $sMostSuitableVariantId = $sVariantId;
00390                     $iMaxActiveCount = $iActive;
00391                 }
00392 
00393                 unset( $aLineSelections );
00394             }
00395         }
00396         return array($aSelections, $sMostSuitableVariantId, $blPerfectFit);
00397     }
00398 
00407     protected function _buildVariantSelectionsList( $aVarSelects, $aSelections )
00408     {
00409         // creating selection lists
00410         foreach ( $aVarSelects as $iKey => $sLabel ) {
00411             $aVariantSelections[$iKey] = oxNew( "oxVariantSelectList", $sLabel, $iKey );
00412         }
00413 
00414         // building variant selections
00415         foreach ( $aSelections as $aLineSelections ) {
00416             foreach ( $aLineSelections as $oPos => $aLine ) {
00417                 $aVariantSelections[$oPos]->addVariant( $aLine['name'], $aLine['hash'], $aLine['disabled'], $aLine['active'] );
00418             }
00419         }
00420 
00421         return $aVariantSelections;
00422     }
00423 
00432     protected function _getSelections( $sTitle )
00433     {
00434 
00435         if ( $this->getConfig()->getConfigParam( 'blUseMultidimensionVariants' ) ) {
00436             $aSelections = explode( $this->_sMdSeparator, $sTitle );
00437         } else {
00438             $aSelections = array( $sTitle );
00439         }
00440 
00441         return $aSelections;
00442     }
00443 
00455     public function buildVariantSelections( $sVarName, $oVariantList, $aFilter, $sActVariantId, $iLimit = 0 )
00456     {
00457         $aReturn = false;
00458 
00459 
00460         // assigning variants
00461         $aVarSelects = $this->_getSelections( $sVarName );
00462 
00463         if ($iLimit) {
00464             $aVarSelects = array_slice($aVarSelects, 0, $iLimit);
00465         }
00466         if ( ( $iVarSelCnt = count( $aVarSelects ) ) ) {
00467 
00468             // filling selections
00469             $aRawVariantSelections = $this->_fillVariantSelections( $oVariantList, $iVarSelCnt, $aFilter, $sActVariantId );
00470 
00471             // applying filters, disabling/activating items
00472             list($aRawVariantSelections, $sActVariantId, $blPerfectFit) = $this->_applyVariantSelectionsFilter( $aRawVariantSelections, $aFilter );
00473             // creating selection lists
00474             $aVariantSelections = $this->_buildVariantSelectionsList( $aVarSelects, $aRawVariantSelections );
00475 
00476             $oCurrentVariant = null;
00477             if ($sActVariantId) {
00478                 $oCurrentVariant = $oVariantList[$sActVariantId];
00479             }
00480 
00481 
00482 
00483             return array(
00484                 'selections' => $aVariantSelections,
00485                 'rawselections' => $aRawVariantSelections,
00486                 'oActiveVariant' => $oCurrentVariant,
00487                 'blPerfectFit' => $blPerfectFit
00488             );
00489         }
00490         return false;
00491     }
00492 }