How to get multiple vendor directories with composer? - php

My project relies on ZF and on a JS library. I wanted to be able to deploy the ZF library to the normal location (vendor/zendframework/zendframework1) but then deploy my JS library to somewhere else (public/my-vendor/my-library). Is there anyway to do this?

Composer is meant to manage your PHP dependencies, not JS.
Also, it only supports one vendor folder.
You might follow the way Symfony bundles use:
install everything in vendor
link (or copy) public assets to a public directory as part of your deployment process
In my opinion it's safer than installing something in a public folder (as long as you copy/link public part of a library only).

I came across the symlink idea but I wanted to automate this instead of manually creating the symlinks. I was going to create a composer script to create the symlink. I then found that symlinks on Windows and *nix need to be created in different ways which made this solution get messier by the second. I found that in the composer docs they talk about this same type of issue on the custom installers page and say that to solve this to create your own custom installer.
Relavent docs section: http://getcomposer.org/doc/articles/custom-installers.md
My custom installer: https://github.com/ddelrio1986/zf1-public-asset-installer

I have implemented this composer plugin to install packages into user (custom) defined folders you can just include it in your composer.json, follow the example and tell me if you have more questions :)
https://github.com/mnsami/composer-custom-directory-installer
composer-custom-directory-installer
A composer plugin, to install differenty types of composer packages in custom directories outside the default composer default installation path which is in the vendor folder.
This is not another composer-installer library for supporting non-composer package types i.e. application .. etc. This is only to add the flexability of installing composer packages outside the vendor folder. This package only supports composer package types,
https://getcomposer.org/doc/04-schema.md#type
The type of the package. It defaults to library.
Package types are used for custom installation logic. If you have a package that needs some special logic, you can define a custom type. This could be a symfony-bundle, a wordpress-plugin or a typo3-module. These types will all be specific to certain projects, and they will need to provide an installer capable of installing packages of that type.
How to use
Include the composer plugin into your composer.json require section::
"require":{
"php": ">=5.3",
"mnsami/composer-custom-directory-installer": "1.1.*",
"monolog/monolog": "*"
}
In the extra section define the custom directory you want to the package to be installed in::
"extra":{
"installer-paths":{
"./monolog/": ["monolog/monolog"]
}
by adding the installer-paths part, you are telling composer to install the monolog package inside the monolog folder in your root directory.
As an added new feature, we have added more flexibility in defining your download directory same like the composer/installers, in other words you can use variables like {$vendor} and {$name} in your installer-path section:
"extra": {
"installer-paths": {
"./customlibs/{$vendor}/db/{$name}": ["doctrine/orm"]
}
}
the above will manage to install the doctrine/orm package in the root folder of your project, under customlibs.
Note
Composer type: project is not supported in this installer, as packages with type project only make sense to be used with application shells like symfony/framework-standard-edition, to be required by another package.

By default, Composer reads composer.json schema. But, it can also use a different file. For instance, you can have zendframework.json and my-library.json.
In the zendframework.json, you can define:
"config": {
"vendor-dir": "zendframework/vendor"
},
In the my-library.json, you can define:
"config": {
"vendor-dir": "my-library/vendor"
},
Finally, you can update the libraries in this way:
COMPOSER=zendframework.json composer update
COMPOSER=my-library.json composer update
This is a simple idea. The benefit is that you solve the issue without third-party tools.

Related

Laravel 5.1 Package Development - loading packages dependencies in development

Hi I'm trying to develop a package in Laravel 5.1. Thanks to help here I have the basics set up.
My current problem is how to load dependencies for the package while I'm developing it.
In the packages composer.json I have added dependencies and have these installed now in a vendor folder within my packages development folder. This is not the frameworks root vendor folder.
Here's my require section of the packages composer.json:
"require": {
"illuminate/support": "~5.1",
"php" : ">=5.3.0",
"google/apiclient": "dev-master"
},
Because they are not part of the main autoload process what is the best approach to ensuring the dependencies for my package are loaded correctly from within the development folder? How do I include the autoload? I'm concerned that if I reference them to their current location/namespace that it will break when later installed as a package in another app.
in my code I have the following:
$client = new \Google_Client($config);
which gives the error:
Class 'Google_Client' not found
I can get round this by adding this dependency to the main composer.json but don't think that is the correct approach to keep the package development independent (if that makes sense)
When I developed in L4.2 there was the workbench which took care of the loading which of course no longer features in L5.1
Any help and best practice appreciated
Because they are not part of the main autoload process
I think you misunderstood how composer dependencies are managed. When in your main compose.json file you list a dependency, composer will add it to the main autoload process as well as all their dependencies, and the dependencies of their dependencies, and so on recursively.
You don't have to worry about where the dependencies are stored or how Composer will load them. Composer will automatically add them to the autoload file and all you have to do is make sure you require the composer autoload file. Once you require the composer autoload file, all the classes and functions loaded by composer will be available. Provided you required the composer autoload file all you have to do to use the classes from any of the installed packages is to make sure you address them using the proper namespace. Composer is smart enough to know where all classes are stored and how to load them (that is what psr-0, psr-4,... are for).
So if you are developing a Composer package, lets call it 'A', and you list the package 'C' as one of the dependencies of your package 'A', composer will add it to the autoload file for you. If you use another package, lets say, Laravel, which has a dependency of you package 'A', then also the package 'C' will be available within Laravel, since it is a dependency of 'A'.
I.e: If this is your composer.json file
{
"name": "foo/bar",
"require": {
"google/apiclient": "1.0.*"
}
}
This code will work
require_once __DIR__ . '/vendor/autoload.php';
$client = new Google_Client();
$youtube = new Google_Service_YouTube($client);
Note I've required the composer autoload file, which seems to be your problem. When you are using Laravel, it will add that file for you.

Composer: extra (not necessary) dependencies installed

Basic question about composer. I would like to test composer and install jquery with it.
I created a composer.json file inside a project subfolder (project_root/test).
{
"require": {
"components/jquery": "^1.11.2"
}
}
Then I opened command prompt (with path = 'project_root/test' = same folder of composer.json) and executed:
composer install
Problem: composer installs NOT ONLY jquery but also symfony and some other stuff.
It's true that I have a symfony project in another folder (totally different folder with different path) which is "under composer"... it seems that composer is "mixing" the two projects.
Any ideas?
P.s. I installed composer with the windows installer (I think it's called global install)
Looking on Packagist, it seems that the version of components/jquery you want to install requires another package (robloach/component-installer), which then requires some other things, which require more things, etc. Eventually, it looks like you end up getting to symphony.
Composer is recursive in that it installs not just the things your package requires, but anything that those things require, etc. This is why you are getting symphony.

Why do CodeIgniter projects sometimes include composer.phar package?

I'm new to Composer and in my current project I would like to install a bunch of PHP libraries like:
Doctrine
Security Library (Which i have no idea but looking for in CodeIgniter)
Bootstrap layout libraries and other when necessary
For that matter , I would like to use Composer based library management in my application,
and i get confused that if i have to include composer.phar on my project directory or not.
since i have it on my environment path and I can run Composer form command line .
How can integrate the above libraries into my codeigniter application then..
Appreciate your toughs!
The composer.phar file is an executable and it should not be committed. What it actually does is that it looks in your composer.json file and there you can declare some more dependencies (libraries for example) and their version:
{
"require": {
"doctrine/orm": "*"
}
}
The version in this case is declared with "*" so Composer will get the latest version. This is very useful if there are more people on the project, to make sure all of them have the same version of dependencies installed (so the composer.json file must be committed).
If you run "composer.phar update" on the other hand, this will get the latest version of all dependencies, no matter the version placed in composer.json and updates the lock file with the new versions.

where do I put composer.json

I have installed composer.
My project dir tree looks something like this
/home/myproject/public_html/myproject.com
I initially installed it in:
/home/myproject/public_html/myproject.com/bin/composer/
But later moved it to:
/home/myproject/usr/local/bin/composer
Questions:
Where to I create composer.json ?
In the official docs they mention that in order to install new packages I need to write a require key in the json format in that file, does this mean that I dont have to upload the package through ftp?
The docs further say that I can simply install dependencies like ths:
php composer.phar install
I dont understand the workflow of this process (im fairly new).. what exactly do I need to do to get some packages going (like Respect)
Composer has 2 basic elements for you to consider:
The composer.php file itself - this can be located anywhere on your system - usually it is convenient to have it in you search path so you can invoke it by name (no path) from the command line.
Composer.json - this file is the configuration for your project. This is usually best located at the top level of your project. Ideally this is a directory outside the scope of your web server - so that it will never be exposed or served.
Symfony2 has some great documentation and examples of composer in use.
Also be aware that some packages you reference via composer will themselves have composer files - to ensure they match your required dependancies - and they may also have their own dependancies that need to be considered.
I would install composer.json in the following
/home/myproject/composer.json
It would be out of scope of the web server and could be used to manage many assets e.g.
public_html/
libs/
config/
docs/
vendor/
Where to I create composer.json ?
You should create composer.json to your project root like /home/myproject/public_html/myproject.com/composer.json. If all files of your application live inside your myproject.com folder.
In the official docs they mention that in order to install new
packages I need to write a require key in the json format in that
file, does this mean that I dont have to upload the package through
ftp?
Yes as long as you're not in shared hosting because most of them don't allow CLI (SSH).
The docs further say that I can simply install dependencies like this
php composer.phar install
Yes you can simple type the above command and composer.json will install the latest version of your package.
Composer.json (Respect Package)
{
"require": {
"respect/validation": "dev-master"
}
}
Now run composer install will install the require package.
For further packages
{
"require": {
"respect/validation": "dev-master",
"doctrine/orm": "2.*"
}
}
Now run update composer update it will download the doctrine/orm as well.

Use composer to install bundle in custom directory

I see there is already a question but it did not answer the question
How can I install a composer package into the /src dir?
How can I install a bundle in the /src directory?
Reason I would like to do this is for development and deployment, so
I don't have to check in Symfony's base code into my subversion repo
I could use Composer to deploy
Looking over the Composer docs some more I did come across this:
http://getcomposer.org/doc/04-schema.md#config
vendor-dir: Defaults to vendor. You can install dependencies into a
different directory if you want to.
Could I set this at a Bundle level? or is this for the overall install?
https://github.com/composer/composer/blob/master/res/composer-schema.json
I know this is late, but in case anyone is searching for an answer that I painstakingly (hours and hours) found: vendor-dir
The documentation says:
By setting this var you can make composer install the dependencies into a directory other than vendor
Example:
{
"config": {
"vendor-dir": "website/password/vendor/"
}
}
From this doc and this doc
Again, hope to save anyone else a couple hours.
{
"extra": {
"installer-paths": {
"sites/example.com/modules/{$name}": ["vendor/package"]
}
}
}
Read more.
If you find composer's custom installers too complex or rigid, and you can plan what types of systems you will be deploying to, you might consider using post-install scripts.
Here's an example that creates a symlink from a package installed under vendors to the location where it might be expected:
"scripts": {
"post-install-cmd": [
"test -d vendor/foo/bar && ln -s ../vendor/foo/bar lib/bar"
]
}
This will create a symlink at lib/bar/ pointing to vendor/foo/bar/.
I have implemented this composer plugin to install packages into user (custom) defined folders you can just include it in your composer.json, follow the example and tell me if you have more questions :)
https://github.com/mnsami/composer-custom-directory-installer
composer-custom-directory-installer
A composer plugin, to install differenty types of composer packages in custom directories outside the default composer default installation path which is in the vendor folder.
This is not another composer-installer library for supporting non-composer package types i.e. application .. etc. This is only to add the flexability of installing composer packages outside the vendor folder. This package only supports composer package types,
https://getcomposer.org/doc/04-schema.md#type
The type of the package. It defaults to library.
Package types are used for custom installation logic. If you have a package that needs some special logic, you can define a custom type. This could be a symfony-bundle, a wordpress-plugin or a typo3-module. These types will all be specific to certain projects, and they will need to provide an installer capable of installing packages of that type.
How to use
Include the composer plugin into your composer.json require section::
"require":{
"php": ">=5.3",
"mnsami/composer-custom-directory-installer": "1.1.*",
"monolog/monolog": "*"
}
In the extra section define the custom directory you want to the package to be installed in::
"extra":{
"installer-paths":{
"./monolog/": ["monolog/monolog"]
}
by adding the installer-paths part, you are telling composer to install the monolog package inside the monolog folder in your root directory.
As an added new feature, we have added more flexibility in defining your download directory same like the composer/installers, in other words you can use variables like {$vendor} and {$name} in your installer-path section:
"extra": {
"installer-paths": {
"./customlibs/{$vendor}/db/{$name}": ["doctrine/orm"]
}
}
the above will manage to install the doctrine/orm package in the root folder of your project, under customlibs.
Note
Composer type: project is not supported in this installer, as packages with type project only make sense to be used with application shells like symfony/framework-standard-edition, to be required by another package.

Categories