View Issue Details

IDProjectCategoryView StatusLast Update
0005939OXID eShop (all versions)4.10. AutoLoaderpublic2024-01-17 15:32
Reporterfinnegan Assigned To 
PriorityhighSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version4.8.7 / 5.1.7 
Summary0005939: EE: AutoLoader does not work with ERP SOAP and Subshop Modules
DescriptionIf you define a SOAP Plugin which will instantiate a Class defined in a Module oxNew() on this class will fail if SOAP call is for a subshop and the module containing the class is deactivated in the Mastershop
Steps To Reproduce- create a mastershop and a subshop in EE
- define a class in a module, register the class in metadata.php
- activate the module only in the subshop
- define a SOAP plugin calling oxNew() on this class in the invoke() method of the plugin
- call oxERPLogin() for the subshop
- make a SOAP call to your plugin with the received login credentials for the subshop
- oxException "class not found" will be returned for the class defined in your module
Additional InformationI traced down this issue to the following facts:
- the autoloader checks for all available classes registered with modules
- BUT the module array variables involved are always from shopId = 1 (Mastershop)
- oxutilsobject.php is responsible for loading module array vars ( public function getModuleVar( $sModuleVarName ) )
- to determine for which shop to query the module vars function getShopId() is called in oxutilsobject
- since getShopId() has NO INFORMATION about the SOAP call and the subshop the call logged into getShopId() will always return 1 for the mastershop
- but if your module is activated only in your subshop then of course the class you want to instantiate with oxNew() is not found since your module is not active in ShopId=1

My Suggestion:
- in getShopId() there are varios checks for getting the shop Id. Add a call to oxconfig::getShopId()
- or: implement a method setShopId() in oxutilsobject and call this method from ths SOAP request handler
TagsAutoLoader, ERP
ThemeAzure
BrowserAll
PHP VersionNot defined
Database VersionNot defined

Relationships

child of 0004722 resolvedSvenBrunk Shop config is not reloaded on shop id change 

Activities

michael_keiluweit

2014-11-19 16:07

administrator   ~0010332

Last edited: 2014-11-19 16:09

Reproduced.

Install EE 5.1.7, ERP 2.13.0.

Create a module:

directory: modules/oxs/
files:
1. metadata.php
2. foobar.php


Content of metdata.php:

<?php
$sMetadataVersion = '1.1';

$aModule = array(
    'id'           => 'oxs_test',
    'title'        => 'oxs_test',
    'description'  => array(
        'de' => 'Schnittstelle für die Verbindung zu ERP Systemen.',
        'en' => 'Interface for connecting with ERP systems.',
    ),
    'thumbnail'    => 'module.png',
    'version'      => '1.0.0',
    'author'       => 'OXID eSales AG',
    'url'          => 'http://www.oxid-esales.com',
    'email'        => '[email protected]',
    'extend'      => array(
        'oxarticle' => 'oxs/foobar',
    ),
);


Content of foobar.php:

<?php
class foobar extends foobar_parent
{
    public function __construct($aParams = null)
    {
        parent::__construct($aParams);
    }
}



Edit modules/erp/plugins/oxsearchplugin.php:


Replace:

class oxSearchPlugin extends oxErpPluginBase
{
    public function invoke($aParams)
    {
        $sSearchParamForQuery = $aParams['sSearchParam'];
        $iSearchStart = $aParams['iStart'];
        $iSearchCount = $aParams['iCount'];


With:

<?php
class oxSearchPlugin extends oxErpPluginBase
{
    public function invoke($aParams)
    {
        oxNew('foobar');

        $sSearchParamForQuery = $aParams['sSearchParam'];
        $iSearchStart = $aParams['iStart'];
        $iSearchCount = $aParams['iCount'];



goto: http://shop/admin/
- create a second shop. switch to second shop.

goto: Extensions -> Modules
- Activate the module erp
- Activate the module oxs_test



Create the file erp.php in the root directory of the shop. Content of erp.php:

<?php

$oSoapObject = new SoapClient( 'http://shop/modules/erp/oxerpservice.php?wsdl&version=2.13.0' );

$aData = array(
    array(
        'sUserName' => 'admin',
        'sPassword' => 'admin',
        'iShopID'   => 2,
        'iLanguage' => 0
    )
);
$oSoapCallResult = $oSoapObject->__soapCall( 'OXERPLogin', $aData );



if (!(bool) $oSoapCallResult->OXERPLoginResult->blResult) {
    throw new Exception('could not login');
}

$aData = array(
    'sSessionID' => $oSoapCallResult->OXERPLoginResult->sMessage,
    'sPluginName' => 'oxSearchPlugin',
    'aRequestData' => array(
        'sArticleId' => '7904e58fefe79cd95d2e4277761ac66a',
        'iStart' => 0,
        'iCount' => 100,
    ),
    'sPluginName' => 'oxSearchPlugin'
);

print_r(
    $oSoapObject->OXERPCallPlugin(
        (object) $aData
    )
);


Expect the output: stdClass Object ( [OXERPCallPluginResult] => stdClass Object ( [OXERPType] => stdClass Object ( [blResult] => [sMessage] => EXCEPTION_SYSTEMCOMPONENT_CLASSNOTFOUND ) ) )

michael_keiluweit

2014-11-20 10:14

administrator   ~0010336

Last edited: 2014-11-20 10:17

The problem seems to be the method oxUtilsObject::getShopId(), 'cause it returns everytime 1, when it is called via erp module.

1. $_POST: shp and actshop <- both parameters aren't set.
2. $_GET: shp and actshop <- both parameters aren't set.
3. This should work only if the erpservice is called wit the domain of shop id 2. But when it's called with the domain of shop 1, it returns 1. If shop 2 hasn't a own domain, there is no way to get an other id than 1:

if (!$iShopId) {
    $aShopUrlMap  = $this->_getShopUrlMap();
    if (is_array($aShopUrlMap) && count($aShopUrlMap)) {
        // TODO: check posibility to use oxregistry
        $oUtilsServer = new oxUtilsServer();
        foreach ($aShopUrlMap as $sUrl => $iShp) {
            if ($sUrl && $oUtilsServer->isCurrentUrl($sUrl)) {
                $iShopId = $iShp;
            }
        }
    }
 }


In my case (tested it with xampp; two domains which pointed both to the xampp htdocs directory. One is registered for shop id 2) it didn't worked with an own domain for shop id 2. But I can imagine that it could work on a webserver. In my case the problem is the way how the URL is checked if it searches after a matching known shop URL.

20.11.2014 - 10:02:06 : $sUrlHost:     secondshop             call: oxUtilsServer | oxUtilsServer::isCurrentUrl
20.11.2014 - 10:02:06 : $sRealHost:    localhost              call: oxUtilsServer | oxUtilsServer::isCurrentUrl
20.11.2014 - 10:02:06 : $sCurrentHost: localhost/modules/erp  call: oxUtilsServer | oxUtilsServer::isCurrentUrl
20.11.2014 - 10:02:06 : $sCurrentHost: localhostmoduleserp    call: oxUtilsServer | oxUtilsServer::isCurrentUrl
20.11.2014 - 10:02:06 : $sURL:         http:secondshop        call: oxUtilsServer | oxUtilsServer::isCurrentUrl


if ( $sURL && $sCurrentHost && strpos( $sURL, $sCurrentHost ) !== false ) {


The marked part of the if query fails everytime.


4. Because nothing from above worked, the method set the id to 1:
if (!$iShopId ) {
    $iShopId = 1;
}


As I mentioned: maybe a workaround is to call the erpservice with the domain of the shop id 2 instead of shop id 1.