First of all, I know this setup is stupid but this is what we're stuck with 🤷♂️
We build websites with our company framework. The website contains some classes that the framework directly accesses. This means we have a circular dependency. This was not a problem until now.
These are slimmer versions of our composer.jsons:
Framework:
The framework just defines some other
{
"name": "company/framework",
"type": "library",
"require": {
...
}
}
Website:
{
"name": "company/website",
"require": {
"company/framework": "^4.3",
...
}
}
Very simple, framework is a dependency of website.
Now, I'm trying to setup a CI server with static analysis for the framework. As mentioned, the framework requires some files in the website for static analysis to succeed.
The new company/framework/composer.json file looks like this:
{
"name": "company/framework",
"type": "library",
"require": {
"company/website": "^4.3",
...
}
}
This works fine when testing a tagged framework version. Whenever we're in a develop branch Composer will fail since website requires a stable ^4.3 version of the framework but this is a develop branch.
Is there any way I can work around this?
Extract the classes that are needed to test the framework into a separate package.
Framework requires that package.
Website requires that package. And requires Framework (which also requires that package).
Voila, you transformed a circular dependency into a linear graph.
Add semantic versioning to this approach, and you will never have serious problems - or spot them pretty soon.
Related
When I worked with Spring MVC in Java , it manage all dependency by Maven and I think with Laravel , all library are managed by Composer. (I'm not sure, cause I'm a newbie in Laravel ^^ )
Now, I have 2 laravel project, one common project and one sub project , in sub project how can I use common project through Composer management ?
As mentioned by Pitchinnate, you can include a local repository via Composer.
You'll want to reference the second repository that the first is dependant upon in the "repositories" section of your composer.json, and then require it.
Ex:
{
"repositories": [
{
"type": "path",
"url": "../../packages/my-package"
}
],
"require": {
"my/package": "*#dev"
}
}
This should allow you to link your project and sub-project, if we've understood your question correctly.
Cheers!
I have an application server, it is like a blog system (my wordpress killer). It is based in php hosted in github and using composer to manage dependencies. Each installation is hosted in my server (I make the installation for them). When a client requires a new "addon/plugin" I create a new package and host it in a private repository hosting. The problems comes when I need to add new package:
Client 1.
- package for calculate prices
Client 2.
- package for show a welcome message
Client 3.
- package for add a calendar
My application will have every package ready to be used in all instances because I am requiring them via composer:
"require": {
"killer/calculate": "dev-master",
"killer/message": "dev-master",
"killer/calendar": "dev-master"
}
Now image if I have 2K clients and everyone of them are requesting custom packages. How can I provide an application (cloned massively) but just keeping in the each installation just the packages that each client need?
Hypothetical solution
I was searching (if it is possible) for something like the following. For each installation, create a file manually where its content specifies the package to be required. For example, let's say each client's installation has something like this:
//composer.json
"require": {
}
//plugins.json (this file is ignored via .gitignore)
{
"killer/calculate": "dev-master"
}
Then, somehow tells to composer.json to require the data from plugins.json. By this way I am avoiding to create a huge composer.json sharing unnecessary packages for all clients.
There is a feature request for allowing composer.json to extend another file. You should go comment on it to draw some attention to it.
The way you would use that feature is to create a default.json file that contains all your regular composer.json contents, including a require section that lists all the common packages you need.
// default.json
{
"require": {
"php": ">=5.4.0"
}
}
Then have a composer.json file for each project that extends and/or overrides default.json like this:
// composer.json
{
"require": {
"killer/calculate": "dev-master"
},
"extends": "default.json"
}
The final result would be:
{
"require": {
"php": ">=5.4.0",
"killer/calculate": "dev-master"
}
}
If you can't wait on the merge request, then you can go checkout the composer fork from the merge request's author and try it out.
Sounds like you have created your own package ecosystem. So, you could work independently from Packagist and simply host all the packages yourself, probably using Satis.
The main suggestion i have is to introduce your application as a package into this ecosystem.
Your application composer.json contains only the packages relevant for the application itself.
{
"name": "better/application",
"require": {
"another/library": "1.0.0",
"another/framework": "1.2.3",
"another/generator": "2.1.3"
},
"require-dev" : {
"phpunit/phpunit" : "4.*",
}
}
I think, that "cloning" the application for the customer/client is not a good idea, because it ignores that plugins have dependencies on a specific version of your application, which is not always "latest" or "dev-master". Let Composer pull the application by version for each client.
By this way I am avoiding to create a huge composer.json sharing unnecessary packages for all clients.
create one repository per new customer/client
add the application itself and the packages requested by the client inside composer.json
add a client config on top
For instance, the composer.json for Client1:
{
"name": "better/application-for-client1",
"require": {
"better/application": "1.0.0",
"better/app-calculate": "1.2.3"
}
}
For instance, the composer.json for Client2:
{
"name": "better/application-for-client2",
"require": {
"better/application": "1.0.1",
"better/app-calculate": "1.2.4",
"better/app-message": "2.0.0"
}
}
Each customer might have its own setup, requiring different version of your application with different additional application packages/plugins (here indicated by using the prefix "app-").
In the end you have two essential files for a customer: a composer.json and a configuration file.
(How the application detects the available modules is another story. At least, the autoloading will work out of the box, when you register Composers Autoloader during the bootstrap of the application.)
(Sidenote: If your application is a multi-site application, then you might replace "cloning" by "symlinking". With multi-site, i mean an application which runs from one central place using a site id (often customer id). If you have the application folder with all packages for development in one monolithic folder, then build a relase folder by cleaning the development stuff out, so that you get a release version with a blank default config. Then symlink the application, the requested packages to the customer folder and place a configuration on top. This approach might save quite a bit disk space and doesn't involve Composer at all.)
I would also encourage you to use the approach proposed by Jens A. Koch in his answer, having a composer.json file for each customer and requiring the main application and all required plugins. Composer supports this scenario quite well and I want to point you to the starting points:
Composer Types
Composer allows to specify types for packages. You can define your own type to mark plugins for your application as such. Many open-source projects (e.g. Symfony with bundles) have adopted this approach for their plugin eco-system.
Custom Installers
You can register custom installers that can execute for a specific type of composer package (i.e. the type you defined for your plugins). Then you can customize the installation process for your plugins, which means you can:
move your custom plugins to specific locations,
automatically adjust plugin configurations,
and most importantly: provide a mechanism that allows the main application to see which plugins are available.
Hmm.. require all packages ones..
It means one big composer.json for everything is running with your system / is compatible with your system. Maybe you will have to introduce a versioning system too.. So you could end up with v1_composer.json ..
But for each client load only the required packages. For example generate a requires.php for each client with necessary require statements which links to your shared libraries.. This will be the fastest solution and most efficient, because you sharing the code which you can share and you only load it when needed
Conclusion
Share as much code as possible... but don't use it when you don't need it.
I am trying to integrate Agile CRM in my Symfony2 application.
There is a PHP library provided by Agile :
https://github.com/agilecrm/php-api
However it's not a bundle.
How can I integrate it correctly in my application? Should I put a require once in my app.php or my kernel? Or is there a better way?
Composer has a feature to auto load files
https://getcomposer.org/doc/04-schema.md#files
{
"autoload": {
"files": ["src/MyLibrary/functions.php"]
}
}
Other ways ?
Expose the functionality as a Service using the code provided in the library.
I think the best way to do this is to:
contribute to the project to add a composer.json
contribute to allow the configuration to be loaded from elsewhere instead of being hardcoded
Then you'll be abled to simply use composer to load that package. :)
Composer (as mentioned in other answers) is only a dependency manager and therefore only part of the solution. If you are really interested in the cleanest way, it is quite simple: write the bundle yourself.
In fact, there are many examples of bundles that work as integration layers for 3rd party libraries. For example, look at https://github.com/nelmio/alice, a Symfony2 bundle meant to wrap Faker, an external data fixture lib.
A bundle may declare configuration options overridable by the app main config files. It may expose service definitions for the library objects so that you can avoid to create them manually and inject them when needed (whether or not the library is written with DI in mind). It may be also useful for twig extensions, event listeners and so on.
A good written bundle promotes reuse, testability and separation of concern. Don't be scared from writing your bundle from scratch, start here http://symfony.com/doc/current/cookbook/bundles/best_practices.html
As agilecrm/php-api is not available on Packagist the best approach would be to add the repository to your composer.json file and then install the package the same way you would with everything else.
{
//...
"repositories": [
{
"type": "package",
"package": {
"name": "agilecrm/php-api",
"version": "2.1.0",
"source": {
"url": "https://github.com/agilecrm/php-api",
"type": "git",
"reference": "2.1.0"
}
}
}
],
"require": {
//...
"agilecrm/php-api": "2.1.0"
}
//...
}
You should add it to your composer.json
{
"require": {
"agilecrm/php-api": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "git#github.com:agilecrm/php-api.git"
}
]
}
or you can add it to composer autoloader https://getcomposer.org/doc/01-basic-usage.md#autoloading
I am working on several projects but each one connects to a REST web service.
I've developed the first one using Laravel, and developed a few classes really useful to communicate with the web services.
I would like to start the second one, and of course, reuse the classes developed for the REST connection.
My problem is, my company wants me to use several git directories for the projects, and each one should be uploaded to a different springloops project.
Springloops is a bit like github, you can upload your code using git.
How would you proceed to avoid copy/paste and use the same laravel code but in different projects (and I guess, in different locations)?
I'm not sure I'm really clear, but don't hesitate to ask me for more information if you need to.
Thanks.
How about creating your own Composer package and store it in a separate (private) Git repo? As far as Composer is concerned it's just like any other package, you may want to check out this section of the docs:
Using private repositories
Exactly the same solution allows you to work with your private
repositories at GitHub and BitBucket:
{
"require": {
"vendor/my-private-repo": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "git#bitbucket.org:vendor/my-private-repo.git"
}
]
}
The only requirement is the installation of SSH keys for a git client.
I've developed my own PHP framework which is used to power many different apps. At the moment, it uses Twig, Symfony YAML, Monolog and Facebook SDK as components. Now I need to create an admin section so those who update the content can login to a secure area, and very likely a user section, so their would be different roles too.
I like the look of Zend and Symfony's components and I have found many Stack Overflow questions related to it, but I was wondering:
If I use Symfony2's Security Component, how do I use it outside of the Symfony2 framework? This is very frustratingly missing from the Components Handbook, seeing as they've documented every other of their components.
If I use Zend_Auth and Zend_Acl, can I load them with Composer, without downloading the full stack? Or would I have to download it manually and extract the classes?
Do you recommend another package?
Found the solution. http://packages.zendframework.com/
Reason I didn't find this out earlier, Zend 2 uses it's own repository instead of Packagist.
Composer.json:
"repositories": [
{
"type": "composer",
"url": "http://packages.zendframework.com/"
}
],
and
"require": {
"zendframework/zend-authentication": "2.0.*",
"zendframework/zend-permissions-acl": "2.0.*"
},
"minimum-stability": "beta"
Though I'm using "minimum-stability": "dev" for my project