Class not found with Composer autoload and PSR-0 - php

I'm trying to use PSR-0 instead of classmap in composer but having some difficulty. It appears that my json file is correct yet the class I'm trying to access is not being picked up. Can someone please have a look and see if they can spot where I'm going wrong:
Here is what I have in composer.json:
"autoload": {
"psr-0": {
"MartynBiz\\Slim3Controller\\": "src/"
}
},
Below is my folder structure:
$ tree .
.
|-- README.md
|-- composer.json
|-- composer.lock
|-- phpunit.xml
|-- src
| |-- Controller.php
| |-- Http
| | |-- Request.php
| | `-- Response.php
| `-- Test
| `-- PHPUnit
| `-- TestCase.php
`-- tests
|-- bootstrap.php
`-- library
`-- ControllerTest.php
Here is my Controller class:
<?php
namespace MartynBiz\Slim3Controller;
abstract class Controller
{
Also, I can confirm that composer autoload script has been included.

Use PSR-4 instead. PSR-0 requires the prefix to be included in the document tree (i.e. src/MartynBiz/Slim3Controller/Controller.php).

Related

Laravel-Module : InvalidArgumentException Action Modules\Test\Http\Controllers\BType_Controller#index not defined

Overview:
I've Laravel project with a Laravel-Module a Laravel Package for Modularizing the project. The Laravel Project routes are working. However, In Laravel-Module action() and url() Helpers methods showing function doesn't exist while it exist.
Problem Statement:
Unable to direct to Laravel-Module Controller using action() and url() method
From AType_Controller.php
namespace Modules\Test\Http\Controllers;
class AType_Controller extends Controller
{
public function testFunc()
{
url(
action('\Modules\Test\Http\Controllers\BType_Controller#index'),
)
InvalidArgumentException Action Modules\Test\Http\Controllers\BType_Controller#index not defined.
Folder Structure:
project-root/
├─ app/
│ └─ Http/
│ └─ Controllers/
├─ bootstrap/
├─ config/
├─ database/
├─ Modules/
| └─ Test/
| └─ Config/
| └─ Console/
| └─ Database/
| └─ Entities/
| └─ Http/
| └─ Controllers/
| └─ AType_Controller.php
| └─ BType_Controller.php
| └─ Notifications/
| └─ Providers/
| └─ Resources/
| └─ Utils/
| └─ composer.json
| └─ module.json
| └─ package.json
├─ public/
│ └─ index.php
├─ resources/
├─ routes/
├─ storage/
├─ vendor/
├─ .env
└─ composer.json
composer.json
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"type": "project",
"require": {
"php": "^8.0.2",
"consoletvs/charts": "^7.2",
"laravel/framework": "^8.29",
"laravel/tinker": "^2.6",
"laravel/ui": "^3.2",
"nwidart/laravel-menus": "^7.0",
"nwidart/laravel-modules": "^8.2",
},
"autoload": {
"files": [
"app/Http/helpers.php"
],
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"Modules\\": "Modules/"
}
},
Edit 1:
I've publish the package configuration by running
php artisan vendor:publish --provider="Nwidart\Modules\LaravelModulesServiceProvider"
And edited my composer.json to add Modules in autoload using ps-4.
Run the composer dump-autoload command.
Edit 2:
$ php artisan tinker
Psy Shell v0.10.6 (PHP 8.0.2 — cli) by Justin Hileman
>>> (new Modules\Test\Entities\Document)->foo()
=> "foo"
Document.php
<?php
namespace Modules\Test\Entities;
use Illuminate\Database\Eloquent\Model;
class Document extends Model
{
public function foo()
{
return 'foo';
}
Edit 3:
$ php artisan module:v6:migrate
All modules have been migrated.
+---------------+---------+
| Module name | Status |
+---------------+---------+
| Essentials | Enabled |
| Manufacturing | Enabled |
| Superadmin | Enabled |
| Woocommerce | Enabled |
This command create modules_statuses.json under Laravel Project.

PSR-4 Autoloading in Laravel

Working on an application that will be used to extend the Chatter package
Issue is, I want to make modifications to the package but don't want to do is directly to the package. Changes won't persist after a composer update.
Now from my understanding extending the package would require me to exclude the specific file from auto-loading and load my own files/directories...
composer.json
I made changes to composer.json to accommodate to Mac/Unix and Windows file path syntax:
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"exclude-from-classmap": [
"vendor/devdojo/chatter/src/Controllers/ChatterDiscussionController.php",
"vendor/devdojo/chatter/src/Models/Discussion.php",
"vendor\\devdojo\\chatter\\src\\Controllers\\ChatterDiscussionController.php",
"vendor\\devdojo\\chatter\\src\\Models\\Discussion.php"
],
"psr-4": {
"App\\": "app/",
"Forum\\": "app/forum"
}
},
folder structure
.
+-- app
| +-- Console
| +-- Exceptions
| +-- Forum
| +-- Chatter
| +-- Controllers
| +-- ChatterDiscussionController.php
| +-- Models
| +-- ...
| +-- Helpers
| +-- Http
| +-- ...
+-- bootstrap
+-- ...
Custom ChatterDiscussionController.php
<?php
namespace Forum\Chatter\Controllers;
use Auth;
use Carbon\Carbon;
use DevDojo\Chatter\Events\ChatterAfterNewDiscussion;
use DevDojo\Chatter\Events\ChatterBeforeNewDiscussion;
use DevDojo\Chatter\Models\Models;
use Event;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as Controller;
use Validator;
use App\User;
class ChatterDiscussionController extends Controller
{...
test
To test this, I placed dd("Custom") in my custom DiscussionController and dd("Original") within the package version of DiscussionController. And as you may already surmise, this continues to hit the package version of the DiscussionController.
The only way I got this to work was to add the specific file to files key within autoload section "files": ["app/Helpers/Chatter.php"] <~~ This is an example. This will be a managing nightmare once I start extending more and more packages. From my understanding this can be accomplished by creating a ServiceProvider, but I am unable to find a suitable example of getting this to work using that method.
Has anyone had this issue before? What was the fix. Any help in the right direction is much appreciated.

namespace defined in autoload psr-4 using in laravel 5 app.php giving not found error

stucked my heads in some errors.i dont getting where i have done my mistake.
I am using laravel 5 and installed it.I want to use l5-repository so i installed https://github.com/prettus/l5-repository this repository using composer commnad:
composer require prettus/l5-repository
and i made all changes as per installation document and its working fine.
after installing repository using composer my directory structure is as below:
curovis
|-- composer.json
|-- composer.lock
|-- app
|-- bootstarp
|-- config
|-- database
`-- vendor
|-- composer
`-- prettus
`-- l5-repository
|-- src
| `-- Prettus
| `-- Repository
`-- composer.json
after this as per doc i have made following entry in /var/www/curovis/config/app.php:
Prettus\Repository\Providers\RepositoryServiceProvider::class,
and its working fine.
Now i want to change composer.json of root directory entry as following:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"Prettus\\Repository\\": "vendor/prettus/l5-repository/src/Prettus"
}
},
and use composer update command. it also works fine.
now i want use same repo with another name so i have change composer.json with follwing:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"RepoTest\\Repository\\": "vendor/repotest/l5-repository/src/RepoTest"
}
},
and add RepoTest\Repository\Providers\RepositoryServiceProvider::class, in app.php file.run composer update command. then it gives following error:
FatalErrorException in /var/www/curovis/vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php line 146: Class 'RepoTest\Repository\Providers\RepositoryServiceProvider' not found
i cant understand why laravel is looking for /var/www/curovis/vendor/laravel/framework/src this path instead of provided as "RepoTest\\Repository\\": "vendor/repotest/l5-repository/src/RepoTest" in composer.json.
is anything i am missing or any error in composer.
Thanks for help.
You NEVER add autoloading for the packages you added inside your main composer.json. The path "vendor" should never appear there.
I recognize you are trying to add a package, then modify it and use that instead. You changed the autoloading prefix from "Prettus" to "RepoTest", but did you also change the namespace in the PHP files? Simply renaming the path does not affect the PHP class names and namespaces, so if you rename a file, and inside that file there is no matching class defined, autoloading will fail.
Whatever it is you are trying to do, I think it is a good idea to ask about that instead of asking to fix problems you think are necessary because of the way you do solve your original problem. If you want to know how to modify an existing project and use your variant of it: Ask about it.
sovled above error by changing composer entry:
when i have see autoload_classmap.php and autoload_psr4.php files of /vendor/composer/ folder autoload_classmap.php file does not contain namespace that i require.
so i have made following change in my composer.json:
"autoload": {
"classmap": [
"database","vendor/repotest/src/Repotest/Repository/"
],
"psr-4": {
"App\\": "app/",
"Repotest\\Repository\\": "vendor/repotest/src/Repotest/Repository/"
}
},
so by making entry in "classmap": make entry in autoload_classmap.php and working fine now.
Thanks #sven for your help.
Example:
"autoload": {
"classmap": [
"database"
],
"files": [
"app/helper.php"
],
"psr-4": {
"App\\": "app/"
}
}
Default Composer file to load.

How to use Composer to autoload classes from outside the vendor?

I use psr-4 autoloader from composer:
"autoload": {
"psr-4": {
"DG\\Munchkin\\": "src/DG/Munch/"
}
}
This loads classes from /var/www/html/xxx/vendor/yyy/src/DG/Munch
But how can I load classes from /var/www/html/xxx/?
I wrote my own autoloader, but when I require vendor/autoload.php (composer autoload) and my autoloader, it won't work until I create instance of a class in my own autoloader.
The src directory would be in your project root.
Its on the same level as vendor directory is.
If you define
"autoload": {
"psr-4": {
"DG\\Munchkin\\": "src/DG/Munch/"
}
}
this will not load classes from /var/www/html/xxx/vendor/yyy/src/DG/Munch,
like you stated.
Because your project structure is:
/var/www/html/
+- /xxx (project)
- composer.json
+- /src
+- DG
+- Munch
+- /vendor
- autoload.php
+- vendor-projectA
+- vendor-projectB
+- yyy
The \DG\Munchkin namespace would map to classes inside
/var/www/html/xxx/src/DG/Munch and not inside
/var/www/html/xxx/vendor/yyy/src/DG/Munch.
But how can I load classes from /var/www/html/xxx/?
Define the paths in the composer.json (inside /var/www/html/xxx/) of your project:
"autoload": {
"psr-4": {
"ProjectRoot\\" : "",
"NamspaceInSourceDir\\" : "src/"
}
}
or load the composer autoloader in your index.php or during it's bootstrap and add the paths manually:
$loader = require 'vendor/autoload.php';
$loader->add('Namespace\\Somewhere\\Else\\', __DIR__);
$loader->add('Namespace\\Somewhere\\Else2\\', '/var/www/html/xxx');
Referencing: https://getcomposer.org/doc/04-schema.md#autoload

Include multiple composer repository configuration files

I want to break up the composer repository configuration into different files.
I use local and external repositories and I would like to keep their configurations separate.
These files would then be pulled into the main composer.json when running the install or update task.
Is this possible?
There is now a plugin called composer-merge-plugin which can merge multiple composer files at runtime.
Usage:
Assume you have your main composer.json file located in a base path, and then you have other composer.json files that you'd like to load from subdirectories in /plugins:
/
|-- composer.json
|-- /plugins
|-- /kittenizer
|-- composer.json
|-- /puppyizer
|-- composer.json
In your main composer.json file, you can load these with:
{
"require": {
"wikimedia/composer-merge-plugin": "~1"
},
"extra": {
"merge-plugin": {
"include": [
"plugins/*/composer.json"
],
"recurse": true,
"replace": false,
"merge-dev": true,
"merge-extra": false
}
}
}
I'm quite late to the party, but I had a similar issue and solved it without a composer plugin.
/root
|-- composer.json
|-- /vendor
|-- /more-dependencies
|-- composer.json
Your composer file in the root-dir:
{
"repositories": [
{
"type": "path",
"url": "more-dependencies"
}
],
"require": {
"something/more-dependencies": "dev-master"
}
}
Your composer file in your other directory (more-dependencies) has to contain at least the following:
{
"name": "something/more-dependencies"
}
You can now composer install in your root directory and anything specified in your subfolder's composer.json will land in your root's vendor folder.
❗ Warning: Only root's composer.json can include repository metadata, not the one in the subfolder (composer-doc).
Side note: In my case the composer.json in the subdir is a cloneable resource. I use the composer hook pre-install-cmd to make sure "more-dependencies" are existing and up-to-date.
"scripts": {
"more-dependencies": [
"git -C more-dependencies pull || git clone https://example/more-dependencies.git more-dependencies"
],
"pre-install-cmd": [ "#more-dependencies" ],
"pre-update-cmd": [ "#more-dependencies" ]
},

Categories