eComEvo
eComEvo

Reputation: 12549

Laravel package trait not found

I'm developing a package and added a "Traits" dir to my PSR-4 structure and this is reflected in the package's composer.json.

{
    "name": "my-private-repo/prefs",
    "description": "Preferences package.",
    "type": "package",
    "keywords": [
        "prefs",
        "preferences"
    ],
    "require": {
        "php": ">=5.5.9",
        "illuminate/support": "5.2.*",
        "laravelcollective/html": "5.2.*",
        "anahkiasen/former": "~4"
    },
    "autoload": {
        "classmap": [
            "src/controllers",
            "src/models"
        ],
        "psr-4": {
            "MyPrivateRepo\\Prefs\\": "src/"
        },
        "files": [
            "src/Prefs/helpers.php"
        ]
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

Within the src/ dir is this structure:

Prefs/
    Traits/
        HasPrefs.php
    Prefs.php
    PrefsServiceProvider.php
    helpers.php

Here is the contents of HasPrefs.php:

namespace MyPrivateRepo\Prefs\Traits;

use MyPrivateRepo\Prefs\Prefs;

trait HasPrefs
{
    public function prefs($key = null, $value = null)
    {
        //...do pref related stuff here...
    }
}

I've loaded the private project up and everything was working great when calling the Prefs class directly. Then I decided to test adding HasPrefs trait to my User model:

namespace App;

use Cartalyst\Sentinel\Users\EloquentUser;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use MyPrivateRepo\Prefs\Traits\HasPrefs;

class User extends EloquentUser implements
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract
{
    use SoftDeletes,
        Authenticatable,
        Authorizable,
        HasPrefs,
        CanResetPassword;

    //...do lots of user related stuff here...
}

Now, every time I try to do anything, I'm given this error:

[Symfony\Component\Debug\Exception\FatalErrorException]
Trait 'MyPrivateRepo\Prefs\Traits\HasPrefs' not found

I then did composer update but got the same error as above when it reaches the scripts section that runs php artisan optimize.

I commented out the references to HasPrefs in User and re-ran artisan optimize which worked without issue.

Uncommented HasPrefs and all is working as expected with no errors...until the next time I need to run composer update again on the project. Then, I am right back to having to comment out references to HasPrefs again and manually run artisan optimize.

Given that this is something that needs to be deployed to a production server, I can't be manually editing every file that uses this trait every time there is a composer update or composer install triggered by an auto-deploy.

I've tried the following to resolve this to no success:

All it takes is a single call to composer update to break it all over again if any of the above temporarily fixed the issue.

Any ideas what is wrong here?

Upvotes: 3

Views: 2982

Answers (1)

Filip Koblański
Filip Koblański

Reputation: 9988

As you can see here:

"psr-4": {
    "MyPrivateRepo\\Prefs\\": "src/"
},

You point src dir as MyPrivateRepo\Prefs namespace. So when you want to use this trait in the dir named Traits your namespace should go like:

MyPrivateRepo\Prefs\Prefs\Traits

because you have a Prefs also, so your use statement in this trait will looks like:

 use MyPrivateRepo\Prefs\Prefs\Prefs;

My advice is to change the composer's entry for:

"psr-4": {
    "MyPrivateRepo\\": "src/"
},

Upvotes: 5

Related Questions