coenjacobs / mozart

Developers tool for WordPress plugins: Wraps all your projects dependencies in your own namespace, in order to prevent conflicts with other plugins loading the same dependencies in different versions.
https://coenjacobs.me/projects/mozart/
MIT License
430 stars 55 forks source link

Can't properly prefix and use the google/apiclient package #143

Open Konamiman opened 1 year ago

Konamiman commented 1 year ago

To be fair I'm not sure if I have found a bug or if I'm misunderstanding how Mozart works, but I'm trying to use it to prefix the google/apiclient package and so far I'm not succeeding.

I have prepared a minimal example. Assume a WordPress plugin named mozart_test with the following files to start with:

mozart_test.php:

<?php
/**
 * Plugin Name: Mozart test
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

include_once dirname( __FILE__ ) . '/vendor/autoload.php';

function mozart_test() {
    $x = new Google_Client();
    echo "All good!\n";
}

composer.json:

{
    "name": "konamiman/mozart_test",
    "require": {
        "google/apiclient": "^2.13"
    },
    "require-dev": {
        "coenjacobs/mozart": "^0.7.1"
    }
}

Then I run composer install, run wp eval 'mozart_test(); and the the "All good!" message. So far so good.

Now, let's introduce Mozart with this updated version of composer.json:

{
    "name": "konamiman/mozart_test",
    "require": {
        "google/apiclient": "^2.13"
    },
    "require-dev": {
        "coenjacobs/mozart": "^0.7.1"
    },
    "scripts": {
        "install-scripts": [
            "rm -rf vendor_src",
            "vendor/bin/mozart compose",
            "composer dump-autoload -o"
        ],
        "post-install-cmd": [ "@install-scripts" ],
        "post-update-cmd": [ "@install-scripts" ]
    },
    "extra": {
        "mozart": {
            "dep_namespace": "MozartTest\\",
            "dep_directory": "/vendor_src/psr4/",
            "classmap_directory": "/vendor_src/psr0/",
            "classmap_prefix": "MozartTest_",
            "packages": [
                "google/apiclient"
            ],
            "delete_vendor_directories": true
        }
    }
}

and in the mozart_test() function I now try to instantiate a class named MozartTest\Google\ApiClient instead.

The first issue is that now composer install throws this error:

In Finder.php line 592:

The "/home/konamiman/wordpress/wp-content/plugins/mozart_test/vendor_src/psr0//google/apiclient" directory does not exist.

This issue goes away and composer install succeeds if I add the following to extra/mozart in composer.json (taken from the configuration for the apiclient package in composer.lock):

"override_autoload": {
    "google/apiclient": {
        "psr-4": {
            "Google\\": "src/"
        }
    }
}

But now when I try to run the mozart_test() function I get PHP Fatal error: Uncaught Error: Class 'MozartTest\Google\Client' not found. And indeed, if I look at the autoload files in vendor/composer I see no declarations for the Google classes at all (if I don't use Mozart I can see 'Google\\' => array($vendorDir . '/google/apiclient/src'), in vendor/composer/autoload_psr4.php).

So my questions would be:

  1. Why do I need to add the extra configuration in override_autoload? Isn't Mozart supposed to take the existing configuration from composer.lock by default?
  2. Why isn't the Google\Client class (converted into MozartTest\Google\Client) registered by the autoloader? Am I doing something wrong?

Another thing I've noticed is that the Google apiclient library has a file named aliases.php in which class alias like 'Google\\Client' => 'Google_Client' are declared. These entries get properly renamed by Mozart, but I wonder how this works when there are other WordPress plugins that also use the apiclient package.

Thanks for your time!

webcreativeng commented 2 months ago

Hi.

Did you get a fix on this or detect what the issue was?

Cheers!

Konamiman commented 2 months ago

Hi @webcreativeng, I wasn't able to proceed further so I ended up solving the problem I had at hand without using Mozart: https://github.com/woocommerce/woocommerce-bookings/pull/3492