3

I have two composer packages in my app that are creating a namespace collision in a third party module. I'm trying to determine the least disruptive way to disambiguate within the third party module so that I don't have to fork the packages.

First package from Vendor X, located in a directory structure like

path/to/vendor/VendorX/MailPackageA:

<?php

namespace MailPackageA;

class Mail {
    ...
}

My existing third-party module, which lists VendorX/MailPackageA as a dependency, located in structure like

moduleDirectory/MailingModule/mail.inc:

<?php

class ThirdPartyMailMod implements CoreMailSystem {

    $mail_object = new MailPackageA\Mail();
    . . .

}

For slightly different mailing functionality used in another module, I had to add a package that uses the same namespace identifier (MailPackageA), but from a different vendor, "VendorY". Like VendorX/MailPackageA, it's placed in a directory structure like

path/to/vendor/VendorY/MailPackageA:

<?php

namespace MailPackageA;

class Mail {
    ...
}

After adding this, I get errors in MailingModule/mail.inc at $mail_object = new MailPackageA\Mail(); because of the obvious namespace collision between MailPackageA\Mail classes from VendorY and VendorX.

Routes I've already been down, but failed:

  • Modify PSR-4 autoload rules in composer.json for either of the packages to create new namespaces. (I'm getting the sense my framework -- Drupal 7 -- does not respect the composer autoload rules, and simply defaults to stock php 7 namespacing), so I've abandoned that for the moment.
  • Try to add a vendor prefix alias to the MailingModule/mail.inc file with use.

    <?php
    
    use VendorX\MailPackageA; 
    
    \\ also tried the `use VendorX\MailPackageA as MailPackageA;` pattern to no effect
    
    class ThirdPartyMailMod implements CoreMailSystem {
    
        $mail_object = new MailPackageA\Mail();
    
    }
    

    I suspect that my app doesn't know about the vendor directories. Not sure how to force that.

What's the least disruptive way (i.e. minimal forking/patching) to make sure MailingModule only uses the MailPackageA\Mail class from Vendor X?

Ryan
  • 53
  • 4
  • Do you `include vendor/autoload.php` anywhere in the project? If Drupal (7 or less) doesn't respect PSR-4, it is no use relying on its autoloader to get the classes from vendor packages. – ob-ivan Feb 01 '18 at 21:11
  • If two seperate modules use the same namespace and don't respect the common rules of namespacing, there's nothing you can do but opening bug reports – Nico Haase Feb 02 '18 at 09:05

1 Answers1

0

to overcome this problem use alias when you use the namespace . use as keyword like this

use VendorX\MailPackageA as newPackageName; 

and if you need to call the class from this namespace you will have it like this

$packageName = new newPackageName\Mail();
samehanwar
  • 3,280
  • 2
  • 23
  • 26
  • Thanks @samehanwar. When I try that approach, I get the following error: `Error: Class 'VendorX\MailpackagaA\Mail' not found in ThirdPartyMailMod` – Ryan Feb 01 '18 at 17:14
  • 1
    That won't work if there is no visible difference between a class from the namespace `MailPackageA` located at folder X and another class from the namespace `MailPackageA` located at another folder – Nico Haase Feb 02 '18 at 09:06