Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with Guzzle (PSR4 transforming) #39

Closed
Wouter0100 opened this issue May 15, 2018 · 4 comments
Closed

Issues with Guzzle (PSR4 transforming) #39

Wouter0100 opened this issue May 15, 2018 · 4 comments
Labels

Comments

@Wouter0100
Copy link

Wouter0100 commented May 15, 2018

Detailed description

I'm maintining a wide variaty of WHMCS modules. Recently WHMCS seems to started using Composer in their own, closed source, software - which conflicts with my modules. Since them I'm looking for such a plugin as Imposter to fix my dependency issues.

Most things seems to work just fine, expect with Guzzle and loading PSR-4 classes.

For example a trace I gathered. Here the core WHMCS software requests Guzzle, and the autoloader seems to respond with my transformed Guzzle instance:

1  Composer\Autoload\includeFile(/var/www/*/app/modules/addons/mollierecurring/vendor/composer/../guzzlehttp/guzzle/src/ClientInterface.php) called at [/var/www/*/app/vendor/composer/ClassLoader.php:322]
--
  | #2  Composer\Autoload\ClassLoader->loadClass(DevApp\WHMCS\MollieRecurring\Vendor\GuzzleHttp\ClientInterface)
  | #3  spl_autoload_call(DevApp\WHMCS\MollieRecurring\Vendor\GuzzleHttp\ClientInterface) called at [/var/www/*/app/modules/addons/mollierecurring/vendor/guzzlehttp/guzzle/src/Client.php:25]
  | #4  include(/var/www/*/app/modules/addons/mollierecurring/vendor/guzzlehttp/guzzle/src/Client.php) called at [/var/www/*/app/vendor/composer/ClassLoader.php:444]
  | #5  Composer\Autoload\includeFile(/var/www/*/app/modules/addons/mollierecurring/vendor/composer/../guzzlehttp/guzzle/src/Client.php) called at [/var/www/*/app/vendor/composer/ClassLoader.php:322]
  | #6  Composer\Autoload\ClassLoader->loadClass(GuzzleHttp\Client)
  | #7  spl_autoload_call(GuzzleHttp\Client) called at [/var/www/*/app/vendor/whmcs/whmcs-foundation/lib/Admin/Setup/General/UriManagement/ConfigurationController.php:0]
  | #8  WHMCS\Admin\Setup\General\UriManagement\ConfigurationController->queryEnvironmentMode() called at [/var/www/*/app/vendor/whmcs/whmcs-foundation/lib/Admin/Setup/General/UriManagement/ConfigurationController.php:0]
  | #9  WHMCS\Admin\Setup\General\UriManagement\ConfigurationController->remoteDetectEnvironmentMode(WHMCS\Http\Message\ServerRequest Object ([*queryBag] => Symfony\Component\HttpFoundation\ParameterBag Object ([*parameters] => Array ()),[*requestBag] => Symfony\Component\HttpFoundation\ParameterBag Object ([*parameters] => Array ()),[*attributesBag] => Symfony\Component\HttpFoundation\ParameterBag Object ([*parameters] => Array ()),[Zend\Diactoros\ServerRequestattributes] => Array (),[Zend\Diactoros\ServerRequestcookieParams] => Array (),[Zend\Diactoros\ServerRequestparsedBody] => ,[Zend\Diactoros\ServerRequestqueryParams] => Array (),[Zend\Diactoros\ServerRequestserverParams] => Array (),[Zend\Diactoros\ServerRequestuploadedFiles] => Array (),[*headers] => Array (),[*headerNames] => Array (),[Zend\Diactoros\ServerRequestprotocol] => 1.1,[Zend\Diactoros\ServerRequeststream] => Zend\Diactoros\PhpInputStream Object ([Zend\Diactoros\PhpInputStreamcache] => ,[Zend\Diactoros\PhpInputStreamreachedEof] => ,[*resource] => Resource id #361,[*stream] => php://input),[Zend\Diactoros\ServerRequestmethod] => ,[Zend\Diactoros\ServerRequestrequestTarget] => ,[Zend\Diactoros\ServerRequesturi] => Zend\Diactoros\Uri Object ([*allowedSchemes] => Array ([http] => 80,[https] => 443),[Zend\Diactoros\Urischeme] => ,[Zend\Diactoros\UriuserInfo] => ,[Zend\Diactoros\Urihost] => ,[Zend\Diactoros\Uriport] => ,[Zend\Diactoros\Uripath] => ,[Zend\Diactoros\Uriquery] => ,[Zend\Diactoros\Urifragment] => ,[Zend\Diactoros\UriuriString] => ))) called at [/var/www/*/app/vendor/whmcs/whmcs-foundation/lib/Admin/Setup/General/UriManagement/View/Helper/SimpleSetting.php:0]
  | #10 WHMCS\Admin\Setup\General\UriManagement\View\Helper\SimpleSetting->getSimpleSettingHtmlPartial() called at [/var/www/*/app/admin/configgeneral.php:0]

This results in either incompatbility or Cannot declare class DevApp\WHMCS\MollieRecurring\Vendor\GuzzleHttp\Client, because the name is already in use in /var/www/*/app/modules/addons/mollierecurring/vendor/guzzlehttp/guzzle/src/Client.php on line 25-errors.

Also - the autoloading files for Guzzle does not work. This because Guzzle includes this file, which checks if GuzzleHttp\uri_template is loaded - but most of the time it is (because of the core software, which already has Guzzle loaded) and so my namespace's Guzzle functions won't get loaded.

WHMCS loads Composer itself and I'm not sure how their composer.json looks like. Mine is, for example:

{
    "require": {
        "mollie/mollie-api-php": "2.0.*",
        "typisttech/imposter-plugin": "^0.3.0"
    },
    "config": {
        "vendor-dir": "src/addons/mollierecurring/vendor"
    },
    "extra": {
        "imposter": {
            "namespace": "DevApp\\WHMCS\\MollieRecurring\\Vendor\\"
        }
    }
}

Context

It is important to me to keep using my current packages (I don't use guzzle directly, but most of my packages do). This could also benefit other people, as Guzzle is a widely used package to handle HTTP requests.

Possible implementation

Unsure. Maybe manually update the PSR-4 mapping?

Your environment

  • PHP 7.2
  • WHMCS addons
  • Different Guzzle versions
@tangrufus
Copy link
Member

tangrufus commented May 15, 2018

WHMCS loads Composer itself and I'm not sure how their composer.json looks like.

If 2 composer.json files in place, imposter won't and should not affects the other one, i.e: the WHMCS' composer.json.


Besides, the way Guzzle includes src/functions.php is not supported:

if (!function_exists('GuzzleHttp\uri_template')) {
    require __DIR__ . '/functions.php';
}

This if/else condition is kind of custom autoloader. So far, imposter supports composer autoloaders only. Pull requests are welcomed.


Both the above issues stop you from using imposter. Perhaps, using WHMCS's Guzzle is the simplest solution.

@Wouter0100
Copy link
Author

Darn - thanks for the fast reply. Unfortunately, I hoped Imposter was a solution for having multiple composer autoloaders and multiple composer.json files. WHMCS does not allow me to edit or manage theirs (and is not even shipped in the source).

So my modules manage their own composer.json where I added Imposter. Unfortunately using WHMCS's Guzzle isn't really possible - as my own dependencies use Guzzle, and as far as I know I can't "flag" Guzzle in my composer.json manually as installed.

@tangrufus
Copy link
Member

After a second thought, the first issue is incorrect. You usage is similar to the project goal - make 2 WordPress plugins bundle their composer packages without conflicts.

However, imposter can't be used on custom autoloaders(issue 2).

I can't "flag" Guzzle in my composer.json manually as installed.

One thing you could try is to use branch aliases - alias a "fake", "empty" package as guzzle.

See: https://getcomposer.org/doc/articles/aliases.md

@Wouter0100
Copy link
Author

Hmm - thanks for your response. After my reply I further continued searching and eventually found PHP Scoper, which does the same - but on a more aggressive level.

With some custom code and an additional script to change package ID's in autoload_files.php, I got things working and isolated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants