I am developing a package but somehow I am not able to make Laravel to discover it.
Package is on the root of the app and follows the next structure:
Files:
StatusManager.php
<?php
namespace TroyerxStatusManager;
trait StatusManager {
//Code
}
Composer.json in packages/troyerx/statusmanager/
{
"name": "troyerx/statusmanager",
"description": "Simple model status manager",
"license": "MIT",
"keywords": [
"troyerx",
"php",
"statusmanager"
],
"authors": [
{
"name": "Sergio",
"email": "[email protected]"
}
],
"autoload": {
"psr-4": {
"Troyerx\Statusmanager\": "src/"
}
},
"require": {}
}
Mi app composer.json looks like:
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"require": {
"php": "^8.1",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^10.0",
"laravel/sanctum": "^3.2",
"laravel/tinker": "^2.8"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
"laravel/pint": "^1.0",
"laravel/sail": "^1.18",
"mockery/mockery": "^1.4.4",
"nunomaduro/collision": "^7.0",
"phpunit/phpunit": "^10.0",
"spatie/laravel-ignition": "^2.0"
},
"autoload": {
"psr-4": {
"App\": "app/",
"Troyerx\Statusmanager\": "packages/troyerx/statusmanager/src/",
"Database\Factories\": "database/factories/",
"Database\Seeders\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Troyerx\Statusmanager\": "packages/troyerx/statusmanager/src/",
"Tests\": "tests/"
}
},
"scripts": {
"post-autoload-dump": [
"Illuminate\Foundation\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-update-cmd": [
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
],
"post-root-package-install": [
"@php -r "file_exists('.env') || copy('.env.example', '.env');""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true,
"allow-plugins": {
"pestphp/pest-plugin": true,
"php-http/discovery": true
}
},
"minimum-stability": "stable",
"prefer-stable": true
}
Since the package is marked to be discover on the autoload, I should expect to get it included when I run:
composer dump-autoload
But I get the following prompt:
Generating optimized autoload files
> IlluminateFoundationComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
INFO Discovering packages.
laravel/sail ................................................................................................................................ DONE
laravel/sanctum ............................................................................................................................. DONE
laravel/tinker .............................................................................................................................. DONE
nesbot/carbon ............................................................................................................................... DONE
nunomaduro/collision ........................................................................................................................ DONE
nunomaduro/termwind ......................................................................................................................... DONE
spatie/laravel-ignition ..................................................................................................................... DONE
Generated optimized autoload files containing 5729 classes
If I call for the trait in a model its not autoloaded
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use TroyerxStatusManagerStatusManager as StatusManager;
class Order extends Model
{
use StatusManager;
}
Gives next error:
Trait "TroyerxStatusManagerStatusManager" not found
Why Laravel its not loading my package? Which step I am missing or where is the problem?
2
Answers
I have found the solution, to make Laravel to discover/install my package when I run
composer dump-autoload
.In the app composer.json I added:
And added in the require-dev the next line:
After running
composer update
the package is discover:So, your package’s
composer.json
should be like this:See that I have:
version
, so you can keep track of version and it is easierYour main
composer.json
should be like this (I will list the sections I have changed or added):I have:
autoload
andautoload-dev
require
with a version constraintrepositories
section in the file linking to what folder it should look it upSo, first edit your package’s composer file, then add the
repositories
to your main composer file, and then use the command line to docomposer require troyerx/statusmanager:^1.0
and done, it will automatically be picked.Remember to bump the package’s composer version (
version
section) to a new version, and then just runcomposer update troyerx/statusmanager
in your main composer and done!This is the composer documentation I have used: https://getcomposer.org/doc/05-repositories.md#path
One thing to have in mind: if you are developing a Laravel package, you should not have
database
andfactories
insidesrc
, but outside, and then have that package’scomposer.json
like this:You need to have your own
ServiceProvider
and add it to the package’s composerextra -> laravel
section, like this: https://github.com/barryvdh/laravel-ide-helper/blob/4dc20b028adaeadf603860f179f09da5aa21f5b5/composer.json#L70-L74Use that development package as guide on how to implement your own package, it should look like very similar (at least with your files, but structure wise).
Use Laravel Jetstream (for example), to see how to load the migrations. Do follow it as an example.
Have in mind that all Laravel packages are like those 2, so if you know a package, go to github and see the structure is has and what it has in
composer.json
, etc. Follow that!