The Controller is part of the Model-View-Controller software design pattern.
The Controller acts as the gateway for taking in a user’s request, collecting the data from a Model, and passing it along to the appropriate View.
Example: User Controller
A request to view the UserDetails
page would first hit the
UserController
, which might look something like this:
/**
* Route to view the userDetailsPage.
* @Route("/{_semester}/{_course}/show_user_details", methods={"GET"})
* @AccessControl(role="INSTRUCTOR")
**/
public function userDetailsPage($user_id) {
$user = $this->core->getQueries()->getUserFromId($user_id);
if ($user) {
return new WebResponse(
"\app\views\user\UserView::class"
'showUserDetails',
$user
)
);
} else {
// render an error
}
}
From the website, they can now make a request which routes to the
userDetails
page. Something like
f20/sample/show_user_details?user_id="aphacker"
Because we added @AccessControl(role="INSTRUCTOR")
, only instructor
level users can access this page.
The $user_id
parameter to our function is populated from the
parameters of the GET request ?user_id="aphacker
.
When we call $this->core->getQueries()->getUserFromId($user_id);
a
database query is run which loads information for the user with a
matching id into a UserModel
. See also the Model documentation.
Returning a MultiResponse / WebResponse
If $user
was successfully loaded (it’s not null), we can render the
page by returning a new MultiResponse object which contains a
WebResponse.
-
The first parameter of the WebResponse is the path to
UserView
. In this case it issite/app/views/user/UserView
. Submitty automatically preppendssite/app/views
and adds the wordView
to the end of the last element in this array. -
The second parameter is the name of the function that we want to call in the
UserView
. In this caseshowUserDetails
. -
Subsequent parameters are the inputs to the
showUserDetails
function. -
If
$user
didn’t load correctly (it is null), we have to return some error page. This is omitted.
See more information in the View documentation.
Disabling a Controller
There are certain circumstances where a controller should be disabled
completely depending on if a feature is enabled or not within the Config.
To do this, you can utilize the
Enabled
annotation in the docstring for the controller class, like so:
use app\libraries\routers\Enabled;
/**
* @Enabled("forum")
*/
class ForumController {}
With this annotation in-place, the router will take the string value passed to
the annotation, run ucfirst
for it,
and then use that to call the is{$Feature}Enabled()
function in the Config modal. For the
above example, it would be calling isForumEnabled()
method. If that method returns false, we
show an access denied error screen to the user, directing them to contact their instructor
if they think it is an error, and then provide a link back to the course home page.