Skip to content

Problem mit OXID-Warenkorb-Modulen und dem WBL_Autoloader gefixt

Published: at 15:42

Es gibt bei OXID zwei mögliche Arten eine Klasse samt deren Module zu laden: Direkt über oxNew() oder über den Autoloader wenn man z.B. Klassenkonstanten aufruft oder “Modul-Erstellungstricks” anwendet. Also beispielsweise

= und OXID einfach dynamisch den neuen Backend-View von oxAdminView erben lassen.

Und ein weiteres Beispiel sollte nicht unerwähnt bleiben, nämlich das Laden von Objekten, die (in der Session) serialisiert wurden, welches beim Autoloader Probleme macht.Ist der Quellcode vor dem jeweiligen session_start- oder unserialize - Aufruf noch nicht vorhanden, so wird PHP eine Instanz von Typ __PHP_Incomplete_Class erzeugen. Genau dieser Umstand in leicht abgewandelter Form tritt auf manchen Systemen mit meinem Autoloader auf.

Die Session-Klasse versucht in oxSession::getBasket() aktuell das Warenkorb zuerst über den Autoloader zu laden:

    public function getBasket()
    {
        if ( $this->\_oBasket === null ) {
            $sBasket = self::getVar( $this->\_getBasketName() );

            //init oxbasketitem class first
            //#1746
            oxNew('oxbasketitem');

            $oBasket = ( $sBasket && ( $oBasket = unserialize( $sBasket ) ) ) ? $oBasket : null;

            //#3908
            $oEmptyBasket = oxNew('oxbasket');
            if ( !$oBasket || ( get\_class($oBasket) !== get\_class($oEmptyBasket) ) ) {
                $oBasket = $oEmptyBasket;
            }

Habt Ihr jetzt über meinen Autoloader ein Warenkorb-Objekt in der Session serialisiert, blubbert dieser Aufruf zuerst in den WBL_Autoloader. Der Autoloader reicht den Versuch die *_parent-Klasse zu laden dann an den OXID-Autoloader oxAutoload weiter. Dieser versucht dann die gesamte Modulchain aufzubauen, aber das kann er ohne den WBL_Autoloader leider nicht:

    private function \_makeSafeModuleClassParents( $aClassChain, $sBaseModule )
    {
                // ... 

                //including original file
                if ( file\_exists( $sParentPath ) ) {
                    include\_once $sParentPath;
                } elseif ( !class\_exists( $sModuleClass ) ) {

**Der hier markierte class_exists-Aufruf ist abhängig vom WBL_Autoloader und blubbert leider auf manchen System nicht wieder zu ihm hoch, denn dies ist ein verschachtelter Aufruf.**Das entsprechende Warenkorb-Objekt gilt ab dem Moment als deaktiv und wird nicht mehr vom System genutzt.

Daher musste leider ein weiterer Core-Fix hinzu, der nichts weiter macht, als über oxNew() die Logik kontrolliert zu laden. Der Fix ist auf Github entsprechend eingecheckt.

	require\_once realpath(dirname(\_\_FILE\_\_) . '/WBL/Modules/Autoloader.php');
	$oAutoloader = new WBL\_Modules\_Autoloader();

	spl\_autoload\_register(array(
		$oAutoloader
			->addCoreOverride('oxsession',     'WBL\_Modules\_Session')
			->addCoreOverride('oxutilsobject', 'WBL\_Modules\_UtilsObject')
			->setAutoloaderNamespaces(array('RS', 'WBL')),
		'includeClass'
	));
	unset($oAutoloader);

Sry für dieses Problem. Es ist einfach ein Seiteneffekt, der kaum auffällt und bei üblichen Modularbeiten nicht auftritt.


Previous Post
Neues Major-Release von OXID erschienen (4.7, 5.0)
Next Post
Tracking der OXID User-ID im WBL Multitracker