Oxcmp_basket erweitern (Individualisierbare Artikel)

Oxid Version: 4.8

Ich hatte das Problem, dass ich keine Individualisierungsoptionen übergeben konnte, wenn das Standardfeld “details” nicht gesetzt war. Nach langer Internetsuche bin ich dann über zwei Bug-Reports von Oxid gestolpert, wo der Grund dafür ersichtlich wurde:

Der komplette persParam Array wird auf NULL gesetzt, wenn das Element “details” nicht exisitert bzw. leer ist. Das ist natürlich ärgerlich, wenn man dieses Feld nicht setzen will.

Ich bin jetzt auch so weit, dass ich eine funktionierende Lösung habe, aber die bereitet mir irgendwie Bauchschmerzen. Ich habe oxcmp_basket erweitert und zwei Funktionen komplett aus dem Core-Source kopiert und meine Änderungen vorgenommen (fürs Forum habe ich die Änderungen mal hervorgehoben):


<?php

class dacmp_basket extends oxcmp_basket {
    /**
     * Collects and returns array of items to add to basket. Product info is taken not only from
     * given parameters, but additionally from request 'aproducts' parameter
     *
     * @param string $sProductId product ID
     * @param double $dAmount    product amount
     * @param array  $aSel       product select lists
     * @param array  $aPersParam product persistent parameters
     * @param bool   $blOverride amount override status
     *
     * @return mixed
     */
    protected function _getItems( $sProductId = null, $dAmount = null, $aSel = null, $aPersParam = null, $blOverride = false )
    {
        // collecting items to add
        $aProducts = oxConfig::getParameter( 'aproducts' );

        // collecting specified item
        $sProductId = $sProductId?$sProductId:oxConfig::getParameter( 'aid' );
        if ( $sProductId ) {

            // additionally fething current product info
            $dAmount = isset( $dAmount ) ? $dAmount : oxConfig::getParameter( 'am' );

            // select lists
            $aSel = isset( $aSel )?$aSel:oxConfig::getParameter( 'sel' );

            // persistent parameters
            if ( empty($aPersParam) ) {
                $aPersParam = oxConfig::getParameter( 'persparam' );


//======= ÄNDERUNG NÄCHSTE ZEILE: Bedingung auskommentiert
                if ( !is_array($aPersParam) /*|| empty($aPersParam['details'])*/ ) {
                    $aPersParam = null;
                }



            }

            $sBasketItemId = oxConfig::getParameter( 'bindex' );

            $aProducts[$sProductId] = array( 'am' => $dAmount,
                                             'sel' => $aSel,
                                             'persparam' => $aPersParam,
                                             'override'  => $blOverride,
                                             'basketitemid' => $sBasketItemId
                                           );
        }

        if ( is_array( $aProducts ) && count( $aProducts ) ) {

            if (oxConfig::getParameter( 'removeBtn' ) !== null) {
                //setting amount to 0 if removing article from basket
                foreach ( $aProducts as $sProductId => $aProduct ) {
                    if ( isset($aProduct['remove']) && $aProduct['remove']) {
                        $aProducts[$sProductId]['am'] = 0;
                    } else {
                        unset ($aProducts[$sProductId]);
                    }
                }
            }

            return $aProducts;
        }

        return false;
    }

    /**
     * Adds all articles user wants to add to basket. Returns
     * last added to basket item.
     *
     * @param array $aProducts products to add array
     *
     * @return  object  $oBasketItem    last added basket item
     */
    protected function _addItems ( $aProducts )
    {
        $oActView   = $this->getConfig()->getActiveView();
        $sErrorDest = $oActView->getErrorDestination();

        $oBasket = $this->getSession()->getBasket();
        $oBasketInfo = $oBasket->getBasketSummary();

        foreach ( $aProducts as $sAddProductId => $aProductInfo ) {

            $sProductId = isset( $aProductInfo['aid'] ) ? $aProductInfo['aid'] : $sAddProductId;

            // collecting input
            $aProducts[$sAddProductId]['oldam'] = isset( $oBasketInfo->aArticles[$sProductId] ) ? $oBasketInfo->aArticles[$sProductId] : 0;

            $dAmount = isset( $aProductInfo['am'] )?$aProductInfo['am']:0;
            $aSelList = isset( $aProductInfo['sel'] )?$aProductInfo['sel']:null;
            






/* ================================================== */                          
            if ( isset( $aProductInfo['persparam'] ) && is_array( $aProductInfo['persparam'] ) ) {
                $aPersParam = $aProductInfo['persparam'];

                //Delete all empty params
                foreach ($aPersParam as $curKey => $sParam) {
                    if (empty($sParam)) {
                        unset($aProductInfo['persparam'][$curKey]);
                    }
                }
                
                //If the Array is now empty, set it to NULL explicitly
                if (empty($aPersParam)) {
                    $aPersParam = NULL;
                }
            }
/* ================================================== */            
   






         
            $blOverride = isset( $aProductInfo['override'] )?$aProductInfo['override']:null;
            $blIsBundle = isset( $aProductInfo['bundle'] )?true:false;
            $sOldBasketItemId = isset( $aProductInfo['basketitemid'] )?$aProductInfo['basketitemid']:null;

            try {
                $oBasketItem = $oBasket->addToBasket( $sProductId, $dAmount, $aSelList, $aPersParam, $blOverride, $blIsBundle, $sOldBasketItemId );
            } catch ( oxOutOfStockException $oEx ) {
                $oEx->setDestination( $sErrorDest );
                // #950 Change error destination to basket popup
                if ( !$sErrorDest  && $this->getConfig()->getConfigParam( 'iNewBasketItemMessage') == 2) {
                    $sErrorDest = 'popup';
                }
                oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx, false, (bool) $sErrorDest, $sErrorDest );
            } catch ( oxArticleInputException $oEx ) {
                //add to display at specific position
                $oEx->setDestination( $sErrorDest );
                oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx, false, (bool) $sErrorDest, $sErrorDest );
            } catch ( oxNoArticleException $oEx ) {
                //ignored, best solution F ?
            }
            if ( !$oBasketItem ) {
                $oInfo = $oBasket->getBasketSummary();
                $aProducts[$sAddProductId]['am'] = isset( $oInfo->aArticles[$sProductId] ) ? $oInfo->aArticles[$sProductId] : 0;
            }
        }

        //if basket empty remove posible gift card
        if ( $oBasket->getProductsCount() == 0 ) {
            $oBasket->setCardId( null );
        }

        // information that last call was tobasket
        $this->_setLastCall( $this->_getLastCallFnc(), $aProducts, $oBasketInfo );

        return $oBasketItem;
    }
}


Zwei Fragen stellen sich mir mit dieser Lösung: Warum kann ich oxcmp_basket nicht wie gewohnt mit oxcmp_basket_parent erweitern und was passiert nun, wenn jemand anderes die gleiche Klasse erweitern will?

Irgendwie scheint mir diese Lösung schmutzig zu sein, ich weiß aber nicht, warum. Sollte man das so umsetzen? Oder gibt es eine elegantere Lösung? Die Logik, wann die Parameter nicht übernommen werden, wird in Zukunft ggf. noch etwas komplexer werden als die einfache Überprüfung, ob alle Elemente leer sind.

Falls es interessant sein sollte, hier meine metadata.php:

<?php

/**
 * Metadata version
 */
$sMetadataVersion = '1.1';

/**
 * Module information
 */
$aModule = array(

// Uninteressantes entfernt

    'extend'       => array(
        'oxcmp_basket' => 'da/daPersonalizeArticle/components/dacmp_basket'
    ),
	'blocks' => array(
		array(
    		'template' => 'page/details/inc/productmain.tpl',
    		'block'=>'details_productmain_persparams',
    		'file'=>'/tpl/blocks/persParams.tpl'
        ),
	),

   'settings' => array(
        array('group' => 'main', 'name' => 'bDaOptionExtendDefaultBlock', 'type' => 'bool', 'value' => 'false'),
        array('group' => 'main', 'name' => 'aDaOptionPersColors', 'type' => 'arr',  'value' => array('Rot','Grün','Blau')),
    )

);

Gibt es niemanden, der dazu eine Aussage treffen kann? Ich fühle mich mit dem Code immer noch nicht wohl - obwohl er funktioniert. Ich wüsste aber auch nicht, wie man es besser machen kann.

Hallo,
wenn ich mal Werbung auf eigener Sache machen darf:

ich habe vor zwei Wochen das Erweiterte Parameter Modul geschrieben:

[Erweiterte Parameter](Erweiterte Parameter)

Grüße
Rafig

Sieht auf jedenfall nach einem klasse Modul aus. Allerdings ist mein primäres Ziel hier weniger das fertige Modul an sich als eher der Lernprozess.
Das funktioniert oft sicher durch lesen des Codes und der Doku, aber manchmal stößt man eben auf Fragen, die man nicht oder nur bedingt selbst beantworten kann.

Bisher bin ich eher “Supportnehmer” hier im Forum. Schön wäre, wenn ich irgendwann auch in der Position wäre, Fragen anderer zu beantworten und sich auch selbst mal was für Oxid stricken zu können, wenn es das, was man braucht, einfach nicht gibt. :slight_smile:
Das funktioniert aber nicht, wenn man sich immer nur fertiger Lösungen bedient.

Hi, vielleicht hilft dir dieser (leider schon etwas ältere) Blogbeitrag von shoptimax bezüglich einer Erweiterung von Komponenten weiter?

[QUOTE=Anpan;158464]
Zwei Fragen stellen sich mir mit dieser Lösung: Warum kann ich oxcmp_basket nicht wie gewohnt mit oxcmp_basket_parent erweitern[/QUOTE]
Was passiert denn wenn du es machst? Sollte eigentlich gehen denke ich.