Home > Software engineering >  Laravel conditionally load trait if class exists in package controller
Laravel conditionally load trait if class exists in package controller

Time:12-09

I've built a Laravel 8 package that's included in one of my Laravel projects, the package optionally can utilise functionality from another package, such as Traits, I'm conditionally loading these in my package's controller using PHP's class_exists but this throws the following error on line 22 of my controller:

syntax error, unexpected 'use' (T_USE)

My controller looks like:

<?php

namespace Stsonline\InboundManagement\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Controllers\Controller;
use Company\CorePackage\Models\Affiliates;
use Company\CorePackage\Models\Settings;

if (class_exists('Company\OptionalPackage\Traits')) {
    use Company\OptionalPackage\Traits\Proxy;
}

class UtilityController extends Controller
{
    if (class_exists('Company\OptionalPackage\Traits')) {
        use Proxy;
    }

    /**
     * Inbound Array
     *
     * Store private variables for use elsewhere.
     */
    public $inboundArray

    // ... functions below here

}

What am I missing? I need to pull in functions and functionality from files from another package only if it exists.

CodePudding user response:

Since this is a Laravel controller and you cant conditionally choose the instance that is created per request, you can create the following classes:

class UtilityController extends Controller {
   // Nothing used
}

class UtilityProxyController extends UtilityController  {
   use Proxy;

  // add utility controller functions that use the `Proxy` trait in this one
}

Then in web.php or api.php (or where you declare the routes) do:

// Add all `UtilityContoller` routes here
if (class_exists('Company\OptionalPackage\Traits\Proxy')) {
    Route::get('someroute/path', [ UtilityProxyController::class, 'handler' ]);
}

You can also make another "fallback" class for route handlers when the trait does not exist in case you don't want the default 404 response in those cases.

  • Related