Add 3rdParty Library to Package

Permalink 1 user found helpful
I have the following requirement: I need to add a 3rdParty Library (GuzzleHttp) to my Package. This library is namespaced. So my question is, how can I use the classes from that library in my package?
I have tried putting the library in the following folder:

and tried loading it like that:
use Concrete\Packages\MyPackage\Vendor\GuzzleHttp\Client;

where the header of the Client.php is the following:
namespace GuzzleHttp;
use GuzzleHttp\Event\HasEmitterTrait;
 * HTTP client
class Client implements ClientInterface

but had no success. Should this be done in another way?
Thanks for any help.

View Replies: View Best Answer
andrew replied on at Permalink Best Answer Reply
What if you installed it via composer

Put composer.json with the guzzle lines in it in the root of packages/my_package/. Then use composer install to install it ( if you're not familiar with it but I imagine you are). This will create a vendor/ directory and install guzzle into that directory.

Then, in your package's controller.php file, include the autoload file from composer

require_once(__DIR__ . '/vendor/autoload.php');

That will include all the autoload code necessary to make Guzzle work. Then just load the libraries as per the guzzle documentation and it should automatically work, since composer will have set up the class mapping and PHP autoloading.
Uranus replied on at Permalink Reply
It's really helpful
creatingweb replied on at Permalink Reply
Thanks a lot, that worked just great.
andrew replied on at Permalink Reply
Excellent, glad to hear it.
programmieraffe replied on at Permalink Reply
Hi Andrew,

what is the best way in 5.7 to achieve this without composer?

Thanks in advance,
andrew replied on at Permalink Reply
FYI: I've written up a specific how-to on this here:
mesuva replied on at Permalink Reply
Just had a question with libraries pulled into packages using composer.

If we do this, is this just for private use, or would such packages be suitable for the marketplace?

What I'm confused about is what would happen if two packages were installed that has pulled in the same vendor library this way.

For example, I've been using Guzzle in a package lately (seconds to add via composer) - what would happen if someone else developed a package that included Guzzle? (which could be quite likely for such a useful library)

Does composer's autoloading take care of that potential conflict, or would it try to load the same classes with the same namespaces more than once and error?
JohntheFish replied on at Permalink Reply
For the marketplace The PRB have been approving packages that are already built with all dependencies. ie. The developer composes them, not the purchasing site owner.
mesuva replied on at Permalink Reply
Good to know, thanks John.

I'm still left with the question though: would multiple packages installed that use the same libraries cause class loading conflicts?

(I guess I could always test it to answer my own question)
JohntheFish replied on at Permalink Reply
I suppose that all depends on how the autoloader works things out.

PS. Yes, a test would be good. Always better to have a real test & proof of behaviour than a theoretical answer.
mesuva replied on at Permalink Reply
I've just done a little test where I created two packages, both that pull in the same library via composer.

What I found was that there were no errors thrown when I was loading up classes from each package at the same time.

So it seems that once a class has been registered for autoloading once with a certain namespace it can't/won't be loaded again.

Where it gets potentially a bit messy is in situations where there are two different versions of the library pulled in. It then comes down to the order that the packages have been installed (so the order that the on_start get run, or however you load in your vendor/autoload.php). If a package pulls in version 1.1 of a library before your package pulls in version 1.5 there's not much you can do.

I think in practice this wouldn't be too much of a problem, as long as package developers keep their vendor directories reasonably up to date.

Maybe Instead of loading in third party scripts in package on_start function, perhaps it should be encouraged to do such loading closer to where the classes are actually needed?I'm thinking that the more that developers register the classes they need closer to when they use them, the less chance they'll be of conflicts.
(no-where near as tidy though)
Mainio replied on at Permalink Reply

Just bumped into this trying to find other thing. But to add, there is actually another discussion about the same topics at:

About your final notes about requiring only when needed: this is actually how composer autoloaders work. When multiple autoloaders define the same class to load, the last defined autoloader always wins (in the current implementation of composer).

To be able to properly handle these conflict situations, it would be currently required for all concrete5 packages to be distributed through composer. Which is theoretically possible but in the real life I don't see that happening due to multiple reasons, primarily because of how c5 is currently structured and who primarily uses it.