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();
00130
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
00136 foreach ( $oVariants as $oSimpleVariant ) {
00137 if ( !$iCounter ) {
00138
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
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
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
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;
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
00239 $aParams['oxarticles__oxactive'] = 0;
00240
00241
00242 $sShopID = oxSession::getVar( "actshop");
00243 $aParams['oxarticles__oxshopid'] = $sShopID;
00244
00245
00246 $aParams['oxarticles__oxparentid'] = $sParentId;
00247
00248 $oArticle = oxNew("oxi18n");
00249 $oArticle->setEnableMultilang(false);
00250 $oArticle->init( 'oxarticles' );
00251 $oArticle->assign( $aParams);
00252
00253
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
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
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
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
00410 foreach ( $aVarSelects as $iKey => $sLabel ) {
00411 $aVariantSelections[$iKey] = oxNew( "oxVariantSelectList", $sLabel, $iKey );
00412 }
00413
00414
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
00461 $aVarSelects = $this->_getSelections( $sVarName );
00462
00463 if ($iLimit) {
00464 $aVarSelects = array_slice($aVarSelects, 0, $iLimit);
00465 }
00466 if ( ( $iVarSelCnt = count( $aVarSelects ) ) ) {
00467
00468
00469 $aRawVariantSelections = $this->_fillVariantSelections( $oVariantList, $iVarSelCnt, $aFilter, $sActVariantId );
00470
00471
00472 list($aRawVariantSelections, $sActVariantId, $blPerfectFit) = $this->_applyVariantSelectionsFilter( $aRawVariantSelections, $aFilter );
00473
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 }