I have created a custom Laravel package. Its hosted on a private repository.
When I try to install the package in a Laravel application like this:
composer require memberportal/congress-models
I get this error:
In ProviderRepository.php line 208:
Class 'Memberportal\CongressesModels\CMServiceProvider' not found
Script #php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1
Installation failed, reverting ./composer.json to its original content.
I have double checked everything a hundred times, but I am clueless why he doesn't find the class CMServiceProvider.php.
Do I need to specify the provider anywhere else then in the composer.json?
This is the content of composer.json from my package:
{
"name": "memberportal/congress-models",
"description": "Takes care of the models between API and client",
"type": "metapackage",
"authors": [
{
"name": "My name",
"email": "my#email.com"
}
],
"version" : "1.0",
"minimum-stability": "stable",
"require": {
"laracasts/presenter": "^0.2.2"
},
"require-dev": {
"orchestra/testbench": "^4.0"
},
"autoload": {
"psr-4": {
"Memberportal\\CongressesModels\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Memberportal\\CongressesModels\\Tests\\": "tests"
}
},
"extra": {
"laravel": {
"providers": [
"Memberportal\\CongressesModels\\CMServiceProvider"
]
}
}
}
This is the folder structure:
This is the content of CMServiceProvider.php:
<?php
namespace Memberportal\CongressesModels;
use Illuminate\Support\ServiceProvider;
class CMServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* #return void
*/
public function register()
{
}
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
$this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
}
}
Since you want to install a Laravel package your package type should be package. A metapackage is a package that does not contain actual software, it simply depends on other packages to be installed.
In short, change
"type": "metapackage",
to
"type": "package",
and Laravel will find the service provider with auto-discovery when the package is required by composer.
Related
I know the title topic sounds similar to other questions, but I've searched many topics on stackoverflow and none resolve my issue.
I am currently developing a package under Laravel ^8.12, below the content of the function that register my routes:
protected function registerRoutes(): void
{
Route::prefix('workflowmakr')
->namespace('AlvariumDigital\WorkflowMakr\Http\Controllers')
->as('workflowmakr.')
->middleware(config('workflowmakr.routes_middleware'))
->group(__DIR__ . '/../routes/api.php');
}
And below is the content of the routes/api.php file:
<?php
use Illuminate\Support\Facades\Route;
Route::resource('actions', 'ActionController')->except(['created', 'edit']);
Route::resource('scenarios', 'ScenarioController')->except(['created', 'edit']);
Route::resource('statuses', 'StatusController')->except(['created', 'edit']);
Route::resource('transitions', 'TransitionController')->except(['created', 'edit']);
For a better view of the project architecture, below is a screenshot of the packages folder containing the package under development:
And finally, below is the composer.json declaring my package:
...
"extra": {
"laravel": {
"providers": [
"AlvariumDigital\\WorkflowMakr\\WorkflowMakrServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/",
"AlvariumDigital\\WorkflowMakr\\": "packages/AlvariumDigital/WorkflowMakr/src/"
}
},
...
When I execute the command php artisan route:list to view all my routes I got this error :
$> php artisan route:list
Illuminate\Contracts\Container\BindingResolutionException
Target class [AlvariumDigital\WorkflowMakr\Http\Controllers\ActionController] does not exist.
at D:\Films\R_D\Laravel packages\workflow-makr\vendor\laravel\framework\src\Illuminate\Container\Container.php:832
828▕
829▕ try {
830▕ $reflector = new ReflectionClass($concrete);
831▕ } catch (ReflectionException $e) {
➜ 832▕ throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e);
833▕ }
834▕
835▕ // If the type is not instantiable, the developer is attempting to resolve
836▕ // an abstract type such as an Interface or Abstract Class and there is
1 [internal]:0
Illuminate\Foundation\Console\RouteListCommand::Illuminate\Foundation\Console\{closure}(Object(Illuminate\Routing\Route))
2 D:\Films\R_D\Laravel packages\workflow-makr\vendor\laravel\framework\src\Illuminate\Container\Container.php:830
ReflectionException::("Class AlvariumDigital\WorkflowMakr\Http\Controllers\ActionController does not exist")
EDIT
Below is the content of the ActionController file:
<?php
namespace AlvariumDigital\WorkflowMakr\Http\Controllers;
use AlvariumDigital\Models\Action;
use AlvariumDigital\WorkflowMakr\Helpers\Constants;
use Illuminate\Routing\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class ActionController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\JsonResponse
*/
public function index()
{
$query = Action::query();
if (config('workflowmakr.pagination_size') == -1) {
return response()->json($query->get(), 200);
}
return response()->json($query->paginate(config('workflowmakr.pagination_size')), 200);
}
// ...
}
EDIT 2
The content of the package composer.json file:
{
"name": "AlvariumDigital/WorkflowMakr",
"description": "Generalize the management of your workflows",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Alvarium Digital",
"email": "contact#alvariumdigital.com",
"homepage": "http://www.alvariumdigital.com",
"role": "Corporate"
},
{
"name": "EL OUFIR Hatim",
"email": "heloufir#alvariumdigital.com",
"homepage": "https://www.linkedin.com/in/eloufirhatim/",
"role": "Developer"
}
],
"support": {
"email": "heloufir#alvariumdigital.com"
},
"minimum-stability": "dev",
"require": {}
}
Did I do something wrong or incomplete?
You can ask for more details if needed.
Thanks
You have structured this directory incorrectly. You have the PSR4 autoloading loading the src directory as the namespace. Your controllers are not in the src folder, only the Service Provider is in there. So to composer there are no files for it to find and autoload based on your PSR4 autoloading.
I'm trying to implement simple library without web server. That means I actually don't have any entry point where I can include autoload.php.
I trying to add bunch of classes, but PhpStorm cannot recognise namespacing and and my classes cannot being auto-imported.
E.g.
I'm trying to import file App/Engines/Contracts/BaseEngine.php which is placed in src/Engines/Contracts/BaseEngine.php via
use App\Engines\Contracts\BaseEngine;
The PhpStorm says Undefined Class
All PhpStorm configuration seems to be correct: I've specified composer.json and checked auto-import in namespace scope.
So, basically the question is: How to deal with composer autoloader in such a library?
Attaching my composer.json code.
{
"name": "mom/task",
"description": "Todo",
"authors": [
{
"name": "Foo Bar",
"email": "foo.mail.com"
}
],
"require": {
"php": "^7.4"
},
"require-dev": {
"phpunit/phpunit": "^8",
"squizlabs/php_codesniffer": "3.*"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
UPD: attaching BaseEngine code.
<?php
namespace App\Engines\Contracts;
interface BaseEngine
{
/**
* #param int $variable
* #param int $multiplier
* #return mixed
*/
public function compute(int $variable, int $multiplier): int;
}
I've added a repository git as a composer dependency to my project.
"repositories": [
{
"type":"package",
"package": {
"name": "Neabfi/SDK-PHP",
"version":"3.1.2",
"source": {
"url": "https://github.com/Neabfi/SDK-PHP.git",
"type": "git",
"reference":"master"
}
}
}
],
"require": {
"Neabfi/SDK-PHP": "3.1.2"
},
In this repository there is a Client class :
<?php
namespace RecastAI;
/**
* Class Client
* #package RecastAI
*/
class Client { ... }
When i try to use it.
<?php
use RecastAI\Client;
[...]
$client = new Client(env('RECAST_REQUEST_TOKEN'), env('RECAST_LANGUAGE'));
[...]
It seems that he cant find it :
[2017-07-26 15:30:50] local.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Class 'RecastAI\Client' not found in /Users/fabien/Sites/abote/app/Recast.php:20
Stack trace:
You should try this in your composer.json:
"repositories": [
{
"type": "git",
"url": "https://github.com/Neabfi/SDK-PHP.git"
}
],
And keep the require section as you have it, perform composer install, and that's it.
I have a question related to Package for Laravel 5. I am creating one package and tried to use that. package successfully created and using composer i can also get that in New Laravel setup , issue is that when i tried to use that it's says class not found. Here's my composer.json and Steps that i followed:
for e.g. my username = git_test and packagename = mypackage
My Package Structure :
**git_test > mypackage > src
My composer.json file
{
"name": "git_test/mypackage",
"description": "XXXXXXXXXX",
"keywords": ["laravel"],
"license": "MIT",
"authors": [
{
"name": "XXXXXXX",
"email": "XXXXXX#gmail.com"
}
],
"require": {
"php": ">=5.4.0",
"illuminate/support": "5.0.*"
},
"autoload": {
"psr-4": {
"git_test\\mypackage\\": "src/"
}
},
"minimum-stability": "dev"
}
Here's my src/myclass.php
namespace git_test\mypackage;
class myclass {
function test(){ echo "This is Test"; }
}
Now i am going to use this in my new laravel project so i add package in my directory composer and try to use the myclass in my HomeController
HomeController Code
use git_test\mypackage\myclass as TaskClass;
class HomeController extends Controller {
public function index()
{
$atTaskObj = new TaskClass('');
}
I got the error like "git_test\mypackage\myclass" Not Found. where i am doing wrong? any suggestion please.
Thanks in Advance!!!
PSR-4 paths have to end with \\:
"autoload": {
"psr-4": {
"git_test\\mypackage\\": "src/"
}
},
I've crated package "za-web/tags"
composer.json:
{
"name": "za-web/tags",
"description": "",
"authors": [
{
"name": "Aleksandr Zamiatin",
"email": "cawa123#mail.ru"
}
],
"require": {
"php": ">=5.4.0",
"illuminate/support": "5.0.*"
},
"autoload": {
"classmap": [
"src/views"
],
"psr-4": {
"ZaWeb\\Tags\\": "src/ZaWeb/Tags"
}
},
"minimum-stability": "dev"
}
And to view tags I'm trying to do
return View::make('tags::cloud', ['data' => $data])->render();
And I've got the error: No hint path defined for [tags].
It works only if I've add to TagsServiceProvider in register() method:
View::addNamespace('tags', __DIR__ . '/../../views');
Your solution work but as explained in the Laravel 5 documentation on package development you should add to your ServiceProvider's boot method:
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
instead of
View::addNamespace('tags', __DIR__ . '/../../views');
If you want to publish your package views, don't forget to use the publishes method:
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
$this->publishes([
__DIR__.'/path/to/views' => base_path('resources/views/vendor/courier'),
]);
}