4.5 Beta - Artikel werden mehrfach in den Warenkorb gelegt

Hallo,
ich habe mal ein wenig unter http://demoshop.oxid-esales.com/revamped-edition/community-edition/ gespielt und da ist mir etwas aufgefallen.

Wenn man, nachdem man einen Artikel in den Warenkorb gelegt hat, auf eine andere Seite wechselt und anschließend über den Back-Button wieder zurück geht, dann wird der Artikel erneut in den Warenkorb gelegt. Das ganz funktioniert auch durch drücken der F5-Taste.

Das könnte man als eine Art “Verkaufsförderung” bezeichnen ist aber, vermute ich mal, nicht beabsichtigt.

das hat aber nix mit 4.5. zu tun sondern mit dem browser zurück button, funktioniert übrigens auch in 4.3.2 und/oder 4.4.5 (mir jedenfalls auch aufgefallen)

ja und nein…

Es stimmt schon, das Formulare normalerweise erneut abgesendet werden, wenn man in Browser auf zurück geht oder ein “Reload” macht. Das ganze lässt sich in PHP aber relativ leicht “abfangen” und ich denke ein Shop dieser Qualität sollte das können.
Ein mehrfaches Formular-Absenden bei “Reload” oder “Back” klingt für mich nach einer “Kinderkrankheit”.

Gruß
Marco

Oh, noch ein Marco :slight_smile:

Ich werde, nachdem ich mir einen Artikel in den WK gelegt habe und F5 bzw. den Browser-Back-Button betätige, von meinem Browser gefragt, ob ich diese Aktion noch einmal durchführen möchte.
Das Verhalten kenne ich von anderen Seiten genauso; mir ist nicht bekannt, wie ich das über PHP abfangen könnte. Hilf mir.

Gruß


Z.B. bei Amazon kannst du zurückgehen ohne Abfrage.

Hallo Marco :wink:

Ich erkläre das mal etwas allgemeiner. Für diesen speziellen Fall kann man das Vorgehen noch ein klein wenig vereinfachen, aber das Prinzip ist das gleiche.

Das Skript, das die Formular-Daten verarbeitet muss zwei Fälle unterscheiden:
[B]Fall 1:[/B] Es ist in den Formular-Daten ein Fehler aufgetreten (z.B. das Feld “eMail” enthält keine eMail-Adresse). Hierbei wird ganz normal vorgegangen. Etwa mit einer Fehlerausgabe.

[B]Fall 2:[/B] (Die Formular-Daten sind OK.) Hier passiert das eigentlich interessante! Das verarbeitende Skript darf KEINE Ausgaben machen. (d.h. kein “echo” o.ä.)
Nach der Verarbeitung (z.B. Artikel hinzufügen zum Warenkorb, Daten in DB schreiben oder etwas ähnliches) wird über ein “header(‘Location: http://www.meinShop.com/irgendwas.php’);” die eigentliche Zielseite aufgerufen.

Für die Browser-History existiert das verarbeitende Skript nicht. D.h weder über ein “Reload” noch über ein “Back” komme ich an das Skript, das das Formular verarbeitet hat. Ein “Reload” lädt einfach die Zielseite neu, ein “Back” geht zurück zum Formular (bzw. zur Detailansicht).

Ich hoffe, ich habe das halbwegs verständlich erklärt :wink: :wink:

Gruß
Marco

Hi,

hatte neben vielen weiteren Problemen/Bugs im oxid e-shop auch das Verhalten, dass Artikel mehrfach in den Warenkorb gelegt wurden.

Wie auch bei den ein-/mehrdimensionalen Varianten (bei eindimensionalen Varianten konnte der Shop seltsamerweise keine Dropdown-Boxen darstellen, funktioniert aber nach einigen Code-Änderungen jetzt auch), war die Lösung bereits an anderer Stelle implementiert - bei der Option “warenkorb öffnen” (nachdem der Artikel in den Warenkorb gelegt wurde) funktionierte es bereits. Hier meine Lösung für “Popup öffnen”:

oxcmp_basket.php:
Bei public function tobasket folgendes hinzufügen:

$this->getConfig()->getConfigParam( 'iNewBasketItemMessage' ) == 2 ||

public function tobasket( $sProductId = null, $dAmount = null, $aSel = null, $aPersParam = null, $blOverride = false )
    {
        // adding to basket is not allowed ?
        $myConfig = $this->getConfig();
        if ( oxUtils::getInstance()->isSearchEngine() ) {
            return;
        }

        // adding articles
        if ( $aProducts = $this->_getItems( $sProductId, $dAmount, $aSel, $aPersParam, $blOverride ) ) {

            $this->_setLastCall( 'tobasket', $aProducts, $this->getSession()->getBasket()->getBasketSummary() );
            $oBasketItem = $this->_addItems( $aProducts );

            // new basket item marker
            if ( $oBasketItem && $myConfig->getConfigParam( 'iNewBasketItemMessage' ) != 0 ) {
                $oNewItem = new OxstdClass();
                $oNewItem->sTitle  = $oBasketItem->getTitle();
                $oNewItem->sId     = $oBasketItem->getProductId();
                $oNewItem->dAmount = $oBasketItem->getAmount();
                $oNewItem->dBundledAmount = $oBasketItem->getdBundledAmount();

                // passing article
                oxSession::setVar( '_newitem', $oNewItem );
            }
        }

        if ( $this->getConfig()->getConfigParam( 'iNewBasketItemMessage' ) == 2 || $this->getConfig()->getConfigParam( 'iNewBasketItemMessage' ) == 3 ) {
            // redirect to basket
            return $this->_getRedirectUrl();
        }
    }

Bei protected function _getRedirectUrl() folgendes hinzufügen:

 // reload and backbutton blocker
        if ( $this->getConfig()->getConfigParam( 'iNewBasketItemMessage' ) == 2 ) {

            // saving return to shop link to session
            oxSession::setVar( '_backtoshop', $sClass.$sPosition );

            // redirecting to basket
            $sClass = 'details?';
         }


protected function _getRedirectUrl()
    {

        // active class
        $sClass = oxConfig::getParameter( 'cl' );
        $sClass = $sClass?$sClass.'?':'start?';
        $sPosition = '';

        // setting redirect parameters
        foreach ( $this->aRedirectParams as $sParamName ) {
            $sParamVal  = oxConfig::getParameter( $sParamName );
            $sPosition .= $sParamVal?$sParamName.'='.$sParamVal.'&':'';
        }

        // special treatment
        // search param
        $sParam     = rawurlencode( oxConfig::getParameter( 'searchparam', true ) );
        $sPosition .= $sParam?'searchparam='.$sParam.'&':'';

        // current page number
        $iPageNr    = (int) oxConfig::getParameter( 'pgNr' );
        $sPosition .= ( $iPageNr > 0 )?'pgNr='.$iPageNr.'&':'';

        // reload and backbutton blocker
        if ( $this->getConfig()->getConfigParam( 'iNewBasketItemMessage' ) == 2 ) {

            // saving return to shop link to session
            oxSession::setVar( '_backtoshop', $sClass.$sPosition );

            // redirecting to basket
            $sClass = 'details?';
		}
		 // reload and backbutton blocker
		 if ( $this->getConfig()->getConfigParam( 'iNewBasketItemMessage' ) == 3 ) {

            // saving return to shop link to session
            oxSession::setVar( '_backtoshop', $sClass.$sPosition );

            // redirecting to basket
            $sClass = 'basket?';
		   
		 }

        return $sClass.$sPosition;
    }