As far as we concerned, Composer is really useful at re-implementing code in PHP application or frame work. But now I want to consider it as a better package and dependency management system for Magento extensions. The post will take you some minutes to read all but do not quit because I believe you will find many things really useful.
From the basic knowledge
We all know about PEAR, right? PEAR was built using the assumption, that PHP library components would be installed system-wide. As it turns out, this isn’t the best solution. In practice, different projects require different versions of the same libraries. If you upgrade system wide libraries, all dependent projects have to be upgraded, too. So, Composer fixes this issue. It installs required libraries separately for each project.
Moreover, it makes it very easy to manage package repositories, much easier than managing PEAR channels. Even more, it can install packages from many different sources: GIT and SVN repositories, ZIP and TAR files, and yes, even PEAR channels. The person installing the package doesn’t even need to care where the package comes from.
So where do you get available libraries?
All publicly available packages for composer are listed on packagist.org. But because plugins for applications, which have their own eco-system, should not be listed there, we created a public repository for Magento modules:packages.firegento.com.
To discover its working principles
Composer uses a configuration file, which lives in a project base directory. The file is named composer.json. This file lists configuration options, for example the minimum-stability, and also the list of packages that should be installed. Also a version, or a version range, can be specified for each package.
Here is an example composer.json:
Composer will use packagist.org to look where to get the libraries. Because Magento modules aren’t listed there, you will have to add the packages.firegento.org repository to the configuration as follows, and also specify the Magento root directory (more on that below):
Once the composer.json configuration file is created, all that needs to be done is install composer (curl –O https://getcomposer.org/installer | php) and run it:
php composer.phar install
And that’s all. The listed packages and all their dependencies will be installed in the project.
The place where composer installs the libraries is a directory called vendor.
Should the contents of the composer.json file ever be changed, run
php composer.phar update
and the new configuration will be applied.
That is also how you uninstall a package: you remove it from the require list in the composer.json and runcomposer.phar update.
Back to Magento
As you probably are aware, Magento modules, in contrast to “usual” PHP libraries, aren’t contained in a single directory within the project. Instead module classes live in the code pool subdirectories, translation files underapp/locale, and templates in the respective area, package and theme folders, and so on. For this reason, the files which composer installed under vendor, somehow need to be merged into the Magento directory hierarchy.
And this is what the magento-composer-installer project provides.
After installing a Magento module with composer, all files and directories will be symlinked into the respective targets in the Magento directory tree, very similar how modman does.
There is one little piece of information that is required so composer can do that, and that is the path to the Magento root directory. You will always need to add that to the project composer.json file, too:
In case you prefer copies to symlinks, no problem: simply set the appropriate config option under extra.magento-deploystrategy:
Maybe that is interesting for users on “old” windows systems that don’t yet support symlinks.
Before we wrap up, there is one more thing that should be talked about. As mentioned before, composer installs libraries (and Magneto modules) into a vendor directory.
So this directory needs to be integrated somehow into the project.
When placed directly in a Magento root directory we would end up with a structure like this:
- ├── .git/
- ├── composer.json
- ├── composer.lock
- ├── index.php
- ├── app/
- ├── js/
- ├── lib/
- ├── media/
- ├── skin/
- ├── var/
- └── vendor/
This works, but you need to make sure that the vendor directory, and also the compser.json and composer.lock files aren’t accessable from a web browser.
For that reason it’s better to make the parent of the Magento directory to the project root folder:
- ├── .git/
- ├── composer.json
- ├── composer.lock
- ├── htdocs/
- │ ├── index.php
- │ ├── app/
- │ ├── includes/
- │ ├── js/
- │ ├── lib/
- │ ├── media/
- │ ├── shell/
- │ ├── skin/
- │ └── var/
- └── vendor/
Each solution partner and each developer have their own preferences, but I think most agree that the second variation is cleaner.
Versioning the project
Preamble: I realize not everybody uses git, but for the sake of simplicity I’ll just refer to git here. Think svn, mercurial or whatever the vcs of your choice is instead if you prefer.
The composer.json file is always included in the git repository. For the vendor directory, it depends – it isn’t always versioned.
When composer.phar install is run, a file composer.lock is created which lists all the packages in the currently installed version. But should this file already exist when the install command is called, then composer will re-create that state in listed in that file. For that reason, it theoretically is enough to version the composer.lock file, and add the vendor folder to the .gitignore list. That is assuming that every package will always remain installable in the future.
To avoid that risk, you might prefer to version the vendor directory after all. You choose.
UPDATE: If you end up versioning the vendor directory, you might want to install packages without the .gitsubdirectories. Composer offers command line switches to control that behaviour: –prefer-dist and –prefer-source (see the reference).
An composer install –prefer-dist will install the packages without the .git subdirectories, whereas –prefer-source will clone the source repositories, which is useful if you want to do work in the packages, too. Then you can commit straight from the vendor/<package-name> directory.
If you are interested in making your own Magento modules installable with composer, please refer to the next blog post – coming shortly right here.
As mentioned before, modules can come from many different sources. All the modules on packages.firegento.comare hosted on github, or are Magento Connect 2.0 packages, which also can be installed. The latter can be recognized by the connect20/ prefix to the package name.
It also goes beyond the scope of this introductory post to describe all the possibilities the project composer.jsonoffers, for example how to configure private repositories. A little further information can be found in the magento-composer-installer README, and of course in the excellent composer documentation on http://getcomposer.org/doc/.
The only one drawback of composer for Magento (so far) is that it doesn’t handle commercial extensions very gracefully. It would be possible to add a private repository and install from there, but that’s not a real solution. But at least the community modules and other external libraries are taken care of nicely!
That is all about Composer I want to share. If you have any comments, it is my pleasure to hear from you. So let me know !
Here is the library of Magento Download for FREE (all versions)
Your Magento website needs a powerful Magento ERP for stock control.
DON'T MISS THE CHANCE!