Skip to content

Latest commit

 

History

History
260 lines (210 loc) · 7.28 KB

File metadata and controls

260 lines (210 loc) · 7.28 KB

Controller & Methods

Controllers are the central building blocks of your application’s logic.
Each controller handles incoming requests, processes data, and determines which views or responses should be returned to the client.
Controllers must extend the Controller class to access all necessary methods and properties.

Passing Data to Templates

Controllers can pass data to view files by setting values on the Response object:

<?php
// Example URL: yourdomain.tld/animals/tiger/indo-chinese
class AnimalController extends Controller {
	public function index(): void {
		$this->response->data["pageTitle"] = "Welcome to Umbrella Corp!";
		$this->response->setTitle("Welcome!");
		$this->response->setView("welcome-page");
	}
}

In the above example, the string Welcome to Umbrella Corp! will be available as $pageTitle in the view:

<!-- welcome-page.tpl.php -->
<h1><?php print $pageTitle; ?></h1>

A view must be set by each controller using the setView method:

class AnimalController extends Controller {
	public function index(): void {
		$this->response->setView("animal-index");
	}
}

The setTitle method is a shortcut for setting a title key in the response data array.
By default, $title is used by the provided header partial in the <title> tag.

Child Controllers

Controllers can specify child controllers to be executed after the parent controller:

<?php
class AnimalController extends Controller {
	public function index(): void {
		$this->children[] = "TigerController";
	}
}

In this example, TigerController will be invoked after AnimalController.
Only the index method is called on child controllers.
Response data set by a parent controller is accessible and modifiable by its children.

Rerouting with StatusCode Exceptions

Controllers can throw StatusCode exceptions to reroute the request stack to a different status code controller.

The following exceptions are available:

Exception HTTP Code Use Case
\Core\StatusCode\BadRequest 400 Malformed or invalid request data
\Core\StatusCode\Unauthorized 401 Authentication required
\Core\StatusCode\Forbidden 403 Access denied for authenticated users
\Core\StatusCode\NotFound 404 Resource or path does not exist
\Core\StatusCode\NotAcceptable 406 Request format not supported

Example:

<?php

class UserController extends \Controller {
	public function profile(): void {
		// Check if user is authenticated
		if (!$this->isAuthenticated()) {
			throw new \Core\StatusCode\Unauthorized();
		}

		// Check if user has permission
		if (!$this->hasPermission("view_profile")) {
			throw new \Core\StatusCode\Forbidden();
		}

		// Validate input
		if (empty($_GET["id"])) {
			throw new \Core\StatusCode\BadRequest();
		}

		// Continue with normal processing
		$this->response->setView("user/profile");
	}
}

When a StatusCode exception is thrown, the framework automatically routes the request to the corresponding status code controller (e.g., UnauthorizedController, ForbiddenController, etc.).

Namespaced Controllers

Note

Namespaced controllers are not routeable.
Meaning they will become inaccessible by URL and CLI.

Controllers can be namespaced for partials and complex structures.
For example, you can use namespaces like Partial or StatusCode:

<?php
class PageController extends Controller {
	public function index(): void {
		// Add partials as child controllers
		$this->children[] = new ClassName("Partial\Alerts");
		$this->children[] = new ClassName("Partial\Sidenav");
	}
}

Example namespaced controllers:

<?php

namespace Partial;

class AlertsController extends \Controller {
	public function index(): void {
		$view = $this->template->getViewPath("partials/alerts");
		$this->response->data["alerts"] = $view;
	}
}
<?php

namespace Partial;

class SidenavController extends \Controller {
	public function index(): void {
		$view = $this->template->getViewPath("partials/sidenav");
		$this->response->data["sidenav"] = $view;
	}
}

This assumes you have view files like alerts.tpl.php in a partials folder.
See Template and theming for more details.

Inherited Controller Properties

Controllers extending the base Controller class inherit several pre-wired properties for routing, templating, content negotiation, and more.
These are set automatically and should not be manually overwritten.

$parent

  • Type: null|\Controller
  • Description: Reference to the parent controller, if any.
  • Usage Example:
    if ($this->parent instanceof \AuthController) { /* ... */ }
    if ($this->parent === null) { /* top-level controller */ }

$request

  • Type: \Core\Request
  • Description: Represents the current HTTP request (GET, POST, files, cookies, etc.).
  • Usage Example:
    $this->request->get;
    $this->request->post;
    $this->request->files;
    $this->request->cookies;
    $this->request->server;

$response

  • Type: \Core\Response
  • Description: Handles output data and headers.
  • Usage Example:
    $this->response->data['title'] = 'My Page';
    $this->response->setStatusCode(404);

$application

  • Type: \Core\Application
  • Description: The root application instance.
  • Usage Example:
    $this->application->getExecutedClassName();
    $this->application->getCalledMethodName();

$router

  • Type: \Core\Router
  • Description: Manages routing state and request/response resolution.
  • Usage Example:
    $path = $this->router->getRoute();

$template

  • Type: \Core\Template
  • Description: Handles asset injection and layout template resolution.
  • Usage Example:
    $view = $this->template->getViewPath("partial/sidenav");
    $path = $this->template->getDirectoryUri("assets/img/logo.png");

$assets

  • Type: \Core\Assets
  • Description: Manages asset registration and injection (CSS, JS, images).
  • Usage Example:
    $this->assets->addStylesheet("assets/css/styles.css");
    $this->assets->addJavascript("assets/js/app.js");

$contentType

  • Type: \Core\ContentType\ContentTypeInterface
  • Description: Holds the negotiated content type (HTML, JSON, XML, etc.).
  • Usage Example:
    if ($this->contentType::class === \Core\ContentType\Html::class) {
        // Render HTML
    }

$renderer

  • Type: \Core\Renderer
  • Description: Combines response data, template, and content type into output.
  • Usage Example:
    $this->renderer->render($this->response);

$children

  • Type: array
  • Description: List of child controllers to execute after the main one (used for layouts/partials).
  • Usage Example:
    $this->children[] = new ClassName('Partial\\Sidebar');

Accessors / Getters

While the above properties are protected and can be access by inheritance, they each have a corresponding getX() method:

  • getRequest()$request
  • getResponse()$response
  • getApplication()$application
  • getRouter()$router
  • getTemplate()$template
  • getChildren()$children
  • getParent()$parent