I'm looking to develop a package in PHP, but I don't want it immediately available on GitHub or somewhere. It's easy enough to include a Packagist file in my composer.json, but how do I add a local package into my composer.json? Also, should I be building the package in /vendor/foo/bar (relative to the root composer.json), or should I put it somewhere else?
Edit: I guess my question is about how everyone else writes their packages. Does every new package get added to Packagist, and then when you want to test your changes, you commit to GitHub (or wherever), and then pull that back down via Composer? That seems really inefficient.
Instead of creating a new repository, you can tell composer to use any local path:
https://getcomposer.org/doc/05-repositories.md#path
For instance, lets say that you have your PHP projects under ~/devel/projects
You may have your main project in ~/devel/projects/main_project, and your "local package" in ~/devel/projects/local_package
Define your composer configuration for the local package. In ~/devel/projects/local_package/composer.json.
{
"name": "your_vendor_id/your_local_package",
...
}
Then, you can edit ~/devel/projects/main_project/composer.json and link to your local package via path repo:
"repositories": [
{
"type": "path",
"url": "../local_package",
"options": {
"symlink": true
}
}
],
"require": {
"your_vendor_id/your_local_package": "dev-master",
...
}
More info on this link (not written by me but has a good explanation on this subject):
https://carlosbuenosvinos.com/working-at-the-same-time-in-a-project-and-its-dependencies-composer-and-path-type-repository/
As this question has many different components/standards to be explained, I'll try to explain as much as possible here and you can PM me or just Google it for more specific questions as they come up.
To answer your first question, "How do I add a local package into my composer.json?":
If by "add local package" you mean autoload your class/package, you can do that by either using PSR-4 or PSR-0 or Classmap options in composer.
Read more
PSR [petermoulding.com] (via archive.org)
PSR-4 autoloading support in Composer [seld.be]
Battle of the Autoloaders: PSR-0 vs. PSR-4 [Sitepoint]
Why use a PSR-0 or PSR-4 autoload in composer if classmap is actually faster? [SO]
You can Google it if you need more info on PSR-0, PSR-4 and Classmap.
Example
"autoload": {
"psr-4": { "Core\\": "src/Core" } ## "standard": { "namespace" : "path/to/dir"}
}
Or (edit)
If you actually want to add a local package:
Create a composer.json for the local package, like:
{
"name": "localPackage/core",
"version": "dev-master"
}
You can also specify other properties and/or dependencies as required.
Zip the package, with the composer.json file as the root file in the archive.zip, and place it where desired.
In the other project/package where you want to include the local package, add the local package name to the required parameter, like
"localPackage/core": "dev-master"
Add the following under the repositories parameter:
"repositories" : [
{
"type": "artifact",
"url": "path/to/localPackage.zip"
}
]
Now if you have the local package on git, then there would be no need to archive the package (basically omit step 2) and you just need to replace the URL in the above example to the path/to/localPackage/.git.
(End of edit)
Now to answer the larger question: "How do I develop and include a Composer package?":
Decide the directory structure. Commonly it is as follows:
/PackageRoot
/src/PackageCore
composer.json ## this is your library’s composer.json
LICENSE
and set up your composer.json.
An example of one of mine composer.json files can be found at http://pastebin.com/tyHT01Xg.
Upload it to Github and tag the version. Use Semantic versioning (make sure you exclude/ignore the vendor directory when uploading to Github).
Register the package with Packagist (after logging in).
If you have tagged your commit as v1.0.0 (or similar), then this will show up in your Packagist dashboard for that package.
Now, if everything is done right, you should be able to use your library as a dependency in other projects by adding it to the composer.json of that project.
Here's a recap of the solutions plus my own
publish on packagist
Since you don't want to publish yet, you're in development, this is a poor option.
upload github
You may not want to publish your library source on github, not want to pay for a private repo, or be able to use a cloud external service (due to political or network policies).
zip your library
You can use the composer repository path in your example implementation to point to a local zip file as a release. You'll have to re-zip every time you make a change to the lib, even with a batch file to do it, this is icky.
upload to local git/svn repo on your machine
This is getting close, but you'll need to do a composer update each time you change your library and want to test your example implementation. This mimics productions but is cumbersome. Personally I recommend this solution, even though it's not brainless.
Autoload the library directly (sortof does what you want)
This is a hack, but you could just add:
{
"require": {
},
"autoload": {
"psr-4": {
"yourlibnamespace": "D:\\Code\\yourlib\\src\\"
}
}
}
Please note that you will need to copy+paste the 'require' section from your lib to your sample implementation. Change 'yourlibnamespace' to your library namespace and "D:\Code\yourlib\src\" to your local path to your library source.
This way any changes are immediately reflected. However you will not be using or testing your library's composer.json file at all. If you change a requirement in your library .json it will not flow through at all. So it has some big disadvantages, but does do what you want, which is to test your library implementation immediately with the least commands possible.
add your example implementation directly in your library tree (recommended)
Usually you just have src\ and tests\, but many have examples\ where you can find sample implementations. As you develop your application you can contribute to these example implementations. You can do this in a local git/svn repo, and you have the advantage of getting the lib's 'require', plus the namespace automatically. It is the best of all worlds. I recommend this method.
It seems most answers on this thread are not "in the know". I am new to Composer myself, but these answers are misleading. The question could simply be stated as: "How can I develop a composer package".
Yes, you could use a custom repository or upload an unfinished package and update it after every change. That neither is the correct solution or the answer to the question.
It doesn't help that Composer's official documentation doesn't state this upfront, but you can see the heading on the Libraries documentation page:
Every project is a package
This is very important to understand
composer.json:
The previously mentioned page goes on to state:
In order to make that package installable you need to give it a name. You do this by adding the name property in composer.json
{
"name": "acme/hello-world",
"require": {
"monolog/monolog": "1.0.*"
}
}
In this example so far, we have a required package, and now a name. Note the vendor/name format.
So now to autoloading our own files, which is documented on the Basic usage page.
{
"autoload": {
"psr-4": {"Acme\\": "src/"}
}
}
This will autoload the namespaced class files under the src/Acme directory.
On to the fun.
Install/Update
Install or update the package with the command:
composer update
or
php composer.phar update
This will download the required packages and create the autoload.php file
Our project structure should look simular to the following:
src
Acme
Foo.php
vendor
monolog
...
composer.json
Including
Now to test.
Include autoload.php
require_once 'path/to/project/vendor/autoload.php';
Assuming Foo.php looks like the following:
<?php
namespace Acme;
class Foo {
public static function bar(){
return 'baz';
}
}
?>
we can then call this from our script:
echo Acme\Foo::bar(); // baz
Please correct any misleading information I may have stated. This is what seems the be the solution to a popular question.
Maybe adding a custom repository will help you?
https://github.com/composer/composer/blob/master/doc/05-repositories.md
You can set up a local git repository with your library very easily.
Of course if you use composer to manage dependencies you should build your library someplace else and download it to vendor/ via composer coz this is the whole point i guess.
That's my flow of creating and developing a new Composer package locally:
Create a new repository for the package on GitHub (just an example)
Add it to Composer's database (packagist.org)
Add it to your main project via composer require. This is where you start wondering how can you apply hotfixes quickly
Clone it on your local machine somewhere, this is where you develop it
Now to test your local version, add a php require() statement where you load the class files in question. The autoloader won't load the one downloaded via composer but your local one.
When you're done hotfixing, delete/comment out the the require statement to revert back to using the composer version of the package.
Commit all changes, tag the commit and push to GitHub; hook fires to update Composer. Run composer update on your main project, the package gets updated to your local version.
This is still not ideal, but it gets the work done for small to medium packages.
To make developing more efficient I simply symlink the development repository into a directory that has already installed it.
For example, if /Code/project-1 requires a package that's in /Code/package-1, I:
Commit package-1 to GitHub (can even be private).
I then tell project-1 to install it using a custom repository (see other answers for the link to repository configuration).
Once it gets installed, I symlink /Code/project-1/vendor/developer/package-1 to /Code/package-1.
That way, when I make changes in /Code/package-1, it's immediately reflected in /Code/project-1.
My workflow does not completely answer the OP's question but may be helpful for others.
I like to develop a reusable package / lib in a real world project and I do not want to go through git / composer locally.
I also do not like to load the package differently locally compared to production (e.g. through a local require statement or local composer setting).
So what I do is simple: I add the package directly under the vendor directory, either directly or using a symlink.
drawbacks
When using composer update / install, your package may be overwritten. (so I tend to update or add dependencies one by one, during this time).
When not being careful, composer install on the production environment may install a different version. So keep pushing your package and version tags!!
Changing the package's dependencies and loading it in the parent project trough composer update, overwrites the package's folder
Related
I'm trying to install the Coinbase PHP API but it requires Composer:
https://github.com/coinbase/coinbase-php
I'm looking for a universal PHP solution (perhaps a function) to let me install composer packages directly onto my server, without having to use Composer.
I think the developers of Composer believe they are helping people, but actually there are thousands of beginner developers that are being locked out of learning web development by the 'Composer barrier'.
It would really help if there was a flexible solution or some approach where we could install without Composer? How can I do this?
Please don't respond with some sarcastic comment. There are people that don't want to use Composer and I don't see why we should be herded into a specific third-party software in order to do web development.
You can try https://php-download.com/ which can help you download all dependency most of the time along with vendor folder. It promises composer not required.
Tried it myself. It finds and creates all required folders and zips it for download. Works perfectly !!
The composer.json file lists the dependencies. In your example:
"require": {
"php": ">=5.5.0",
"guzzlehttp/guzzle": "^6.0",
"psr/http-message": "^1.0",
"psr/log": "^1.0"
},
You must then find the corresponding packages in the packagist site. Repeat the same process for each dependency: find additional dependencies in their corresponding composer.json files and search again.
When you finally have a complete list of the required packages, you only need to install them all one by one. For the most part, it's just a matter of dropping the files somewhere in your project directory. But you must also ensure that PHP can find the needed classes. Since you aren't using Composer's auto-loader, you need to add them to your own custom autoloader. You can figure out the information from the respective composer.json files, e.g.:
"autoload": {
"psr-4": { "Coinbase\\Wallet\\": "src/" }
},
If you don't use a class auto-loader you'll need to figure out the individual require_once statements. You'll probably need a lot of trial and error because most library authors won't care documenting that.
Also, and just in case there's confusion about this:
Composer has an official GUI installer for Windows and a copy and paste command-line installation procedure for all platforms.
Composer can be run locally and its output just uploaded elsewhere. You don't need SSH in your shared hosting.
The command needed to install a library can be copied and pasted from the package web site—even if the package maintainer didn't care to document it, packagist.org generates it by default.
Composer is not perfect and it doesn't suit all use cases but, when it comes to installing a library that relies on it, it's undoubtedly the best alternative and it's a fairly decent one.
I've checked other answers that came after mine. They mostly fall in two categories:
Install a library and write a custom download script with it
Use an online web based interface for Composer
Unless I'm missing something, none of them address the complaints expressed by the OP:
Learning curve
Use of third-party software
Possibility to develop right on the server (using SSH, I presume)
Potentially deep dependency tree
I'm using shared hosting for a website and can't execute commands there. Aside from running composer via php script request that I request via browser, I usually use this workflow:
Make sure you have php installed locally.
Make directory on desktop.
download composer.phar from https://getcomposer.org/download/ (under header *Manual Download) and place it in the directory.
make a file composer.json paste in it the following contents
{
"require": {
"coinbase/coinbase": "~2.0"
}
}
Browse to the directory with the shell of your choice(bash, git-bash, cmd, windows bash)
type php composer.phar update
Upload the vendor directory to your webserver via ftp or whatever mechanic you use.
include in your php project where you load your libraries(modify path to where you uploaded the vendor dir so it will include that autoload file)
require_once('vendor/autoload.php');
This way you get the benefit of dependency management and you don't have to include manually all the gazillion of files and download all the dependencies manually, and updating them is just as easy as typing php composer.phar update and then replacing the vendor dir on your server with the new one.
An alternative solution that worked for me (since php-download was down) can be done by making your own little local composer downloader.
Download and install XAMPP locally: https://www.apachefriends.org/index.html
Download and install composer locally: https://getcomposer.org/download/
Open commandprompt, navigate to say c:\temp and and simply type the composer dependancy, for example: composer require league/oauth2-client
Copy the files from your c:\temp folder to your web host using an FTP program
Add this to the top of your php: require("vendor/autoload.php");
This is not the ultimate solution but for me it was a big help for most of the cases:
https://github.com/Wilkins/composer-file-loader
Allow you to load composer.json file just as composer would do it.
This allow you to load composer.json file without composer (so
theorically PHP 5.2 is enough)
I know the question is old but I hope it will help someone.
I had to do this for an FTP server I didn't have SSH access to. The site listed in here worked, then I realized you can just do a composer install on your own server (using your target's PHP version), then copy all the files over.
Analizing the problem
The problem in installing the dependencies without Composer is the autoloading system.
Composer use a homemade autoloader based on an array map, this is a de-facto standard.
But this autoloading system, "fortunally" in this case, is not PSR-4 compliant.
PSR-4 is the de-iure standard for autoload a class in PHP, so you can't escape from autoloading. You must use one of them.
Solution Proposal
In this case, this brilliant PSR-4 autoloader is capable to be manually configured to autoload a VendorClass in a VendorNamespace anywhere in your code, as long as you require the custom autoload.php file early in your source code.
Real life example
Let's look at this example:
I have a legacy project who can't and won't use Composer never and never even if God allow this with a miracle. This project can be speed up in development with this fantastic package for command line scripts.
This is my project directory structure:
- src
- tests
- vendor (not the Composer's one)
This package has this directory structure:
- examples
- src
- Commando
- tests
The only thing I need is the src folder. Placing this folder in my vendor folder would be fine. So my custom autoloader would be like this:
// Constants
$base_path = "path\to\my\project";
$autoloader_class = '\vendor\MarcoConsiglio-Wichee\PSR-4-Autoloading\Psr4AutoloaderClass.php';
define("BASE_PATH", str_replace("\\", DIRECTORY_SEPARATOR, $base_path));
// Autoloader
require_once BASE_PATH.'\vendor\MarcoConsiglio-Wichee\PSR-4-Autoloading\Psr4AutoloaderClass.php';
// Init the autoloader.
$package = [
"nategood\commando" => [
"namespace" => "Commando",
"path" => str_replace("\\", DIRECTORY_SEPARATOR, '\vendor\nategood\commando\src\Commando')
],
"kevinlebrun\colors.php" => [
"namespace" => "Colors",
"path" => str_replace("\\", DIRECTORY_SEPARATOR, '\vendor\kevinlebrun\colors.php\src\Colors')
]
];
// Register namespaces.
$loader = new \PSR4\Psr4AutoloaderClass;
$loader->register();
// Namespace // Path to source
$loader->addNamespace($package["nategood\commando"]["namespace"], BASE_PATH.$package["nategood\commando"]["path"]);
$loader->addNamespace($package["nategood\commando"]["namespace"], BASE_PATH.$package["nategood\commando"]["path"]."\Util");
$loader->addNamespace($package["kevinlebrun\colors.php"]["namespace"], BASE_PATH.$package["kevinlebrun\colors.php"]["path"]);
Now I can use the command package anywhere in my project!
Pros & Cons
This solution allow you to:
Easely and manually build your own custom autoloader (you only need to specify the VendorNamespace and the folder(s) where search for VendorClasses in the VendorNamespace.
Freely organize your composer dependency anywhere in your project folder (and why not, outside it)
Import a composer package as is in your project (either downloading locally with Composer or cloning the package repository) or a relevant part of it (i.e removing composer.json file or files that require the composer autoloader).
Cons:
Manually build your custom autoloader means to work on every required dependency of your project (i hope not a lot).
Mistakes in package source paths can be tedious and frustrating.
Works only with PSR-4 compliant file names (i.e. can't use a A.class.php file name)
I'm trying to install the Coinbase PHP API but it requires Composer:
https://github.com/coinbase/coinbase-php
I'm looking for a universal PHP solution (perhaps a function) to let me install composer packages directly onto my server, without having to use Composer.
I think the developers of Composer believe they are helping people, but actually there are thousands of beginner developers that are being locked out of learning web development by the 'Composer barrier'.
It would really help if there was a flexible solution or some approach where we could install without Composer? How can I do this?
Please don't respond with some sarcastic comment. There are people that don't want to use Composer and I don't see why we should be herded into a specific third-party software in order to do web development.
You can try https://php-download.com/ which can help you download all dependency most of the time along with vendor folder. It promises composer not required.
Tried it myself. It finds and creates all required folders and zips it for download. Works perfectly !!
The composer.json file lists the dependencies. In your example:
"require": {
"php": ">=5.5.0",
"guzzlehttp/guzzle": "^6.0",
"psr/http-message": "^1.0",
"psr/log": "^1.0"
},
You must then find the corresponding packages in the packagist site. Repeat the same process for each dependency: find additional dependencies in their corresponding composer.json files and search again.
When you finally have a complete list of the required packages, you only need to install them all one by one. For the most part, it's just a matter of dropping the files somewhere in your project directory. But you must also ensure that PHP can find the needed classes. Since you aren't using Composer's auto-loader, you need to add them to your own custom autoloader. You can figure out the information from the respective composer.json files, e.g.:
"autoload": {
"psr-4": { "Coinbase\\Wallet\\": "src/" }
},
If you don't use a class auto-loader you'll need to figure out the individual require_once statements. You'll probably need a lot of trial and error because most library authors won't care documenting that.
Also, and just in case there's confusion about this:
Composer has an official GUI installer for Windows and a copy and paste command-line installation procedure for all platforms.
Composer can be run locally and its output just uploaded elsewhere. You don't need SSH in your shared hosting.
The command needed to install a library can be copied and pasted from the package web site—even if the package maintainer didn't care to document it, packagist.org generates it by default.
Composer is not perfect and it doesn't suit all use cases but, when it comes to installing a library that relies on it, it's undoubtedly the best alternative and it's a fairly decent one.
I've checked other answers that came after mine. They mostly fall in two categories:
Install a library and write a custom download script with it
Use an online web based interface for Composer
Unless I'm missing something, none of them address the complaints expressed by the OP:
Learning curve
Use of third-party software
Possibility to develop right on the server (using SSH, I presume)
Potentially deep dependency tree
I'm using shared hosting for a website and can't execute commands there. Aside from running composer via php script request that I request via browser, I usually use this workflow:
Make sure you have php installed locally.
Make directory on desktop.
download composer.phar from https://getcomposer.org/download/ (under header *Manual Download) and place it in the directory.
make a file composer.json paste in it the following contents
{
"require": {
"coinbase/coinbase": "~2.0"
}
}
Browse to the directory with the shell of your choice(bash, git-bash, cmd, windows bash)
type php composer.phar update
Upload the vendor directory to your webserver via ftp or whatever mechanic you use.
include in your php project where you load your libraries(modify path to where you uploaded the vendor dir so it will include that autoload file)
require_once('vendor/autoload.php');
This way you get the benefit of dependency management and you don't have to include manually all the gazillion of files and download all the dependencies manually, and updating them is just as easy as typing php composer.phar update and then replacing the vendor dir on your server with the new one.
An alternative solution that worked for me (since php-download was down) can be done by making your own little local composer downloader.
Download and install XAMPP locally: https://www.apachefriends.org/index.html
Download and install composer locally: https://getcomposer.org/download/
Open commandprompt, navigate to say c:\temp and and simply type the composer dependancy, for example: composer require league/oauth2-client
Copy the files from your c:\temp folder to your web host using an FTP program
Add this to the top of your php: require("vendor/autoload.php");
This is not the ultimate solution but for me it was a big help for most of the cases:
https://github.com/Wilkins/composer-file-loader
Allow you to load composer.json file just as composer would do it.
This allow you to load composer.json file without composer (so
theorically PHP 5.2 is enough)
I know the question is old but I hope it will help someone.
I had to do this for an FTP server I didn't have SSH access to. The site listed in here worked, then I realized you can just do a composer install on your own server (using your target's PHP version), then copy all the files over.
Analizing the problem
The problem in installing the dependencies without Composer is the autoloading system.
Composer use a homemade autoloader based on an array map, this is a de-facto standard.
But this autoloading system, "fortunally" in this case, is not PSR-4 compliant.
PSR-4 is the de-iure standard for autoload a class in PHP, so you can't escape from autoloading. You must use one of them.
Solution Proposal
In this case, this brilliant PSR-4 autoloader is capable to be manually configured to autoload a VendorClass in a VendorNamespace anywhere in your code, as long as you require the custom autoload.php file early in your source code.
Real life example
Let's look at this example:
I have a legacy project who can't and won't use Composer never and never even if God allow this with a miracle. This project can be speed up in development with this fantastic package for command line scripts.
This is my project directory structure:
- src
- tests
- vendor (not the Composer's one)
This package has this directory structure:
- examples
- src
- Commando
- tests
The only thing I need is the src folder. Placing this folder in my vendor folder would be fine. So my custom autoloader would be like this:
// Constants
$base_path = "path\to\my\project";
$autoloader_class = '\vendor\MarcoConsiglio-Wichee\PSR-4-Autoloading\Psr4AutoloaderClass.php';
define("BASE_PATH", str_replace("\\", DIRECTORY_SEPARATOR, $base_path));
// Autoloader
require_once BASE_PATH.'\vendor\MarcoConsiglio-Wichee\PSR-4-Autoloading\Psr4AutoloaderClass.php';
// Init the autoloader.
$package = [
"nategood\commando" => [
"namespace" => "Commando",
"path" => str_replace("\\", DIRECTORY_SEPARATOR, '\vendor\nategood\commando\src\Commando')
],
"kevinlebrun\colors.php" => [
"namespace" => "Colors",
"path" => str_replace("\\", DIRECTORY_SEPARATOR, '\vendor\kevinlebrun\colors.php\src\Colors')
]
];
// Register namespaces.
$loader = new \PSR4\Psr4AutoloaderClass;
$loader->register();
// Namespace // Path to source
$loader->addNamespace($package["nategood\commando"]["namespace"], BASE_PATH.$package["nategood\commando"]["path"]);
$loader->addNamespace($package["nategood\commando"]["namespace"], BASE_PATH.$package["nategood\commando"]["path"]."\Util");
$loader->addNamespace($package["kevinlebrun\colors.php"]["namespace"], BASE_PATH.$package["kevinlebrun\colors.php"]["path"]);
Now I can use the command package anywhere in my project!
Pros & Cons
This solution allow you to:
Easely and manually build your own custom autoloader (you only need to specify the VendorNamespace and the folder(s) where search for VendorClasses in the VendorNamespace.
Freely organize your composer dependency anywhere in your project folder (and why not, outside it)
Import a composer package as is in your project (either downloading locally with Composer or cloning the package repository) or a relevant part of it (i.e removing composer.json file or files that require the composer autoloader).
Cons:
Manually build your custom autoloader means to work on every required dependency of your project (i hope not a lot).
Mistakes in package source paths can be tedious and frustrating.
Works only with PSR-4 compliant file names (i.e. can't use a A.class.php file name)
I have a main php project that needs a php component developed by me, that i intend to reuse in other projects, the component is in the main project vendor directory.
However pushing to Github the component, go to the main project, running composer update is time consuming.
In order to speed up the development of the component, is there a way to include the local component project into the main project?
This is how I do local composer package development.
Create a vendor-repo folder next to the vendor folder.
Create a directory for the vendor and project name for example vendor-repo/vendorname/packagename
Create a git repo inside the packagename folder and build your composer package complete with composer.json etc.
Add your local repository to the main composer.json (the one that requires your package). You can also disable the packagist repo by adding the "packagist": false as per the example below. This will speed things up and is a good idea if you aren't using any packages from packagist.
"repositories": [
{
"type": "path",
"url": "vendor-repo/vendorname/packagename"
},
{
"packagist": false
}
]
Then when you run composer update it will get your package from your local repo rather than needing to get it from GitHub.
You can add the library directly inside your vendor folder, register the sources using the psr-0 or psr-4 autoload, dump the autoload classes and create a git repository inside the folder.
So you can use it as a library, and at the same time, you don't need to pull every update you do to test the library inside your project.
I don't know if it's a good approach, but symlinks didn't work for me and i still need to register the classes in the autoload.
I would like my CakePHP project to use best practices. Currently we have our PHP dependencies checked into our project's repo, and i don't like that.
I want the project to leverage Composer, but i don't understand the proper strategy.
First, there is the official CakePHP repo:
composer.json is in the project root.
There are /vendors/ and /plugins/ and they are under .gitignore.
/app/Vendor/ and /app/Plugin/ are not ignored.
Then, there's an app-template boilerplate from FriendsOfCake:
composer.json is in the project root.
There are no /vendors/ or /plugins/.
/app/Vendor/ and /app/Plugin/ are under .gitignore.
Lastly, there's cakephp-composer, an active project. It implies that:
composer.json is in /app/.
The plugin itself is supposed to be installed by hand into /app/Plugin/.
Readme does not explain .gitignore strategy, but plugin author says that /app/Vendor/ and /app/Plugin/ should be ignored.
cakephp-composer is the weirdest thing. How am i supposed to fetch CakePHP and cakephp-composer after cloning my project?
I want to achieve the following:
My project repo contains only source code of the project itself. Any code that is versioned somewhere else, e. g. CakePHP framework and CakePHP plugins, should not appear in my repo.
After cloning my project's repo to a new location, i want to fetch all PHP dependencies, including CakePHP and its plugins, with a single Composer command. No manual downloading/cloning. The project should start working right after Composer finishes its job.
I really like the app-template boilerplate from FriendsOfCake. It looks simple and reasonable to me. So i wish my project structure were as close to app-template as possible.
I don't understand and request explanations for the following things:
Where is the folder for Composer to fetch dependencies into configured? Composer docs mention "PSR-4" and i (being a frontend dev coming from the Ruby world) don't have a slightest idea what that is.
What folders should be put under .gitignore?
Do i really need cakephp-composer? I hope that i don't!
How do i configure composer.json to fetch plugins with Composer, especially if i don't use cakephp-composer? It might be as simple as just mentioning package names under require, but how do i tell Composer whether plugins should go under app/Vendor/ and app/Plugin/? Oh, and where should they go?
How do i properly include CakePHP and CakePHP plugins fetched by Composer into my project?
For an example CakePHP plugin to be fetched by Composer, take haml. It's what i need for my frontend work and it has its own Composer dependency.
OK, there's several questions there... I'll try to answer a few.
First and foremost, you should be clear on wether you want to use CakePHP 2.X, or CakePHP 3.0. I assume since you're talking about an existing project, you mean Cake 2.X - which wasn't built with composer in mind. Cake 3.0 was built with composer in mind, so if upgrading to that is an option, I assume it'll be nicer (I haven't used 3.0 yet myself)
Here's a simplified example composer.json file from one of my projects:
{
"name": "my-project",
"require": {
"cakedc/migrations": "2.2.2",
"cakephp/debug_kit": "2.2.1",
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"config": {
"vendor-dir": "app/Vendor/"
},
"extra": {
"installer-paths": {
"app/Plugin/Migrations": ["cakedc/migrations"],
"app/Plugin/DebugKit": ["cakephp/debug_kit"],
}
}
}
see the line "vendor-dir": "app/Vendor/" - that's where I've configured composer to put it's packages, by default, in my app/Vendor/ folder.
What goes in .gitignore... we'll come back to that.
No, you don't need this.
See the line "installer-paths": {? That's where I've configured composer to put specific CakePHP plugins in Cake's plugins dir, as opposed to the default app/Vendor/ which I mentioned in 1.
For CakePHP Plugins - see 4. For CakePHP itself, I haven't personally done it. I did try at one point and found the setup to be not playing nicely with one of my plugins, so I gave up on it. However, you should be able to use the same principals as above.
Now, coming back to 2. what should be in your .gitignore? Anything that has contents completely maintained by composer - in my case, that's app/Vendor/, and app/Plugin/. That assumes that ALL the contents of those folders is maintained by composer. If you had eg. one plugin that you'd added manually, then you couldn't ignore the whole folder - you'd have to ignore only the specific plugins installed with composer.
PS - I personally delete the root vendor/ and plugins/ folders - I don't use them at all.
Background
I'm developing a series of websites which share a common engine. Something very similar to StackExchange's network of websites. Every webiste is a separate Symfony2 installation on a different Git repository, with a dependency to the engine, which is also placed on a separate repository.
"requires": {
...
"my-platform/core": "dev-master"
}
I'm still in the early stage of development, so I'd like not have to use composer update everytime I change something in the core repository. It seems that Composer has a right tool to solve this problem but it doesn't want to work properly.
My directory structure:
Workspace
MyPlatformCore
src
MyPlatform
Core
SomeClass.php
composer.json
MyWebsiteAAA
app
src
vendor
web
composer.json
MyWebsiteBBB
app
src
vendor
web
composer.json
Autoload section from composer.json from every MyWebsiteXXX repository:
"autoload": {
"psr-0": {
"MyPlatform": "../MyPlatformCore/src"
}
},
Problem
If i run php composer.phar dumpautoload --optimize from MyWebsiteXXX it generates files of autoloader with wrong paths. File vendor/composer/autoload_classmap.php contains:
'MyPlatform\\Core\\...' => $vendorDir . '/myplatform/core/src/MyPlatform/Core/...php',
while it should contain:
'MyPlatform\\Core\\...' => $vendorDir . '/../MyPlatformCore/src/MyPlatform/Core/...php',
P.S. Workspace\MyPlatformCore is in fact a symlink, but it should matter, isn't it?
Composer does not fit your current phase of work.
Having a working PSR-0 autoloader for your core classes will make them available to your other code. Adding this autoloader to the Composer autoloader should work, but I think it is better to integrate your core "code in progress" via symlink instead of constantly composer-updating it.
The real benefit would be with an existing core codebase in several tagged versions, and your multiple websites using defined versions that differ from each other. You would only work on the core if there are features to be added or bugs fixed. The daily work would go into any of the websites, which might include updating this websites core files when it is time to do so.