36     public function init($oArticles)
 
   38         $this->_oArticles = $oArticles;
 
   51         $oMdVariants = 
oxNew(
"OxMdVariant");
 
   52         $oMdVariants->setParentId($sParentId);
 
   53         $oMdVariants->setName(
"_parent_product_");
 
   54         foreach ($oVariants as $sKey => $oVariant) {
 
   55             $aNames = explode(trim($this->_sMdSeparator), $oVariant->oxarticles__oxvarselect->value);
 
   56             foreach ($aNames as $sNameKey => $sName) {
 
   57                 $aNames[$sNameKey] = trim($sName);
 
   59             $oMdVariants->addNames(
 
   62                 ($this->
getConfig()->getConfigParam(
'bl_perfLoadPrice')) ? $oVariant->getPrice()->getBruttoPrice() : null,
 
   78         $oVariants = $oArticle->getAdminVariants();
 
   82         $aConfLanguages = $myLang->getLanguageIds();
 
   84         foreach ($aSels as $sSelId) {
 
   85             $oSel = 
oxNew(
"oxi18n");
 
   86             $oSel->setEnableMultilang(
false);
 
   87             $oSel->init(
'oxselectlist');
 
   90             foreach ($aConfLanguages as $sKey => $sLang) {
 
   91                 $sPrefix = $myLang->getLanguageTag($sKey);
 
   92                 $aSelValues = $myUtils->assignValuesFromText($oSel->{
"oxselectlist__oxvaldesc" . $sPrefix}->value);
 
   93                 foreach ($aSelValues as $sI => $oValue) {
 
   94                     $aValues[$sI][$sKey] = $oValue;
 
   96                 $aSelTitle[$sKey] = $oSel->{
"oxselectlist__oxtitle" . $sPrefix}->value;
 
   97                 $sMdSeparator = ($oArticle->oxarticles__oxvarname->value) ? $this->_sMdSeparator : 
'';
 
   98                 if ($sVarNameUpdate) {
 
   99                     $sVarNameUpdate .= 
", ";
 
  101                 $sVarName = 
oxDb::getDb()->quote($sMdSeparator . $aSelTitle[$sKey]);
 
  102                 $sVarNameUpdate .= 
"oxvarname" . $sPrefix . 
" = CONCAT(oxvarname" . $sPrefix . 
", " . $sVarName . 
")";
 
  104             $oMDVariants = $this->
_assignValues($aValues, $oVariants, $oArticle, $aConfLanguages);
 
  105             if (
$myConfig->getConfigParam(
'blUseMultidimensionVariants')) {
 
  106                 $oAttribute = 
oxNew(
"oxattribute");
 
  107                 $oAttribute->assignVarToAttribute($oMDVariants, $aSelTitle);
 
  123     protected function _assignValues($aValues, $oVariants, $oArticle, $aConfLanguages)
 
  128         $aVarselect = array(); 
 
  130         for ($i = 0; $i < count($aValues); $i++) {
 
  131             $oValue = $aValues[$i][0];
 
  132             $dPriceMod = $this->_getValuePrice($oValue, $oArticle->oxarticles__oxprice->value);
 
  133             if ($oVariants->count() > 0) {
 
  135                 foreach ($oVariants as $oSimpleVariant) {
 
  138                         $oVariant = 
oxNew(
"oxarticle");
 
  139                         $oVariant->setEnableMultilang(
false);
 
  140                         $oVariant->load($oSimpleVariant->oxarticles__oxid->value);
 
  141                         $oVariant->oxarticles__oxprice->setValue($oVariant->oxarticles__oxprice->value + $dPriceMod);
 
  143                         foreach ($aConfLanguages as $sKey => $sLang) {
 
  144                             $oValue = $aValues[$i][$sKey];
 
  145                             $sPrefix = $myLang->getLanguageTag($sKey);
 
  146                             $aVarselect[$oSimpleVariant->oxarticles__oxid->value][$sKey] = $oVariant->{
"oxarticles__oxvarselect" . $sPrefix}->value;
 
  147                             $oVariant->{
'oxarticles__oxvarselect' . $sPrefix}->setValue($oVariant->{
"oxarticles__oxvarselect" . $sPrefix}->value . $this->_sMdSeparator . $oValue->name);
 
  149                         $oVariant->oxarticles__oxsort->setValue($oVariant->oxarticles__oxsort->value * 10);
 
  151                         $sVarId = $oSimpleVariant->oxarticles__oxid->value;
 
  154                         foreach ($aVarselect[$oSimpleVariant->oxarticles__oxid->value] as $sKey => $sVarselect) {
 
  155                             $oValue = $aValues[$i][$sKey];
 
  156                             $sPrefix = $myLang->getLanguageTag($sKey);
 
  157                             $aParams[
'oxarticles__oxvarselect' . $sPrefix] = $sVarselect . $this->_sMdSeparator . $oValue->name;
 
  159                         $aParams[
'oxarticles__oxartnum'] = $oSimpleVariant->oxarticles__oxartnum->value . 
"-" . $iCounter;
 
  160                         $aParams[
'oxarticles__oxprice'] = $oSimpleVariant->oxarticles__oxprice->value + $dPriceMod;
 
  161                         $aParams[
'oxarticles__oxsort'] = $oSimpleVariant->oxarticles__oxsort->value * 10 + 10 * $iCounter;
 
  162                         $aParams[
'oxarticles__oxstock'] = 0;
 
  163                         $aParams[
'oxarticles__oxstockflag'] = $oSimpleVariant->oxarticles__oxstockflag->value;
 
  164                         $aParams[
'oxarticles__oxisconfigurable'] = $oSimpleVariant->oxarticles__oxisconfigurable->value;
 
  165                         $sVarId = $this->_createNewVariant($aParams, $oArticle->oxarticles__oxid->value);
 
  166                         if (
$myConfig->getConfigParam(
'blUseMultidimensionVariants')) {
 
  167                             $oAttrList = 
oxNew(
'oxattribute');
 
  168                             $aIds = $oAttrList->getAttributeAssigns($oSimpleVariant->oxarticles__oxid->value);
 
  169                             $aMDVariants[
"mdvar_" . $sVarId] = $aIds;
 
  172                     if (
$myConfig->getConfigParam(
'blUseMultidimensionVariants')) {
 
  173                         $aMDVariants[$sVarId] = $aValues[$i];
 
  180                 foreach ($aConfLanguages as $sKey => $sLang) {
 
  181                     $oValue = $aValues[$i][$sKey];
 
  182                     $sPrefix = $myLang->getLanguageTag($sKey);
 
  183                     $aParams[
'oxarticles__oxvarselect' . $sPrefix] = $oValue->name;
 
  185                 $aParams[
'oxarticles__oxartnum'] = $oArticle->oxarticles__oxartnum->value . 
"-" . $iCounter;
 
  186                 $aParams[
'oxarticles__oxprice'] = $oArticle->oxarticles__oxprice->value + $dPriceMod;
 
  187                 $aParams[
'oxarticles__oxsort'] = $iCounter * 100; 
 
  188                 $aParams[
'oxarticles__oxstock'] = 0;
 
  189                 $aParams[
'oxarticles__oxstockflag'] = $oArticle->oxarticles__oxstockflag->value;
 
  190                 $aParams[
'oxarticles__oxisconfigurable'] = $oArticle->oxarticles__oxisconfigurable->value;
 
  191                 $sVarId = $this->_createNewVariant($aParams, $oArticle->oxarticles__oxid->value);
 
  192                 if (
$myConfig->getConfigParam(
'blUseMultidimensionVariants')) {
 
  193                     $aMDVariants[$sVarId] = $aValues[$i];
 
  209     protected function _getValuePrice($oValue, $dParentPrice)
 
  213         if (
$myConfig->getConfigParam(
'bl_perfLoadSelectLists') && 
$myConfig->getConfigParam(
'bl_perfUseSelectlistPrice')) {
 
  214             if ($oValue->priceUnit == 
'abs') {
 
  215                 $dPriceMod = $oValue->price;
 
  216             } elseif ($oValue->priceUnit == 
'%') {
 
  217                 $dPriceModPerc = abs($oValue->price) * $dParentPrice / 100.0;
 
  218                 if (($oValue->price) >= 0.0) {
 
  219                     $dPriceMod = $dPriceModPerc;
 
  221                     $dPriceMod = -$dPriceModPerc;
 
  237     protected function _createNewVariant($aParams = null, $sParentId = null)
 
  240         $aParams[
'oxarticles__oxactive'] = 0;
 
  244         $aParams[
'oxarticles__oxshopid'] = $sShopID;
 
  247         $aParams[
'oxarticles__oxparentid'] = $sParentId;
 
  249         $oArticle = 
oxNew(
"oxArticle");
 
  250         $oArticle->setEnableMultilang(
false);
 
  251         $oArticle->assign($aParams);
 
  254         return $oArticle->getId();
 
  263     protected function _updateArticleVarName($sUpdate, $sArtId)
 
  266         $sUpdate = 
"update oxarticles set " . $sUpdate . 
" where oxid = " . $oDb->quote($sArtId);
 
  267         $oDb->Execute($sUpdate);
 
  277     public function isMdVariant($oArticle)
 
  279         if ($this->getConfig()->getConfigParam(
'blUseMultidimensionVariants')) {
 
  280             if (strpos($oArticle->oxarticles__oxvarselect->value, trim($this->_sMdSeparator)) !== 
false) {
 
  298     protected function _fillVariantSelections($oVariantList, $iVarSelCnt, &$aFilter, $sActVariantId)
 
  300         $aSelections = array();
 
  303         foreach ($oVariantList as $oVariant) {
 
  305             $aNames = $this->_getSelections($oVariant->oxarticles__oxvarselect->getRawValue());
 
  306             $blActive = ($sActVariantId === $oVariant->getId()) ? 
true : 
false;
 
  307             for ($i = 0; $i < $iVarSelCnt; $i++) {
 
  308                 $sName = isset($aNames[$i]) ? trim($aNames[$i]) : 
false;
 
  310                     $sHash = md5($sName);
 
  314                         $aFilter[$i] = $sHash;
 
  317                     $aSelections[$oVariant->getId()][$i] = array(
'name' => $sName, 
'disabled' => null, 
'active' => 
false, 
'hash' => $sHash);
 
  332     protected function _cleanFilter($aFilter)
 
  334         $aCleanFilter = 
false;
 
  335         if (is_array($aFilter) && count($aFilter)) {
 
  336             foreach ($aFilter as $iKey => $sFilter) {
 
  338                     $aCleanFilter[$iKey] = $sFilter;
 
  343         return $aCleanFilter;
 
  354     protected function _applyVariantSelectionsFilter($aSelections, $aFilter)
 
  356         $iMaxActiveCount = 0;
 
  357         $sMostSuitableVariantId = null;
 
  358         $blPerfectFit = 
false;
 
  360         if (($aFilter = $this->_cleanFilter($aFilter))) {
 
  361             $aFilterKeys = array_keys($aFilter);
 
  362             $iFilterKeysCount = count($aFilter);
 
  363             foreach ($aSelections as $sVariantId => &$aLineSelections) {
 
  365                 foreach ($aFilter as $iKey => $sVal) {
 
  366                     if (strcmp($aLineSelections[$iKey][
'hash'], $sVal) === 0) {
 
  367                         $aLineSelections[$iKey][
'active'] = 
true;
 
  370                         foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
 
  371                             if ($iKey != $iOtherKey) {
 
  372                                 $aLineOtherVariant[
'disabled'] = 
true;
 
  377                 foreach ($aLineSelections as $iOtherKey => &$aLineOtherVariant) {
 
  378                     if (!in_array($iOtherKey, $aFilterKeys)) {
 
  379                         $aLineOtherVariant[
'disabled'] = !($iFilterKeysCount == $iActive);
 
  383                 $blFitsAll = $iActive && (count($aLineSelections) == $iActive) && ($iFilterKeysCount == $iActive);
 
  384                 if (($iActive > $iMaxActiveCount) || (!$blPerfectFit && $blFitsAll)) {
 
  385                     $blPerfectFit = $blFitsAll;
 
  386                     $sMostSuitableVariantId = $sVariantId;
 
  387                     $iMaxActiveCount = $iActive;
 
  390                 unset($aLineSelections);
 
  394         return array($aSelections, $sMostSuitableVariantId, $blPerfectFit);
 
  405     protected function _buildVariantSelectionsList($aVarSelects, $aSelections)
 
  408         foreach ($aVarSelects as $iKey => $sLabel) {
 
  409             $aVariantSelections[$iKey] = 
oxNew(
"oxVariantSelectList", $sLabel, $iKey);
 
  413         foreach ($aSelections as $aLineSelections) {
 
  414             foreach ($aLineSelections as $oPos => $aLine) {
 
  415                 $aVariantSelections[$oPos]->addVariant($aLine[
'name'], $aLine[
'hash'], $aLine[
'disabled'], $aLine[
'active']);
 
  419         return $aVariantSelections;
 
  430     protected function _getSelections($sTitle)
 
  433         if ($this->getConfig()->getConfigParam(
'blUseMultidimensionVariants')) {
 
  434             $aSelections = explode($this->_sMdSeparator, $sTitle);
 
  436             $aSelections = array($sTitle);
 
  453     public function buildVariantSelections($sVarName, $oVariantList, $aFilter, $sActVariantId, $iLimit = 0)
 
  459         $aVarSelects = $this->_getSelections($sVarName);
 
  462             $aVarSelects = array_slice($aVarSelects, 0, $iLimit);
 
  464         if (($iVarSelCnt = count($aVarSelects))) {
 
  467             $aRawVariantSelections = $this->_fillVariantSelections($oVariantList, $iVarSelCnt, $aFilter, $sActVariantId);
 
  470             list($aRawVariantSelections, $sActVariantId, $blPerfectFit) = $this->_applyVariantSelectionsFilter($aRawVariantSelections, $aFilter);
 
  472             $aVariantSelections = $this->_buildVariantSelectionsList($aVarSelects, $aRawVariantSelections);
 
  474             $oCurrentVariant = null;
 
  475             if ($sActVariantId) {
 
  476                 $oCurrentVariant = $oVariantList[$sActVariantId];
 
  481                 'selections'     => $aVariantSelections,
 
  482                 'rawselections'  => $aRawVariantSelections,
 
  483                 'oActiveVariant' => $oCurrentVariant,
 
  484                 'blPerfectFit'   => $blPerfectFit