I have a composer project for which I need to create a custom plugin that will also use composer. Both the main project and the plugin use the same dependencies but in different versions. How should I resolve these dependencies between each other? So that the plugin uses a dependency from its composer vendor and not from the vendor of the main project?
I found for example this solution: https://github.com/TypistTech/imposter-plugin but it doesn't seem very elegant to me.
Compare as well with another recent Q&A Dependency Conflict between Plugin and Theme which should add more general clarification.
As you normally use Composer to resolve dependencies you could also use it here. However there seems to be a little misconception or at least some lack of clarity in your question:
So that the plugin uses a dependency from its composer vendor and not from the vendor of the main project?
In a compoer project, there is only one vendor folder, the one of the root project, the one you likely meant by "main project".
This paired with the description of only a "Project" and a "Plugin" there might be a slight chance that it is either one project which has its dependencies managed by Composer ("Project") of which one dependency is the "Plugin".
Or you have just two independent projects ("Project" and "Plugin") that can work independent to each other (normally not the case for "Plugin" material).
At the end of the day it is less a question of Composer, but just whether your software projects dependencies can resolve or not in a compatible manner.
As PHP has a global namespace and it is static, if you really have incompatible dependencies across the same software packages, you need to fork these and rename the namespace so that you can have one dependency for your module A and one for module B. So next to your a "Project" and a "Plugin" you also have projects you manage the dependency packages in, e.g. rewriting Namespaces and then offering to composer via a repository.
Related
When distributing Shopware Plugins as a ZIP file, it must include the vendor directory, but without the shopware/core, shopware/administration, etc. dependencies defined in the composer.json. That one I got to work.
But how to include dependencies, which themselves have dependencies, that overlap with the shopware/core dependencies?
Explicitly, I try to add a package, that depends (like Shopware itself) on psr/cache.
But when I include it, I receive the following error message, when activating the plugin:
Fatal error: Cannot declare interface Psr\Cache\CacheItemPoolInterface, because the name is already in use in /var/www/html/vendor/psr/cache/src/CacheItemPoolInterface.php on line 14
Is there any known workflow to solve these kinds of issues? The documentation, that Shopware provides, do not explain how to solve these kinds of conflicts.
If you distribute plugins for Shopware and use Composer libraries, you can find scope and namespace conflicts like Fatal error: Cannot declare interface.... The same problem is found on WordPress, Joomla, PrestaShop, or any other CMS where you don't have complete control of what is installed.
As you described, the initial problem is a conflict between the core libraries and your plugin dependencies. Additionally, you can find trouble between every package installed on the system that copies Composer packages to Shopware using the same libraries or different versions of the same libraries.
In practice, the only real and most flexible solution is prefixing the PHP code that you bundle in the ZIP file. In this way, you are entirely sure that it works independently of what is installed alongside it.
In the PHP ecosystem, there are a few solutions to prefix namespaces and customize the project scope. For instance: php-scoper, namespacer, mozart or PHP-Prefixer.
Disclaimer: I'm the lead PHP-Prefixer developer.
If it is your plugin, then there are three options.
Require the same package
Use a tool like https://github.com/humbug/php-scoper to fix the naming problems.
Install it via composer
If it is not yours, you should create an issue for the plugin provider.
Thanks for your attention, this is a question of organization, I work with PHP and GIT for version control. I use Netbeans IDE to program, GIT integrated (although I am still a rookie).
Normally, I follow the approach that Symfony2 specifies for organize the project files, but I use my own framework for my projects.
The (main) question is: Any component or code part which has its own version control must be located under the /vendor/directory?
For example:
I have my project files in src\Acme\ProjectX\, also the utility package which use all my projects: src\Acme\Util\, and it is under the version control too (GIT).
and now let's remember the basic skeleton of a project based on Symfony or similar:
/app (application related elements)
/src (source code of the project)
/vendor (third party libraries)
/web (front end controller, the web directory, assets resources etc...)
So, Must be 'Acme\Util' included in the vendor directory? And, is necessary to use composer to declare the dependences?
In addition, the Utility package has a lot of classes but only few are used in projects. Must I remove those are not using by the project.
Summarizing, It will be nice if someone can contribute his knowledge for help me to represent an scenario like this.
I hope I could explained...
Thanks in advance!
Vendor directory
It's a good practice to separate external dependencies and the application code. If you are using Composer you can change it to something else.
Unused classes
Unused classes shouldn't matter if they aren't being loaded. They'll just take a bit of extra disc space.
It might be a good idea to separate the Utility package into multiple packages if you find yourself frequently using only a small part of it.
Dependency managers
It isn't necessary to use a dependency manager, but it sure does help. Having to install, configure and maintain everything manually (especially with many dependencies and sub-dependencies) would be a horror.
I'm making WordPress plugin that is using a few third party libraries. Is it common practice to use Composer for WordPress plugin?
If it's okay to use it, then I assume that I should provide all Composer files along with my plugin, because I don't want to make people manually run composer install.
Another question is, is it safe to use Composer's autoloading? I configured it to autoload my own classes and the libraries are of course autoloaded as well. That's convenient.
Is using Composer with WordPress plugin an overhead? Or does it have any additional issues?
This is old question, but nothing has changed since 3 years. Using Composer for requiring dependencies in WordPress plugin/themes is usually a bad idea. PHP does not allow to load more than one class with the same FQN. So if two different plugins will install the same library independently, classes from random installation of library will be loaded which may result really weird bugs (especially if these are different versions of the same library). To avoid such problems you should have only one composer.json instance per project, so in this case Composer should be run at WordPress level.
In general if you have the same package installed multiple times, you probably will get some troubles (and this will happen if every plugin maintainer will use Composer on its own). Note that this is not directly related to Composer - if you copy libraries manually you will get exactly the same problem (maybe even worse).
If you really want to use Composer in your plugin you may try tools like humbug/php-scoper which will modify namespaces of used dependencies and make them unique.
I've already spent a few hours searching for an answer to my question but still haven't found a suitable answer.
Basically, I've taken over a PHP project which uses composer to pull in third party libraries/dependencies. However, a lot of the dependencies are no longer managed and is possible that the author might remove them completely from github anytime.
I'm currently thinking that I should check in the whole vendor folder so even if the libraries are no longer available through composer, I will still have them with me.
Alternatively, I could fork those libraries repo and have composer to pull from my account instead. Is this acceptable?
I would really hope to get some advice on the best method to deal with this.
Thanks in advance!
Should i check in the whole vendor folder in, so even if the libraries are no longer available through composer, I will still have them with me?
My suggestion is to create a backup branch containing your application with all it's vendors. Just do a git checkout -b {VERSION}-backup, followed by composer install (which gets you the composer.lock and all dependencies into the defined vendor folder) and then a git push origin {VERSION}-backup.
This allows to rely on dynamic package management as long as the packages are available via Packagist and downloadable from their source (Github, etc.).
Now, in case, a dependency gets deleted and becomes un-available, you remove it from your composer.json and merge the code from the last {VERSION}-backup branch into the master branch. = You replaced a dynamic dependency with a static one from you backup.
By the way: ever thought about getting a security audit for your code?
This will not work, with dynamically pulled dependencies. Security audits are done for specific versions - for a static set of dependencies. Given this context, pushing in a complete app with all it's dependencies is common and a best-practice. But what do we have: Composer in the backend to install new themes and composer install --no-dev --optimize-autoload on the production box to "install" software. Modern times ;)
Could I fork those libraries repo and have composer to pull from my account instead. Is this acceptable?
Yes! And you might also ask the guys over at Packagist to remove no-longer maintained packs or get them replaced or aliased to a new personal fork.
It really depends on whether your project needs to be optimized for portability or not.
Although, it's better safe with a best-practice violation, than sorry with an unavailable dependency you have to spend time replacing and refactoring for ...
From her packagist - theoretically it is possible but unlikely.
From the practice the main problem with packages directly connected to CVS. But if it is live project you allays can find another copy of code to recover functional.
First of all, I'm a complete newbie to Composer. I've been trying it out since it's a sounds awesome and mainly because Zend Framework 2 uses it.
Zend Framework 2 is actually also the reason for this thread.
It get the basics of Composer. But with my current server setup I have a request, which I can't seem to figure out if possible.
Let me explain.
I have multiple Zend Framework 2 projects:
/home/morten/sites/Project-1/
/home/morten/sites/Project-2/
/home/morten/sites/Project-3/
All of these projects should be running ZF2. When running composer in each project - each of them get their own separate download of the ZF2 Library files. Which is a bit redundant with my setup.
I have a complete and up-to-date download of ZF2 Library located at:
/var/www/shared/Zend/
And my php.ini has that path added to PHP's include_path, so the whole ZF2 library is available for all the three projects.
IS IT POSSIBLE to make Composer use in it's setup. Because if I try to change stuff and try things out in the composer files, then it just re-downloads Zend because it's a required component for other modules.
Can this be done? And if yes, how can I do it?
Hope I have explained myself good enough for you guys to understand what I'm trying to do and want :)
Thanks a lot in advance!
Regards,
Morten
You might be able to have one composer.json file stored in /var/www/shared/Zend, where you would put your dependencies and use Composer do manage them. Then all projects could include the same autoloader.
However, I wouldn't recommend that approach:
Your project's dependencies (composer.json) should be stored with your project. If you want to install your project somewhere else (for instance if you want to move one project to another server), you are missing the composer.json to install the required dependencies.
It will not be possible to update the dependencies of one project, without updating the dependencies of all other projects. If you want to introduce a new feature in Project 1, which requires a new version of a certain dependency, all other projects will get this new version as well - which might introduce backward compatibility breaks if an older feature that Project 2 relies on, is no longer supported. Since you can only have one version of each dependency, it is not possible for two projects to have different versions of the same dependency.
This approach might be useful if all projects will have the exact same functionality and code, but in that case you should probably merge them into one project.
In all other cases, I would suggest to use Composer the way it's supposed to be used: give all projects their own composer.json file and let Composer download the dependencies per project, in each project's vendor directory. The downside is that it'll cost you a little more disk space, but you'll get a lot of flexibility for it in return.