1
votes

I am using 3 packages in my Laravel 5.8 application:

These are clashing because Backpack Base relies on the Global Alias for "Alert" being set to use PrologueAlert. See an example of how it uses \Alert here:

private function checkLicenseCodeExists()
{
    if ($this->app->environment() != 'local' && !config('backpack.base.license_code')) {
        \Alert::add('warning', "<strong>You're using unlicensed software.</strong> Please ask your web developer to <a target='_blank' href='http://backpackforlaravel.com'>purchase a license code</a> to hide this message.");
    }
}

Source: https://github.com/Laravel-Backpack/Base/blob/1.1.4/src/BaseServiceProvider.php#L264

Because I haven't bought that license yet I started seeing an error caused because that above snippet was trying to pass a string to Alert::add() but it was calling the add() method on Styde\Html\Alert\Container::add() which expects the parameter to be an instance of Styde\Html\Alert\Message instead of calling it on Prologue's version of Alert which accepts a string. It's calling the wrong "Alert"!

Even though my application is specifically set to use PrologueAlert for Alert

// config/app.php

'aliases' => [
    ...
    'Alert' => Prologue\Alerts\Facades\Alert::class
]

I have discovered the reason is that in version 1.7 Styde moved the Aliases for his package from the protected $globalAliases variable on HTMLServiceProvider.php to the composer.json auto-discover section

"extra": {
    "laravel": {
        "providers": [

        ],
        "aliases": {
            "Field": "Styde\\Html\\Facades\\Field",
            "Alert": "Styde\\Html\\Facades\\Alert",
            "Menu": "Styde\\Html\\Facades\\Menu",
            "Form": "Collective\\Html\\FormFacade",
            "Html": "Collective\\Html\\HtmlFacade"
        },
        "dont-discover": [
            "laravelcollective/html"
        ]
    }
}

Source: https://github.com/StydeNet/html/commit/f51138fb42bef458f3f0e101b98344162b7327ba#diff-b5d0ee8c97c7abd7e3fa29b9a27d1780

Now, it seems my application is prioritising Styde's alias of "Alert" over my own application-set value!

Other than rolling back to use version 1.6 of Styde, how can I force Laravel to prioritise my own defined aliases over ones discovered via the composer.json?

1

1 Answers

4
votes

I found the solution! It was actually inspired by a snippet in my original post.

You can add an extra section to your application's composer.json that get read by the Laravel application and used to decide which packages to ignore during auto-discover like this:

// composer.json
{
    ...
    "extra": {
        "laravel": {
            "dont-discover": [
                "styde/html"
            ]
        }
    }
}

This then allows you to pick and choose aliases from the problematic package and define as many or as few of the them as you like in your config/app.php (for my application I was only using the Field alias from Styde/Html so that was the only one I had to add to my App config).

I think as more and more package maintainers start leveraging the auto-discover feature this is going to become a more widely used feature.

Afterthought: This is a shift in the relationship between Composer and Laravel. Whereas the composer.json file was traditionally just a package manager that would be run at installation and then not used when the application is running, it is now a config file that is read by the application. I learned this the hard way as our pipeline that packages-up and deploys the code used to tidy up files that weren't required in the production environment. It was deleting composer.json which started the error happening again in our QA environment.