Author: Manuel Lemos
Posted on: 2014-01-07
Package: PHP Composer Asset Manager
This Asset Manager package is a plugin that extends Composer to install any package files outside the vendor directory.
Additionally, it can also read the user names and passwords from a configuration file, so you do not have to enter them every time Composer retrieves packages from repositories that may require authentication, like PHP Classes and JS Classes.
Read this article now to learn how to take advantage of these features of this Composer plugin.
Contents
Making Composer Better with Special Plugins
Installing Asset Files Outside the Vendor Directory
Using the Composer Asset Manager Plugin
Implementing New Types of Installation Actions
Automatic Login for Repositories that Require a Password
Conclusion
Making Composer Better with Special Plugins
Composer is an excellent tool for installing packages needed by a PHP project. However, it is not perfect. There will always be needs that some projects have, which may not be addressed by the current Composer version.
Fortunately, Composer developers had the great idea to make it extensible with third party plugins. This way, Composer can address the needs of a much greater range of PHP projects.
Composer plugins are basically like regular packages, but they implement the Composer plugin API. This API allows providing new features by altering the package installation process in useful ways.
Installing Asset Files Outside the Vendor Directory
One need that currently Composer does not address is the installation of the so called asset files.
Assets are files that Web applications need, for instance to run on the browser side. For instance, Web applications need to serve JavaScript libraries, CSS files, images, etc..
Currently, Composer installs all package files inside the vendor directory. However, asset files need to be installed below the current site Web document root, so they can be served to the user browser. The Web document root is usually not inside the vendor directory.
If you need to install packages with JavaScript files, for instance from JSClasses Composer repository, an alternative solution needs to be used to make the JavaScript files from those packages be installed in the right directories under the Web document root.
This is where this PHP Composer Asset Manager package comes into action. One of the main needs that it addresses is the installation of asset files in the right Web document root directory or sub-directory.
Using the Composer Asset Manager Plugin
The first thing you need to do to use this Composer Asset Manager Plugin package is to add it to your project composer.json file.
As you may see below, you need to added the packages phpclasses/assets in the require section of your project. That is a dummy package that triggers the loading of this Composer Asset Manager plugin package.
For instance, the actions below tell the plugin to install all JavaScript files in the directory web/js . The plugin will create any sub-directories if they do not exist.
{ "name": "your-project-name-here", "require": { "phpclasses/assets": "*", ... list other required packages here ... "jsclasses/fast-content-loader": "*" }, "repositories": [ { "type": "composer", "url": "http://www.phpclasses.org/" }, ... other repositories definition goes here ... { "type": "composer", "url": "http://www.jsclasses.org/" } ] "extra": { "assets": { ... your assets installation definitions go here ... "actions": [ { "js-target": "web/js" } ], "packages": { "jsclasses/fast-content-loader": { } } } } }
As you may see above, the definitions of where you want your assets go should be included in the project extra section. It must contain an entry named assets that defines whatever installation actions you need to be performed.
The assets section needs to specify which packages of all you are using in your project have the asset files you want to be installed. In the example it just installs assets from the package jsclasses/fast-content-loader.
Each package may have specific installation actions associated. Those actions need to be defined in a section named actions inside the package definitions. In the example that section is empty for the package jsclasses/fast-content-loader. This means there are no package specific installation actions to be performed.
However, you can define actions for all packages in the assets section named actions. That is a section may list one or more installation actions to be executed.
All actions must have a type entry defined explicit or implicitly. It defines the name of the action. Currently only the action copy is supported. Other actions may be supported in the future.
The copy action tells the plugin to copy asset files in a given directory defined by the target entry. The pattern entry defines a regular expression that matches the names of the files to be copied.
"extra": { "assets": { ... your assets installation definitions go here ... "actions": [ { "type": "copy", "target": "web/js", "pattern": "\\.js$" } ], "packages": { "jsclasses/fast-content-loader": { } } } }
To simplify you can define that action with a simple entry named js-target. You may as well use a css-target entry for copying CSS files or image-target entry for copying JPEG, PNG and GIF image files.
"actions": [ { "js-target": "web/js" } ]
Implementing New Types of Installation Actions
As mentioned above, in the future it will be implemented other types of actions for installing asset files, like copying and minifying JavaScript or CSS files, optimizing image files, or creating sprite images from a set of image files.
Meanwhile you can implement your own custom installation actions by creating a new plugin that extends this one. Just create a new package with a class that extends the class mlemos\Composer\AssetInstaller and override the function installAction.
public function installAction(PackageInterface $package, $action) { // return true if the parent class implements this action if(parent::installAction($package, $action)) return true; switch($action['type']) { case 'some-action-namespace/some-action-name': // Your action code goes here // Return true to tell that your plugin implemented this action return true; } // Return fall to tell that your plugin does not implement this action return false; }
Make sure the name of the installation actions you implement have an unique prefix, like some-action-namespace/ in this example. This is meant to avoid action name collisions in case you implement actions that have the same name as future actions implemented by this plugin.
Automatic Login for Repositories that Require a Password
Another need that currently Composer does not address well is automatic login on repositories that require authentication. Currently Composer requires that you manually enter a user name and password every time it accesses those repositories. That is a tedious task.
In the past it was necessary to create a patched version of Composer to read repository user names and passwords from a separate configuration file. However, that is not an ideal solution because not everybody can use a patched version of Composer.
Fortunately this plugin also provides a solution for that problem. It can read a configuration file and set the necessary user names and passwords for repositories that require authentication. This way the user is no longer prompted for the user name and password in the shell (unless the user name and password are incorrect).
Currently the configuration file needs to be located in the project directory with the name auth.json. For security reasons you may want to remove that file after you install your project in a production server, to minimize security damages in case your server is compromised.
Here is a sample authentication configuration file:
{ "config": { "basic-auth": { "www.jsclasses.org": { "username": "your-user-name", "password": "your-JS-Classes-composer-repository-token-password" }, "www.phpclasses.org": { "username": "your-user-name", "password": "your-PHP-Classes-composer-repository-token-password" } } } }
It is possible that this feature of automatic authentication of this plugin is no longer needed in the future because there is a patch submitted as pull request by Stephan Hochdörfer to implement a similar feature built-in Composer. Until this patch is merged into Composer, this plugin feature will continue to be useful.
Conclusion
As you may have learned from this article, it is possible to extend Composer to make it even more useful than it is today. Many thanks to Composer authors Jordi Boggiano, Nils Adermann and many others that contributed to develop Composer and make it extensible with third party plugins.
I would like to thank in particular to Stephan Hochdörfer of bitExpert for being so helpful with his knowledge, which helped making this plugin possible.
This plugin is Open Source and is available for download and installation without requiring you to be registered in the PHP Classes site. Feel free to use it and copy it to your own environment if necessary. If you redistribute it, it would be appreciated if you link to this article, so other users may learn more how to use the plugin.
Other than that, please post a comment to this article now if you have comments, questions or suggestions you would like to make about the plugin.
You need to be a registered user or login to post a comment
Login Immediately with your account on:
Comments:
7. Extending Installation Action - simhachalam (2016-10-06 15:07)
Extending Installation Action... - 1 reply
Read the whole comment and replies
6. free online minifier - wenbuyi (2015-12-07 08:01)
comment... - 0 replies
Read the whole comment and replies
5. composer password - evident (2015-11-13 11:14)
composer password... - 1 reply
Read the whole comment and replies
4. Need some help creating my custom installer - Frog warrior (2014-08-27 17:45)
This is the first time I've created a plugin... - 0 replies
Read the whole comment and replies
3. Excellent post - Part 2 - Frog warrior (2014-08-27 16:32)
One minor issue though... - 0 replies
Read the whole comment and replies
2. Excellent post - Frog warrior (2014-08-27 12:13)
I learned a great deal from that... - 0 replies
Read the whole comment and replies
1. How to contribute? - Donald Tyler (2014-05-01 17:45)
How to contribute?... - 1 reply
Read the whole comment and replies