autoload psr-4 gets lost during install - composer-php

this is the composer.json of my bundle (shortened)
{
"name": "acme/my-bundle",
"type": "library",
"version": "0.5.0",
"autoload": {
"psr-4": {
"Acme\\MyBundle\\": ""
}
}
}
and in my project:
"require": {
"acme/my-bundle": "dev-master"
},
then i run composer install resulting in a installed.json like
[
{
"name": "acme/my-bundle",
"version": "dev-master",
"version_normalized": "9999999-dev",
"type": "library",
"installation-source": "source"
//
// here must be this:
// "autoload": {
// "psr-4": {
// "Acme\\MyBundle\\": ""
// }
// },
// but these lines are missing!
//
}
]
and a autoload-psr4.php:
<?php
// autoload_psr4.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
/* here must be this:
* 'Acme\\MyBundle\\' => array($vendorDir . '/acme/my-bundle'),
* but this line is missing!
*/
);
the autoload is gone, and also other keys like require
what am i missing?
i also tried psr-0, but no success. autoload_namespaces.php is just an empty array.

I did not mention, that I wanted to fetch a package from a private repo! This will make the difference!
So I had to re-specify the autoload
"require": {
"acme/my-bundle": "dev-master"
},
"repositories": [
{
"type": "package",
"package": {
"version": "dev-master",
"name": "acme/my-bundle",
"source": {
"url": "ssh://git#example.com/acme/my-bundle",
"type": "git",
"reference": "test"
},
// THIS IS |
// ADDITIONAL V
"autoload": {
"psr-4": {
"Acme\\MyBundle\\": ""
}
}
}
}
]
see https://stackoverflow.com/a/24193122/816362
Thanks #zacharydanger

Related

Using Composer autoload inside a ZIP package

I've been trying to get composer to generate classmaps for an API provided by a 3rd party company (OtherCompany in the example configuration) but have been unable to get it to work the way I think it should. However, I'm very new to composer so I may be completely wrong.
The situation is as follows. I have a project directory which contains the following composer.json (which does not generate classmaps for api.php):
{
"name": "company/company-library",
"description": "A useful library",
"type": "library",
"license": "GPL-3.0-or-later",
"authors": [
{
"name": "company",
"email": "hello#company.com"
}
],
"require": {
"othercompany/otherlibrary": "^1.0"
},
"config": {
"optimize-autoloader": true
},
"autoload": {
"psr-4": {
"Company\\CompanyLib\\": "src/"
}
},
"minimum-stability": "dev",
"repositories": [
{
"type": "package",
"package": {
"name": "othercompany/otherlibrary",
"type": "library",
"description": "Eases the integration of othercompany APIs into company's useful library",
"homepage": "https://otherlibraryportal.othercompany.com",
"version": "1.0",
"dist": {
"url": "../../../../repository/othercompany-otherlibrary-1.2.zip",
"type": "zip"
},
"require": {
"php": ">=5.6.1",
"phpseclib/phpseclib": "3.0.18"
},
"config": {
"optimize-autoloader": true
},
"autoload": {
"classmap": ["api.php"]
},
"minimum-stability": "dev"
}
}
]
}
The package "othercompany/otherlibrary" is contained in a ZIP file which only contains 2 files in a folder named othercompany-otherlibrary-1.2:
api.php
readme.txt
After a 'compose install', these files are stored in the directory:
vendor/othercompany/otherlibrary
The api.php file contains a number of classes which I would like to autoload. However, using the configuration above and various modifications of the classmap directive, have not been able to achieve the desired effect. Only if I move the classmap directive to the root level autoload directive in composer.json and update the path to vendor/othercompany/otherlibrary/api.php, classmaps are generated for the package my libary depends on. Snippet:
"autoload": {
"psr-4": {
"Company\\CompanyLib\\": "src/"
},
"classmap": ["vendor/othercompany/otherlibrary/api.php"]
}
Although this works and classmaps are now generated, I cannot help but think that this should not work this way as each package should independently be able to specify autoload options. If this is correct, what would be the right way to specify autoload options for the othercompany/otherlibrary package?
ADDITIONAL INFORMATION
api.php:
<?php
// Creates the API Request from the context
class APIRequest {
}
// API Response
class APIResponse {
}
// Api Method Type Constants
class APIMethodType {
}
// API Context that contain info for the API endpoint
class APIContext {
}
?>
companylibrary.php:
<?php
/**
* #package Company Library
* #author Company < hello#company.com >
* #version 1.0.0
*/
// Exit if accessed directly.
if (!defined('ABSPATH')) {
exit;
}
define('WC_CL_VERSION', '1.0.0');
require_once plugin_dir_path(__FILE__) . 'vendor/autoload.php';
/**
* Classes are correctly autoloaded if the autoload directive for the
* package the 'root' package depends on, is specified at the 'root'
* package level.
*
* If the autoload directive is specified at the package level of the
* 'sub' level of the package itself, no classmaps are generated.
*/
$public_key("othercompanypublickey");
$context = new APIContext();
$context->set_api_key('companyapikey');
$context->set_public_key($public_key);
$request = new APIRequest($context);
composer.json (which does generate classmaps for api.php):
{
"name": "company/company-library",
"description": "A useful library",
"type": "library",
"license": "GPL-3.0-or-later",
"authors": [
{
"name": "company",
"email": "hello#company.com"
}
],
"require": {
"othercompany/otherlibrary": "^1.0"
},
"config": {
"optimize-autoloader": true
},
"autoload": {
"psr-4": {
"Company\\CompanyLib\\": "src/"
},
"classmap": ["vendor/othercompany/otherlibrary/api.php"]
},
"minimum-stability": "dev",
"repositories": [
{
"type": "package",
"package": {
"name": "othercompany/otherlibrary",
"type": "library",
"description": "Eases the integration of othercompany APIs into company's useful library",
"homepage": "https://otherlibraryportal.othercompany.com",
"version": "1.0",
"dist": {
"url": "../../../../repository/othercompany-otherlibrary-1.2.zip",
"type": "zip"
},
"require": {
"php": ">=5.6.1",
"phpseclib/phpseclib": "3.0.18"
},
"minimum-stability": "dev"
}
}
]
}
Do not compress the folder containing the othercompany/otherlibrary files but instead, simply compress the files.
For a working project, please refer to GitHub:
github.com/ezoer/companylibrary

error class name not recognized when installing package through module`s composer

I created a module with Laravel Module and I want to install a package in a this module. The package was installed in a module's vendor but the problem is that its class is not defined somewhere else in the project.
Here is my composer.json :
{
"name": "nwidart/audit",
"description": "",
"authors": [
{
"name": "Nicolas Widart",
"email": "n.widart#gmail.com"
}
],
"extra": {
"laravel": {
"providers": [
"Modules\\Audit\\Providers\\AuditServiceProvider"
],
"aliases": {
}
}
},
"autoload": {
"psr-4": {
"Modules\\Audit\\": "Modules/Audit/"
}
},
"require": {
"owen-it/laravel-auditing": "^9.2",
}
}
You cannot use the package inside a module. You should use "composer merge plugin" for this problem or add it to the root of the project.
i use this package for merge composer.json files
https://github.com/wikimedia/composer-merge-plugin
just note :
{
"require": {
"wikimedia/composer-merge-plugin": "dev-master"
},
"extra": {
"merge-plugin": {
"include": [
"composer.local.json",
"Modules/*/composer.json"
],
"require": [
"Modules/Audit/composer.json"
],
"recurse": true,
"replace": false,
"ignore-duplicates": false,
"merge-dev": true,
"merge-extra": false,
"merge-extra-deep": false,
"merge-scripts": false
}
},

How to add a package to a custom laravel package?

I'm building a custom Laravel package which requires the guzzlehttp/guzzle package. Below is my composer.json file:
{
"name": "lomse/awesomePackage",
"description": "this an awesome package",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Selom",
"email": "awesome#gmail.com"
}
],
"minimum-stability": "dev",
"require": {
"guzzlehttp/guzzle": "^6.3"
},
"autoload": {
"psr-4": {
"Lomse\\AwesomePackage\\": "src/"
}
}
}
Below is the content of my AwesomeProvider.php file:
<?php
namespace Lomse\AwesomePackage;
use GuzzleHttp\Client;
use Illuminate\Support\ServiceProvider;
class AwesomeProvider extends ServiceProvider
{
public function boot(){
}
public function register()
{
$this->app->singleton(Awesome::class, function ($app) {
return new Awesome(new Client); //Class 'GuzzleHttp\Client' not found
});
}
}
I keep getting Class 'GuzzleHttp\Client' not found.
What am I doing wrong?
So, this turns out to be quite simple. I highlighted the steps to take in order to solve this. Hope this helps anyone who is having the same issue.
I had to push my code to a repo lomse/awesome-package on Github
then specified preferred-install as dist in the ./lomse/awesome-package/package.json config property`:
"config": {
"preferred-install": "dist"
}
The full code is
{
"name": "lomse/awesome-package",
"description": "this an awesome package",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Selom",
"email": "awesome#gmail.com"
}
],
"minimum-stability": "dev",
"require": {
"guzzlehttp/guzzle": "^6.3"
},
"autoload": {
"psr-4": {
"Lomse\\AwesomePackage\\": "src/"
}
},
"config": {
"preferred-install": "dist"
}
}
In the root package.json, specify the repository of your package as follow:
"repositories": [
{
"type": "git",
"url": "git#github.com:lomse/awesome-package.git"
}
]
Also add your package repo to the package.json require property as shown below:
"lomse/awesome-package": "dev-master"
From your root directory, run the code below to update your dependencies. This will clone the lomse/awesome-package repo into your vendor folder and install any other dependencies required by your package:
composer update -vvv
-vvv is for debugging purposes

composer installs own TYPO3 extension in wrong path

I have a own TYPO3 extension hosted on bitbucket. Getting this via composer works (see here for input). The extension is downloaded into my vendor folder. Being there i cannot install the extension via extension-manager.
How can I getting my ext into typo3conf/ext (ensuring autoloading will work)?
The extensions coming via
{
"type": "composer",
"url": "http://composer.typo3.org/"
}
are going to (as expected):
web/typo3config/ext
here is my project composer.json:
{
"repositories": [
{
"type": "composer",
"url": "http://composer.typo3.org/"
},
{
"type": "package",
"package": {
"name": "metaxos/exaibbrplus",
"version": "dev-2016",
"source": {
"url": "https://metaxos#bitbucket.org/metaxos/exaibbrplus.git",
"type": "git",
"reference": "release/2016"
}
}
}
],
"name": "Metaxos/ibbrating2016",
"require": {
"typo3/cms": "7.6.2",
"bk2k/bootstrap-package" : "dev-master",
"typo3-ter/compatibility6" : "7.6.0",
"typo3-ter/extension-builder" : "7.6.0",
"metaxos/exaibbrplus": "dev-2016"
},
"extra": {
"typo3/cms": {
"cms-package-dir": "{$vendor-dir}/typo3/cms",
"web-dir": "web"
}
}
}
here is my extension composer.json:
{
"name": "metaxos/exaibbrplus",
"description": "custom ext for typo3",
"type": "typo3-cms-extension",
"version": "0.0.1",
"require": {
"typo3/cms-core": ">=7.6.0,<8.0"
},
"replace": {
"extkey": "self.version",
"typo3-ter/extkey": "self.version"
},
"autoload": {
"psr-4": {
"Metaxos\\Exaibbrplus\\": "Classes/"
}
},
"keywords": ["custom", "ext"],
"homepage": "http://www.blah.ch"
}
For Composer to install the package in web/typo3conf/ext, the package needs to have the type typo3-cms-extension. In your extension's composer.json this type is actually declared, however Composer will not respect it because you explicitly declare the package configuration in your project-level composer.json:
"repositories": [
# ...
{
"type": "package",
"package": {
"name": "metaxos/exaibbrplus",
"version": "dev-2016",
"source": {
"url": "https://metaxos#bitbucket.org/metaxos/exaibbrplus.git",
"type": "git",
"reference": "release/2016"
}
}
}
]
As you're using "type": "package" for your own repository, I suspect that Composer ignores the composer.json from that package. As you already have a Git repository that contains a composer.json, I'd suggest adding the repository using the vcs type instead:
"repositories": [
{
"type": "vcs",
"url": "https://metaxos#bitbucket.org/metaxos/exaibbrplus.git"
}
]
When doing that, Composer should use the composer.json from that repository, recognize the correct package type (typo3-cms-extension) and install the package in the correct directory.
You need to add the type key with the value typo3-cms-extension to the root composer.json. This will place your extension in web/typo3conf/ext instead of vendor/$vendor/$package which in turn will make it available to the cms.
It is important, to know that if you redefine the package in the root composer.json as repository type package, nothing from the extensions' composer.json file will be taken into account and you need to define any concerns about that package in the root composer.json.
So-applying the rules I mentioned above, your root composer.json will look like that:
{
"repositories": [
{
"type": "composer",
"url": "http://composer.typo3.org/"
},
{
"type": "package",
"package": {
"name": "metaxos/exaibbrplus",
"version": "dev-2016",
"type": "typo3-cms-extension",
"source": {
"url": "https://metaxos#bitbucket.org/metaxos/exaibbrplus.git",
"type": "git",
"reference": "release/2016"
},
"autoload": {
"psr-4": {
"Metaxos\\Exaibbrplus\\": "Classes/"
}
},
}
}
],
"name": "Metaxos/ibbrating2016",
"require": {
"typo3/cms": "7.6.2",
"bk2k/bootstrap-package" : "dev-master",
"typo3-ter/compatibility6" : "7.6.0",
"typo3-ter/extension-builder" : "7.6.0",
"metaxos/exaibbrplus": "dev-2016"
},
"extra": {
"typo3/cms": {
"cms-package-dir": "{$vendor-dir}/typo3/cms",
"web-dir": "web"
}
}
}
As mentioned above by #helmbert, you are either left with completely redefining the package or using another repository type. You may want to consider using satis or a URL repository.
try to add
"replace": {
"exaibbrplus": "self.version",
"typo3-ter/exaibbrplus": "self.version"
},
And use only "Metaxos\\Exaibbrplus\\": "Classes/" in the autoloader.

How do I set the correct settings for my composer installer

My current folder structure:
Composer/PluginInstaller.php
The content of composer.json:
{
"name": "zepluf/installer",
"type": "composer-installer",
"description": "Composer installer for ZePLUF addons.",
"homepage": "http://github.com/zepluf/installer",
"license": "custom",
"authors": [
{
"name": "Raine Ng",
"email": "vunguyen#rubikin.com",
"homepage": "http://rubikin.com"
}
],
"autoload": {
"psr-0": {
"Zepluf\\Composer": "Composer"
}
},
"extra": {
"class": "Zepluf\\Composer\\PluginInstaller"
},
"target-dir": "zepluf/Composer"
}
I would like the installer to be put inside:
vendor/zepluf/Composer/PluginInstaller.php
The problem is that I keep getting:
Fatal error: Class 'Zepluf\Composer\PluginInstaller' not found in phar://C:/Prog
ramData/Composer/bin/composer.phar/src/Composer/Installer/InstallerInstaller.php
on line 102
Any pointer will be greatly appreciated
Assuming PluginInstaller.php is at the root of your package, it should be configured like this:
// ...
"autoload": {
"psr-0": {
"Zepluf\\Composer": ""
}
},
"extra": {
"class": "Zepluf\\Composer\\PluginInstaller"
},
"target-dir": "Zepluf/Composer"

Resources