Laravel Custom Trait Not Found - php

I'm new to traits, but thought I'd give it a try. But, it doesn't seem to load.
I've created a trait within a folder under the Laravel app directory: app\Helpers called CheckPermsAgainstObjectTrait.php
Here is the trait code:
<?php
namespace App\Helpers;
trait CheckPermsAgainstObjectTrait {
function something{}
}
I try to use it in a controller as such:
<?php
namespace App\Http\Controllers;
use this&that;
use App\Helpers\CheckPermsAgainstObjectTrait;
class PolicyController extends Controller{
use CheckPermsAgainstObjectTrait;
}
Classes in that directory load fine. PHPStorm sees the trait fine. I've clear compiled aritsan and dumped autoload. I'm guessing there is something that Laravel doesn't like with the namespacing? I would hope I don't need to do any manual loading in composer -- but I'm having trouble finding any documentation to give me a hint as to what I'm screwing up.
The error:
FatalErrorException in PolicyController.php line 15:
Trait 'App\Helpers\CheckPermsAgainstObjectTrait' not found
Any thoughts?

Did you dump autoload files?
composer dump-autoload

The answer for me was that I had the wrong namespace at the top of my trait file due to working from a Laravel trait as an example. If your trait is in App/Traits/MyTrait.php then make sure your namespace is:
namespace App\Traits;
trait MyTrait
{
// ..
}
Then from the file that's including the trait:
use App\Traits\MyTrait;
class MyClass
{
use MyTrait;
// ..
}
No need to mess with config/app.php, composer.json or autoloading.

I had a very similar problem where I was getting the error Trait 'Tests\CreatesApplication' not found in '.../my_project/tests/TestCase.php' on line 9 while running tests with phpunit because I manually updated my Laravel project and must have missed some changes. This may also happen to anyone creating a trait or class in a unique namespace.
Anyways, #Devon 's comment on the original question pointed me in the right direction.
I was missing the required autoloader configuration in my composer.json file, so I checked what it should be for my version of Laravel (5.4 in this case) from the Laravel github repository.
In this case, I was not calling from a namespace within App\ (which was already in composer.json.)
Here's what I was missing from composer.json:
{
...,
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
...
}
Thanks goes to Devon! Hope this keeps someone else from pulling their hair out.

composer dumpautoload -o
this worked for me

This may happen sometime when your Trait filename is misspelled or incorrect as with the class name. Do check your file name is same as classname

This may happen sometime when your Trait filename is misspelled or incorrect as with the class name. Do check your file name is same as classname

Related

I manually delated a Trait file, now I get "Trait 'App\Http\Controllers\CommonTrait' not found". How do I fix this?

After manually deleting a Trait file that was no longer needed by the compiler I see that the compiler is looking in the Controller folder instead of the Traits folder.
I have tried composer dump-autoload, php artisan clear-compiled, php artisan /clear-cache and php artisan optimize. How can I fix this problem?
After manually deleting a Trait file that was no longer needed by the compiler I see that the compiler is looking in the Controller folder instead of the Traits folder.
I guess this means you moved the Trait file into another directory?
Since composer usually is configured to use the PSR-4 autoloading this would require you to also change the namespace of the move Trait.
I.e. trying to load App\Http\Controllers\CommonTrait the autoloader is looking for the Trait in the src/Http/Controllers/CommonTrait.php file. If you moved that file to say src/Http/Controllers/Traits/CommonTrait.php you have to change the namespace of the Trait to
namespace App\Http\Controllers\Traits;
and import it for usage as
use App\Http\Controllers\Traits\CommonTrait;
The answer to my problem is to make sure that nothing in your code is using the trait. I found a controller that was still using the trait. Big newbie mistake. Maybe it's time for this old sea-dog to ...

Laravel package development - Target class [ControllerName] does not exist

I'm following a tutorial on how to create laravel packages.
I'm using Laravel v8.42.1 (PHP v7.4.3) and jetstream package.
I'm stuck on creating a controller for my package, I always get following error when trying to connect to my url via the laraval app (<base-url/playground):
Target class [TestVendor\TestPackage\Http\Controllers\PlaygroundController] does not exist.
The TestVendor\TestPackage\src\routes.php is recognized by the main application:
use TestVendor\TestPackage\Http\Controllers\PlaygroundController;
use Illuminate\Support\Facades\Route;
Route::get('/playground', [PlaygroundController::class, 'index']);
And is loaded from my ServiceProvider class:
$this->loadViewsFrom(__DIR__.'/resources/views', 'playground');
loadRoutesFrom(__DIR__.'/routes.php');
My namespacing is also normally correctly written in the composer.json of my package:
"autoload": {
"psr-4": {
"TestVendor\\TestPackage\\": "src/"
}
},
And I have my PlaygroundController in src/Http/Controllers/PlaygroundController.php:
namespace TestVendor\TestPackage\Http\Controllers;
use Illuminate\Routing\Controller;
class PlaygroundController extends Controller
{
public function index()
{
return view('playground::hello');
}
}
The view is also in the right package.
I'm using https://github.com/Jeroen-G/laravel-packager to scaffold my packages.
Did multiple composer auto-load and composer updates.
It seems my controller is not recognized in the main application, I think somewhere my name spacing is not correct?
I already had a look at:
Target class controller does not exist - Laravel 8
Solution did not work
Target class does not exist. problem in laravel 8
Solution did not work
You have namespaced your controller as:
namespace TestVendor\TestPackage\Http\Controllers;
In the line above though you say:
And I have my PlaygroundController in src/Http/PlaygroundController.php:
Unless that is a typo, you need to add a Controllers directory underneath Http and put your PlaygroundController in there:
src/Http/Controllers/PlaygroundController.php
For psr-4 autoloading, your folder structure and namespaces should mimic each other.

Autoload PHP Classes using Composer

I am trying for the first time to autoload PHP Classes using Composer.
I have this dir structure:
-app
-controllers
-models
-MySql.php
-interfaces
-IDatabase.php
My problem is that I am not able to implement the IDatabase interface in my MySql class. It gives me: Fatal error: Interface 'App\Models\I\IDatabase' not found.
composer.json
{
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
}
IDatabase.php
namespace App\Models\I;
interface IDatabase
{
public function connect();
public function execute($query,$param);
}
Mysql.php
namespace App\Models;
use App\Models\I\IDatabase;
class MySql implements IDatabase
{
...
}
What am I doing wrong? I can't figure it out. Thanks.
It looks like
App\Models\I\IDatabase
Should be
App\Models\Interfaces\IDatabase
You can't abbreviate the directory name.
Also as I said in the comments
Casing is important! app vs App, etc. or app\models\interfaces\IDatabase It's probably mainly this one I vs interfaces but Casing will get you on Linux.
So you can either change the directories to be uppercase, or you can change the namespace to be lower cased (but they should be the same).
On windows this may work with the case issues, because windows filesystem is case insensitive. But as soon as you put that on Linux which is case sensitive, well it's not gonna work out to good.
Cheers!
Namespaces should follow the exact directory structure, and are case sensitive.
If your Interface is in the directory app\models\interfaces, the namespace should be App\models\interfaces. App in your case can be with capital A because you explicitly mapped it in the composer.json.
So you can either rename the folders or fix the namespace.
Also, you cannot give custom name to the namespaces (i.e. I in App\Models\I). As I stated before, the namespace must follow the directory structure, unless you create a specific mapping in the composer.json

Vendor Bundle failed to load

I searched for hours to solve my problem, but now I just don't know what to check anymore..
I created a new project for composer: https://github.com/Gcob/esvit-ng-table-for-symfony
Everything is fine until it comes to the appKernel.php, I declarate my new freshly downloaded from composer bundle like this: new Gcob\NgTableBundle\GcobNgTableBundle(), but I got an error message:
ClassNotFoundException in AppKernel.php line 23:
Attempted to load class "GcobNgTableBundle" from namespace "Gcob\NgTableBundle".
Did you forget a "use" statement for another namespace?
I don't know exacly how the appKernel finds its bundles, but I know that the namespace is important and the filename too, so my file GcobNgTableBundle.php has the namespace namespace Gcob\NgTableBundle; and the class declaration is class GcobNgTableBundle extends Bundle as it should be.
Is there any place I should tell the kernel that the file GcobNgTableBundle.php exists for vendor bundles? If some one got any idea, please tell me, but don't forget that I tried a lot of stuff ( first time asking question o_O )
You need to change your composer and add an autoload part.
Without it, namespaces can fail. Check documentation for details.
It must be similar to this:
"autoload": {
"psr-4": { "Symfony\\Bundle\\EsvitNgTableBundle\\": "" }
},
Check this one for example.
After a lot of wasted time, I understood :P The answer of mim was in the good direction! I learned here how composer namespaces works. The appKernel in Symfony only loads the composer file "vendor/composer/autoload_namespaces.php" to load FAKE namespaces xD.

Laravel/Composer: The use statement with non-compound name

In my laravel project I created a model called CustomerLinks. The model resides in the app/models folder. My composer file has an autoload of:
"autoload": {
"classmap": [
...
"app/models",
...
],
...
},
And I have a use statement in my ExtendedUserController that references CustomerLinks:
<?php
...
use CustomerLinks;
...
class ExtendedUserController extends UserController {
It's my understanding that since the autoload property in the composer file has app/models in the classmap it means I should be able to use use CustomerLinks without a namespace prefix.
This works, but any time I make a change to my ExtendedUserControler and reload my browser I get the error:
The use statement with non-compound name 'CustomerLinks' has no effect
The error points to the use CustomerLinks line extended user controller.
When I do a composer dump-autoload everything works fine, but it becomes extremely irritating when I have to follow the pattern
make a change -> dump autoload -> refresh browser -> repeat
Is there some way of dealing with the error?
If you are not within a namespace (i.e. you are in the root namespace), and the class you want to use also is not in a namespace (i.e. also in the root namespace), then using use makes no sense, because the code will work the same without it. You are not importing anything with this statement.
Composer has nothing to do with this, neither has any other autoloading. It's how PHP works by itself.

Categories