Autoloading classes from my private repository included in Composer - php

I've added my own repository to a Composer, it download properly into my another project.
Unfortunately Composer doesn't take my repository code under consideration while updating autoloading.
autoload_namespaces.php has many namespaces generated but any of them is my repository code.
I could add namespaces in my "autoloading" section in composer.json or I could also add it in PHP using Autoloader9287463497853476 object but those solutions (ideologically equal) doesn't interest me.
How can I force my Composer to generate autoloading for my repository code also?

If you add your package using the repository section of composer.json, i would sugest you to include there the code for autoload, as i used here:
"repositories": [
{
{
"type": "package",
"package": {
"name": "brand/name",
"type": "library",
"version": "1.0.0",
"dist": {
"url": "file:///path-to-file.zip",
"type": "zip",
"reference": "XXXX"
},
"autoload": {"psr-0": { "Name\\Space\\": "dest-folder" }
},
}
}
I hope it helps.

Related

How do I get my composer package autoloaded properly?

I have created a package to separate out business logic into easier to distribute modules. The composer file looks like this:
{
"name": "aggiq/johnny-cash",
"description": "A collection of controllers, models, migrations, and tests for a phonebanking backend.",
"license": "MIT",
"authors": [ ... ],
"require": {
"illuminate/database": ">=5.5"
},
"require-dev": {
"fzaninotto/faker": "~1.4"
},
"autoload": {
"psr-4": {
"Johnny\\Phonebanking\\": "src/"
}
}
}
And our source files are indeed in src/:
src/Controllers/PhonebankController.php
src/Models/Phonebank.php
...
I saved and pushed this to our gitlab repo, and then included it as a dependency in a test project:
{
...,
"repositories": [{
"type": "package",
"package": {
"name": "aggiq/johnny-cash",
"version": "0.1",
"type": "package",
"source": {
"url": "gitlab url",
"type": "git",
"reference": "dev"
}
}
}],
"require": {
"aggiq/johnny-cash": "*",
},
...
}
And when I do composer update, it successfully grabs the project and downloads it into the vendor folder:
vendor/aggiq/johnny-cash/Controllers/PhonebankController.php
...
However, when I look in the test project's autoload_psr4.php, it's not there. Is there a step I missed?
Edit: updates the directories to have capital letters to match the namespaces, and here is the generated PSR4 php file:
<?php
// autoload_psr4.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);
You have registered autoloading at your package's composer.json correctly:
"autoload": {
"psr-4": {
"Johnny\\Phonebanking\\": "src/"
}
}
This means, any class in Johnny\Phonebanking namespace will be in src directory. E.g.:
Johnny\Phonebanking\SomeClass => src/SomeClass.php
Johnny\Phonebanking\SomeNamespace\AnotherClass => src/SomeNamespace\AnotherClass.php
As you can see, it has to respect CapitalLetters.
Saying that, you should correct first letters of your directories, from:
src/controllers/PhonebankController.php
src/models/Phonebank.php
to
src/Controllers/PhonebankController.php
src/Models/Phonebank.php
I have solved it. We needed to do two things.
The repository type specified in the parent pacakge should be vcs not package since we are loading from a git server:
"repositories": [{
"type": "vcs",
"url": "git#xxx.git"
}]
The package type in the child package should be library:
"type": "library"
Once those two changes were made, composer update installed not only the child package but also its dependencies, proving it is being recognized by composer.

How to autoload a repository in composer which does not follow PSR-0 or PSR-4?

So, I'm trying to use jcleblanc/reddit-php-sdk, but it follows no standards whatsoever and does not have a repository available, so I've had to manually define it myself in my composer.json file:
"repositories" : [{
"type": "package",
"package": {
"name": "jcleblanc/reddit-php-sdk",
"version": "dev-master",
"source": {
"url": "https://github.com/jcleblanc/reddit-php-sdk",
"type": "git",
"reference": "origin/master"
},
"autoload": {
"classmap": ["reddit-php-sdk/", "/", "reddit.php", "config.php"]
}
}
}],
Directory structure in vendor/ here:
However, when I then run composer dump-autoload, the classes in this project are not autoloaded, and don't appear in any of the autoload_*.php composer files. This means I of course get a "Class 'reddit' not found" error whenever I try and use it.
Solutions?
You can use Composer's file autoloading.
{
"autoload": {
"files": ["src/MyLibrary/functions.php"]
}
}
However, that's more geared towards helper function files and I've not tried it with a Class file (although there's no reason it shouldn't work).
Ended up forking the project myself, but it turns out the original project is broken anyway.

GitHub repository autoloading with Composer issue

I got PHP Fatal error: Class 'sendwithus\sendwithus_php\lib\API' not found
composer.json:
{
"repositories": {
"sendwithus_php": {
"type": "package",
"package": {
"name": "sendwithus/sendwithus_php",
"version": "1.0.3",
"source": {
"url": "https://github.com/sendwithus/sendwithus_php",
"type": "git",
"reference": "0dfed56"
}
}
}
},
"require": {
"sendwithus/sendwithus_php": ">=1.0.3"
}, "autoload": {
"psr-0": {
"Foo\\": "src/",
"sendwithus\\": "vendor/sendwithus/sendwithus_php/lib"
}
}, "minimum-stability" : "dev"
}
test.php:
use sendwithus\sendwithus_php\lib\API;
require_once 'vendor/autoload.php';
$api = new API('KEY');
What am I doing wrong?
There is a bunch of stuff going wrong in your case. I'll try to correct it as well as I can.
First I took a look at the library you are requiring. It is public on Github, and it has a composer.json file that has errors.
{
"name": "sendwithus/api",
"version": "1.0.3",
"require": {},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/sendwithus/sendwithus_php"
}
]
}
These infos are slightly wrong. Only the name is correctly formatted.
There shouldn't be a version. Versions are detected by tagging the code in git.
If nothing is required, that key can be omitted.
The current repository URL shouldn't be included in it's own repository.
Mentioning a license would be nice - currently everybody using this library should be scared about violating copyright.
The important, but missing info: How is autoloading configured?
Investigating the contents of that repository quickly reveals that it does not conform to PSR-0, so the only viable alternativ is classmap autoloading - which is sufficient enough because there are only two files in the lib folder.
A correct autoloading definition would be:
"autoload": {
"classmap": ["lib"]
}
Details on how to construct this are in http://getcomposer.org/doc/04-schema.md#classmap Effectively, the value for the classmap key is a list of directories relative to the repository root directory that should be indexed.
The test folder need not be mentioned here. Using PHPUnit, that folder would be scanned for any file containing test classes. The test bootstrap should include the vendor/autoload.php file generated by Composer.
I don't know if the OP is responsible for this repository or can change it. This info above should be implemented in the repository itself, but it is also helpful if it cannot, because it can also go into a "package" definition.
So now we are going to look at the mentioned composer.json of the OP:
{
"repositories": {
"sendwithus_php": {
"type": "package",
"package": {
"name": "sendwithus/sendwithus_php",
"version": "1.0.3",
"source": {
"url": "https://github.com/sendwithus/sendwithus_php",
"type": "git",
"reference": "0dfed56"
}
}
}
},
"require": {
"sendwithus/sendwithus_php": ">=1.0.3"
}, "autoload": {
"psr-0": {
"Foo\\": "src/",
"sendwithus\\": "vendor/sendwithus/sendwithus_php/lib"
}
},
"minimum-stability" : "dev"
}
The "repositories" key can contain objects that are of type "package" that contain all the necessary info of a project that fails to do so, or fails to do correctly. As I mentioned, the autoloading is broken in the original definition, so it must be fixed here:
"sendwithus_php": {
"type": "package",
"package": {
"name": "sendwithus/api",
"version": "1.0.3",
"source": {
"url": "https://github.com/sendwithus/sendwithus_php",
"type": "git",
"reference": "0dfed56"
},
"autoload": {
"classmap": ["lib"]
}
}
}
This would correctly reference that repository and enable autoloading. Note that the name has changed here to the original - it would probably trigger trouble if this library is known under two different names (one defined here, and the other in the original repository), but using the same namespace and class names.
Now that the repository info is fixed, all other things work as usual in composer.json.
"require": {
"sendwithus/api": "1.0.3"
},
"autoload": {
"psr-0": {
"Foo\\": "src/"
}
},
"minimum-stability" : "dev"
Note that the autoloading defined here is for THIS library or application only. Do not include the autoloading of the dependencies here!
And then we take care of your code:
use sendwithus\sendwithus_php\lib\API;
require_once 'vendor/autoload.php';
$api = new API('KEY');
The namespace is wrong. Don't use the name from Composer. Use the name from the code you are importing. This is correct:
require_once __DIR__ . "../vendor/autoload.php";
use sendwithus\API;
$api = new API("apikey");
Note that you cannot change the namespace of the library with a rename in Composer. Composer only downloads the PHP source files for you, it does not change the code inside the files.
My final composer.json file is this:
{
"repositories": {
"sendwithus_php": {
"type": "package",
"package": {
"name": "sendwithus/api",
"version": "1.0.3",
"source": {
"url": "https://github.com/sendwithus/sendwithus_php",
"type": "git",
"reference": "0dfed56"
},
"autoload": {
"classmap": ["lib"]
}
}
}
},
"require": {
"sendwithus/api": "1.0.3",
},
"autoload": {
"psr-0": {
"Foo\\": "src/"
}
},
"minimum-stability": "dev"
}
If you have a standard directory structure (as in vendor/sendwithus/sendwithus_php/lib) You will need to modify the path to be relative to the composer.json of that package:
"sendwithus\\": "vendor/sendwithus/sendwithus_php/lib"
Becomes:
"sendwithus\\": "lib/"
Take a look at vendor/composer/autoload_namespaces.php Which should list the path that is being used. Notice how composer will prepend the $vendorDir for you so your namespace should not need to reference it
An example from my project:
'Core\\' => array($vendorDir . '/alex-patterson-webdev/core/src'),

How to use rackspace php-opencloud with Laravel 4

I'm trying to use the php-opencloud library with Laravel 4 (it's my first time with it, I'm a bit intimidated...)
I have added this to my composer.json, tried a composer update, which downloaded the lib correctly, but what's next? How can I autoload it?
"repositories": {
"php-opencloud": {
"type": "package",
"package": {
"name": "rackspace/php-opencloud",
"version": "1.4.1",
"source": {
"url": "https://github.com/rackspace/php-opencloud.git",
"type": "git",
"reference": "origin/master"
}
}
}
}
Most of the packages you install via Composer make use of autoloading:
Basic Usage: AutoloadingComposer Docs
That is basically just including a single file in your bootstrap and you're ready to go:
require 'vendor/autoload.php';
That is relative to the location where you placed your composer.json file.

Use Composer without Packagist

Say for instance you want to use a bundle from someone else, but want to do some modifications. So you do your modifications in some new branch, and configure comspoer.json like:
{
"require": {
"sylius/assortment-bundle": "dev-soft-deleteable-products-disabled"
},
"repositories": [
{
"type": "package",
"package": {
"name": "sylius/assortment-bundle",
"version": "1.0",
"autoload": { "psr-0": { "Sylius\\Bundle\\AssortmentBundle": "" } },
"target-dir": "Sylius/Bundle/AssortmentBundle",
"source": {
"url": "https://github.com/umpirsky/SyliusAssortmentBundle.git",
"type": "git",
"reference": "soft-deleteable-products-disabled"
}
}
}
]
}
This works with master branch, but with custom branch it gives: The requested package sylius/assortment-bundle dev-soft-deleteable-products-disabled could not be found.
Any idea?
You should really be using a VCS repository instead of the package repository. Package is for when there is no composer.json and you want to specify it inline instead. In your case there is a composer.json, so you can use the VCS repo, like so:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/umpirsky/SyliusAssortmentBundle"
}
]
Composer will in this case use the GitHub API to fetch the branch names and check if the version dev-soft-deleteable-products-disabled exists. If it does, it will clone the repository and check out said branch.
Hopefully if you do this as a side effect your problem will be fixed as well.
For more information read the docs chapter on repositories.
Satis can be used as a micro version of Packagist - allowing you to centrally control your Composer dependancies for private repositories.
Composer Guide to Satis Usage

Categories