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