Responses
When the router hands an HTTP request to a controller and invokes it, it expects the controller, after performing the necessary processing, to ultimately return an object of the packages\base\Response class.
A response can be a web page, a file, data in JSON or XML form, or plain text.
In Jalno, the packages\base\Response class was created for working with responses. The methods listed below are defined in this class. To work with the Response class, you need to create an object of it. You can also use the response property of the controller class, which already holds an object of the Response class.
You can specify the status of a response when creating the Response object.
The status value is false by default.
use packages\base\Response;
$response = new Response(true);
| Method | Purpose |
|---|---|
| is_ajax(): bool | Indicates whether the request is of AJAX type |
| is_api(): bool | Indicates whether the request is of API type |
| setView(View $view): void | Sets the View |
| getView(): ?View | Returns the specified View object |
| setFile(File $file): void | Sets a file |
| setStatus(bool $status): void | Sets the response status |
| getStatus(): bool | Returns the response status |
| setData(mixed $data, string $key): void | Sets data |
| getData(string $key): mixed | Returns the data that has been set |
| json(): string | Returns the response status and the data that has been set in JSON format |
| go(string $url): void | Redirects the user |
| rawOutput(string $output): void | Prints text to the output |
| setHeader(string $key, string $value): void | Sets header fields |
| setHttpCode(int $code): void | Specifies the response status code |
| setMimeType(string $type, ?string $charset = null): void | Sets the content-type and charset fields in the header |
| forceDownload(): void | Specifies that the file that has been set is meant for download |
Web Pages
If you have an object of the View class and want to display it to the user, use the setView method of the Response class; the framework will show it to the user once the controller has finished executing.
Example 1
<?php
namespace packages\packagename\controllers;
use themes\themename\views;
use packages\base\{Controller, Response, View};
class Main extends Controller {
public function index(): Response {
$view = View::byName(views\Index::class);
$response = new Response(true);
$response->setView($view);
return $response;
}
}
Example 2
<?php
namespace packages\packagename\controllers;
use themes\theme\views;
use packages\base\{Controller, Response, View};
class Main extends controller {
public function index(): Response {
$view = View::byName(views\Index::class);
$this->response->setStatus(true);
$this->response->setView($view);
return $this->response;
}
}
Files
Responses can be files, and files can either be downloaded (such as compressed archives, applications, and so on) or displayed to the user immediately (such as images or audio and video files).
For this purpose, you can use the setFile method of the Response class.
If you want the file to only be downloadable and not displayed in the browser (such as audio and video files), you must call the forceDownload() method of the Response class. When this method is called, the content-disposition field in the header is set to the value attachment, and the file is no longer opened in the browser.
The details of the file given to the user must be specified; this is done using the methods of the packages\base\response\File class.
Example 1
<?php
namespace packages\packagename\controllers;
use packages\packagename\Ticket;
use packages\base\{Controller, Response, NotFound};
class Main extends controller {
public function getTicketFile($data): Response {
$file = Ticket\File::byId($data['id']);
if (!$file) {
throw new NotFound();
}
$response = new Response();
$responsefile = new Response\File();
$responsefile->setLocation($file->path);
$responsefile->setSize($file->size);
$responsefile->setName($file->name);
$response->setFile($responsefile);
$response->setStatus(true);
return $response;
}
}
Example 2
<?php
namespace packages\packagename\controllers;
use packages\packagename\File as Model;
use packages\base\{Controller, Response, NotFound, Packages};
class Main extends controller {
public function download($data): Response {
$file = Model::byId($data['id']);
if(!$file) {
throw new NotFound();
}
$file = Packages::package('packagename')->getFile($file->path);
$responsefile = new response\File();
$responsefile->setLocation($file->getPath());
$responsefile->setSize($file->size());
$this->response->forceDownload();
$this->response->setFile($responsefile);
$this->response->setStatus(true);
return $response;
}
}
Responding to Ajax and API Requests
If you send a request from the browser and need the server to return the required information in JSON or XML form, you must use the setData($data, $key) method of the Response class.
This function receives, in its first parameter, the item value (which can be of any data type), and in its second parameter (which must be a string), the key for that value.
When the framework receives the value ajax=1 or api=1 in the URL Parameter, it sends these values to the browser.
By calling the getData method, you can access the data that has been set. The input parameter of this method is the data key. If no parameter is passed to getData, it returns an array of the data that has been set.
Example 1
<?php
namespace packages\packagename\controllers;
use packages\packagename\state;
use packages\base\{Controller, Response};
class API extends controller {
public function getCities($data): Response {
$response = new Response(true);
$city = new state\City();
$city->where("state", $data["state"]);
$city->orderBy("title_fa", "ASC");
$city->ArrayBuilder();
$response->setData($city->get(null, ["id", "title_fa"]), "cities");
return $response;
}
}
Example 2
<?php
namespace packages\packagename\controllers;
use themes\themename\views;
use packages\base\{Controller, Response, View};
class Dashboard extends controller {
public function forbidden(): Response {
$this->response->setStatus(false);
$this->response->setHttpCode(403);
$view = View::byName(views\Forbidden::class);
$this->response->setView($view);
if ($this->response->is_api()) {
$this->response->setData("forbidden", "error");
}
return $this->response;
}
}
Printing Text as Output
Sometimes the response you send may not be a web page or a file, and you may want to display only some text to the user. In this case, by calling the rawOutput method, you can display the desired text to the user. The input argument of this method is the desired string.
Example
<?php
namespace packages\packagename\controllers;
use packages\base\{Controller, Response, HTTP};
class Dashboard extends Controller {
public function checkAccess(): Response {
if (Http::$client["ip"] == "127.0.0.1") {
$this->response->setStatus(false);
$this->response->setHttpCode(403);
$this->response->rawOutput("<h1>403 Forbidden page</h1>");
}
return $this->response;
}
}
Redirecting the User
Consider a case where the user has submitted the site's login form to the server and the controller concludes that the entered information is correct; now it is time to move the user to the user panel. Or you may need to send the user to a payment gateway to pay an invoice. In these situations, you need to move the user from one address to another, and this can be done with the Go method of the Response class. Whatever address you enter in the single parameter of this function, the user will be redirected to that address.
For more information about addressing, refer to the URL Generation page.
Example
<?php
namespace packages\packagename\controllers;
use themes\themename\views;
use function packages\base\url;
use packages\packagename\User;
use packages\base\{Controller, Response, View, InputValidationException};
class Main extends controller {
public function login(): Response {
$view = View::byName(views\Login::class);
$this->response->setView($view);
$inputRules = array(
"username" => array(
"type" => "email",
),
"password" => array()
);
$inputs = $this->checkinputs($inputRules);
$user = new User();
$user->where("email", $inputs["username"]);
$user->where("password", md5($inputs["password"]));
$user = $user->getOne()
if (!$user) {
throw new InputValidationException("username");
}
$this->response->setStatus(true);
$this->response->Go(url("userpanel"));
return $this->response;
}
}
Response Status
The setStatus method is defined for specifying the response status; the input of this method is a boolean.
Calling the getStatus() method returns the status that has been set.
The response status is more important when responding to API and Ajax requests.
Example
<?php
namespace packages\packagename\controllers;
use packages\packagename\User;
use packages\base\{Controller, Response};
class Users extends controller {
public function getUser($data): Response {
$user = User::byId($data['id']);
$this->response->setStatus(false);
if ($user) {
$this->response->setStatus(true);
$this->response->setData($user, "user");
}
return $this->response;
}
}
Setting the Status Code
Every response that is sent has a status code. In Jalno, you can specify the status code by calling the setHttpCode($code) method.
The example below checks whether the sent request is of type Ajax or API and, if so, sets its status code to 401.
Example
<?php
namespace packages\packagename\controllers;
use packages\base\{Controller, Response};
class Dashboard extends controller {
public function authError(): Response {
$this->response->setStatus(false);
if ($this->response->is_ajax() or $this->response->is_api()) {
$this->response->setHttpCode(401);
}
return $this->response;
}
}
Setting Header Fields
In Jalno, the setHeader($key, $value) method is defined for setting header fields. This method takes the field name in its first parameter and the field value in its second parameter.
Example
<?php
namespace packages\packagename\controllers;
use themes\themename\views;
use packages\packagename\Post;
use packages\base\{Controller, Response, View, NotFound};
class News extends controller {
public function post($data): Response {
$post = Post::byId($data['id']);
if(!$post) {
throw new NotFound();
}
$view = View::byName(views\news\Post::class);
$this->response->setView($view);
$view->setData($post, "post");
$this->response->setHeader("author", $post->author);
return $this->response;
}
}