skip to Main Content

I have two modules (myModuleA and myModuleB) on a PrestaShop website that are using different version of the library phpofficephpspreadsheet.
The problem is that when I call a method from phpofficephpspreadsheet in myModuleA, it’s start using myModuleB phpofficephpspreadsheet method.

Example:

Call to a member function setActiveSheetIndex() on null

in modules/mymoduleb/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php (line 1439)

in modules/mymodulea/test.php (line 33).

Is it possible to rename namespace from phpofficephpspreadsheet ?

I want to use phpofficephpspreadsheet like so :

use MyModuleAPhpOfficePhpSpreadsheetSpreadsheet; 

and

use MyModuleBPhpOfficePhpSpreadsheetSpreadhsset; 

2

Answers


  1. You wouldn’t need to rename the namespaces, just use an alias:

    use MyModuleAPhpOfficePhpSpreadsheetSpreadsheet as module_a_spreadsheet;

    use MyModuleBPhpOfficePhpSpreadsheetSpreadsheet as module_b_spreadsheet;

    Then you can use them independently:

    module_a_spreadsheet::foo();

    module_b_spreadsheet::foo();

    More about aliasing: https://www.php.net/manual/en/language.namespaces.importing.php


    Update – Based on your comment, it IS possible to create an alias for an entire namespace, but you would need to register the same new namespace alias for all additional classes that were called within the original class. You could use a combination spl_autoload_register and class_alias, but this seem like a huge waste in resource and a bit of overkill in my opinion. I haven’t tested the code below, but I think it would be a good place to start:

    spl_autoload_register(
        function( $class_name ){
            
            $original_namespace = 'PhpOffice';
    
            if( substr($class_name,  0, strlen($original_namespace) ) != $original_namespace ) {
                return;
            }
    
            $module_a_class = 'MyModuleA\'.$class_name;
            $module_b_class = 'MyModuleB\'.$class_name;
    
            class_alias($module_a_class, $class_name);
            class_alias($module_b_class, $class_name);
    
            $module_a_exists = class_exists($module_a_class );
            $module_b_exists = class_exists($module_b_class );
        },
        $throw = true,
        $prepend = false
    );
    

    I think the simplest solution is to just create a couple of variables and use those:

    $module_a_spreadsheet = new PhpOfficePhpSpreadsheetSpreadsheet();
    $module_b_spreadsheet = new PhpOfficePhpSpreadsheetSpreadsheet();
    
    Login or Signup to reply.
  2. This is a common issue with the PrestaShop modules, where we don’t have one composer.json, but all modules load their dependencies.

    The solution could be to prefix all your vendors, there are some tools to help you do that:

    https://github.com/humbug/php-scoper
    or PHP-Prefixer: https://github.com/PHP-Prefixer/hello-prestashop-world

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search