I followed tutorial on internet, and make it work. But still have to call the method. But we know that in LoginController, like showLoginForm(), login(), if you don'r add this, it still works, because it is defined in trait AuthenticatesUsers.
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
}
My own trait, have to call the method manually.
app\Traits\MenuTrait.php
<?php
namespace App\Traits;
use Illuminate\Http\Request;
trait MenuTrait {
public function getMenus()
{
$menus[] = [
'id' => 'menu-dashboard',
'icon' => 'fas fa-home',
'name' => 'Dashboard',
'href' => route('lang.admin.dashboard'),
'children' => []
];
...
app\Http\Controllers\Admin\DashboardController.php
...
use App\Traits\MenuTrait;
class DashboardController extends Controller
{
use MenuTrait;
public function index()
{
$data['menus'] = $this->getMenus();
return view('ocadmin.dashboard', $data);
}
How to make the trait method work without calling it?
CodePudding user response:
traits is used to reuse code, not to 'make it work without calling'
to make it work in your example you should do something like this
trait MenuTrait {
// note that function renamed to fit routes
public function index()
{
$menus[] = [
'id' => 'menu-dashboard',
'icon' => 'fas fa-home',
'name' => 'Dashboard',
'href' => route('lang.admin.dashboard'),
'children' => []
];
// ...
$data['menus'] = $menus;
return view('ocadmin.dashboard', $data);
}
then in conctoller you can skip function index
// ...
use App\Traits\MenuTrait;
class DashboardController extends Controller
{
use MenuTrait;
// no function index here as its in trait
// other functions
}
now when frontend hit route
Route::get('dashboard/menus/index', [DashboardController::class, 'index']);
php will go into DashboardController
and try to find method index
which is defined in MenuTrait
same things for LoginController
note that noone can stop you from overriding trait methods, but keep in mind that you will be able to use overrided methods only with some dancing around and most time you don't want to do this kind of stuff
// routes.php
Route::get('some_path/index', [GuestDashboardController::class, 'index']);
// ...
use App\Traits\MenuTrait;
class GuestDashboardController extends Controller
{
use MenuTrait;
public function index(){
if (random_int(100, 999) < 600){
abort(403, 'no luck, bro');
}
return view('view_name', ['message'=>"we lost trait's index function"]);
}
// other functions
}
summary: if you want to be able to get menus in differrent controllers - use your trait as is to not repeat code, if the only goal to 'call methods invisibly' - traits are not about it (to make controller cleaner put code into controller or service class or single action class)