Controllers

Controllers

Instead of defining all of your request handling logic as Closures in routes/web.php file, you may want to organise them using Controller classes.

Controllers

Controllers are stored in the app/Controllers directory by default but in yuga, everything is configurable which means you can put them in app/AnyFolder and map them to the appropriate namespace

Defining Controllers

Below is an example of a basic controller class. Note that the controller extends the base controller class that comes with Yuga. The base class provides a few convenience methods such as the middleware method, which can be used to attach middleware to controller methods:

<?php
namespace App\Controllers;
use Yuga\Controllers\Controller;
use App\ViewModels\UsersViewModel;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return UsersViewModel
*/
public function show($id)
{
return new UsersViewModel($id);
}
}

The route that corresponds to this controller is as below:

Route::get('user/{id}', '[email protected]');

Controllers are not required to extend the base controller but if you don't, you will not have access to important methods like middleware and many others.

Constructor Injection

The Yuga service container is used to resolve all Yuga controllers. As a result, you are able to type-hint any dependencies your controller may need in its constructor. The declared dependencies will automatically be resolved and injected into the controller instance:

<?php
namespace App\Controllers;
use App\Models\Post;
use Yuga\Controllers\Controller;
class UserController extends Controller
{
/**
* The posts model instance.
*/
protected $posts;
/**
* Create a new controller instance.
*
* @param Post $post
* @return void
*/
public function __construct(Post $post)
{
$this->posts = $post;
}
}

You can also type-hint any Yuga classes and interfaces If the container can resolve them, you can type-hint them.

Method Injection

In addition to constructor injection, you can also type-hint dependencies on your controller's methods. A common use-case for method injection is injecting the Yuga\Http\Requestinstance into your controller methods:

<?php
namespace App\Controllers;
use Yuga\Http\Request;
use Yuga\Controllers\Controller;
class UserController extends Controller
{
/**
* Store a new post.
*
* @param Request $request
* @return Response
*/
public function save(Request $request)
{
$name = $request->get('name');
}
}

If your controller method is also expecting input from a route parameter, list your route arguments any where with other dependencies, remember, Route parameters are injected into route callbacks / controllers based on their names in the Route defined, the order of getting them in callback / controller does not matter. For example, if your route is defined like so:

Route::put('user/{id}', '[email protected]');

You may still type-hint the Yuga\Http\Request and access your id parameter by defining your controller method as follows:

<?php
namespace App\Controllers;
use Yuga\Http\Request;
class UserController extends Controller
{
/**
* Save a given user.
*
* @param Request $request
* @param int $id
* @return Response
*/
public function save(Request $request, $id)
{
// your code
}
}

OR, like so:

<?php
namespace App\Controllers;
use Yuga\Http\Request;
class UserController extends Controller
{
/**
* Save a given user.
*
* @param int $id
* @param Request $request
* @return Response
*/
public function save($id, Request $request)
{
// your code
}
}

Route parameters are injected into route callbacks / controllers based on their names in the Route defined, the order of getting them in callback / controller does not matter.

Creating Controllers using yuga console command

Controllers can be created using the php yuga make:controller command

i.e php yuga make:controller UsersController would produce the following scaffold:

<?php
namespace App\Controllers;
use Yuga\Http\Request;
use Yuga\Http\Response;
use Yuga\Http\Redirect;
class UsersController extends Controller
{
/**
* Create a new UsersController instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
}