Title: Controllers Description: Controllers define how a resource is created, updated, read, deleted or take any action.
There are four Galaxy CLI commands "directives" for making a controller: base
, thin
, post
, and term
. You can also create a controller manually using the example code to follow.
base
- Make a base controller with the methodsindex
,add
,create
,edit
,update
,show
,delete
, anddestroy
.thin
- Make a base controller with no methods.post
- Make a controller with no methods extending theWPPostController
.term
- Make a controller with no methods extending theWPTermController
.
Take a look at making a base
controller with a model.
php galaxy make:controller -m base Person
Will product a basic thin controller class, see below, but with these predefined methods: index
, add
, create
, edit
, update
, show
, delete
, and destroy
. If you use the thin
directive, these methods will not be created.
php galaxy make:controller -m thin Person
Will produce app/Controllers/PersonController.php
,
<?php
namespace App\Controllers;
use \TypeRocket\Controllers\Controller;
class PersonController extends Controller
{
}
Note: To manually create a controller, you can use the example above as your template example.
The WPPostController
is used for working with post types. Because the WPPostController
automatically has create()
, update()
, and destroy()
methods, you do not need to worry about custom post types if you make a controller extending this class.
To make a post controller use the Galaxy CLI.
php galaxy make:controller -m post Person
Will produce app/Controllers/PersonController.php
,
<?php
namespace App\Controllers;
use \App\Models\Person;
use \TypeRocket\Controllers\WPPostController;
class PersonController extends WPPostController
{
protected $modelClass = Person::class;
}
Because WordPress does not use an MVC architecture TypeRocket spoofs this design pattern for you when a post is updated on the edit and add post pages. In fact, TypeRocket spoofs this anytime the save_post
action is called to ensure consistency.
The WPTermController
is for working with taxonomy terms. Because the WPTermController
automatically has create()
, update()
and destroy()
methods, you do not need to worry about taxonomy terms if you make a controller extending this class.
To make a term controller use the Galaxy CLI.
php galaxy make:controller -m term Person
Will produce app/Controllers/PersonController.php
,
<?php
namespace App\Controllers;
use \App\Models\Person;
use \TypeRocket\Controllers\WPTermController;
class PersonController extends WPTermController
{
protected $modelClass = Person::class;
}
Because WordPress does not use an MVC architecture TypeRocket spoofs this design pattern for you when a term is updated on the edit and add taxonomy term pages. In fact, TypeRocket spoofs this anytime the create_term
or edit_term
action is called to ensure consistency.
There are times when you do not want the global resource middleware stack to be called for specific methods of a controller by the kernel. To dynamically set the middleware stack use the __construct()
method on a controller and the addMiddleware()
method.
For example, take a member controller where you want to have different middleware for the login methods.
<?php
namespace App\Controllers;
class MemberController extends Controller
{
public function __construct()
{
$this->addMiddleware('not_member', ['only' => ['login', 'login_verify']]);
}
/*
* When this method is called the "not_member"
* middleware group stack will be called by the
* kernel.
*/
public function login()
{
return tr_view('members.login');
}
public function login_verify()
{
$redirect = tr_redirect();
if( $id = auth_verify() ) {
$redirect->toUrl( home_url('/members/' . $id ));
} else {
$redirect->back();
}
return $redirect;
}
// ...
}
In the Kernel
the middleware might have these settings.
class Kernel extends \TypeRocket\Http\Kernel
{
protected $middleware = [
'hooks' => [],
'http' => [ VerifyNonce::class ],
// ...
'not_member' => [
Middleware\Nonmember::class
],
];
}
The addMiddleware()
method must be called from the controllers __constructor()
method and takes two arguments:
$group
- The middleware group to call from the kernel.$settings
- An array of settings defining theonly
orexcept
methods to call in the middleware group.
Only call the not_member
middleware group on the login
and login_verify
controller methods.
$this->setMiddleware('not_member', ['only' => ['login', 'login_verify']]);
Call the is_member
middleware group on all methods but the login
and login_verify
controller methods.
$this->setMiddleware('is_member', ['except' => ['login', 'login_verify']]);
To start working with controllers. You need to understand the MVC design pattern. To help you get started, let's take a look at a simple public JSON API built using MVC and TypeRocket.
For this example, we will create an endpoint that lists the latest published posts in WordPress. In the TypeRocket routes/public.php
file add a route to the URL /posts/published/latest/
for any GET requests. Then, point that route to a method on the ApiController
.
tr_route()->get()->match('/posts/latest/')->do('latest@Api');
When a user visits the URL http://example.com/posts/published/latest/
it will call the latest()
method on the ApiController
in the app/Controllers/
folder. Let's create the ApiController
and implement latest()
method now.
php galaxy make:controller -m thin Api
In the newly created controller, add the method latest()
.
<?php
namespace App\Controllers;
use App\Models\Post;
use TypeRocket\Controllers\Controller;
class ApiController extends Controller
{
public function latest() {
$latest = (new \App\Models\Post)->published()->take(10)->get();
return $latest;
}
}
Because we are returning an array
TypeRocket will format the view as JSON.
You can also secure the method using model policies accessed by the can()
method.
public function latest(\TypeRocket\Models\AuthUser $user) {
$post = new \App\Models\Post;
// only logged-in users who can create a post
// can also view the JSON API
if(!$post->can('write', $user)) {
tr_abort(401);
}
return $post->published()->take(10)->get();
}
Note: Be sure to take the security of your site into account when making public APIs.
Also, you can create a much simpler JSON API using just the route. This required no controller, middleware, or kernel setup.
This example will have the same net result as the controller example.
tr_route()->get()->on('/posts/latest/', function() {
return (new \App\Models\Post)->published()->take(10)->get();
});