-
Notifications
You must be signed in to change notification settings - Fork 0
06. Controllers
With controllers, you can provide the custom logic of your application. Videna framework provides four pre-cooked controllers that can be parents for your custom controllers:
- HTTP controller
\Videna\Controllers\HttpController
handles HTTPPOST
andGET
requests to provide static and dynamic pages. - Application controller
\Videna\Controllers\AppController
handles requests to provide RESTful services. - Web API controller
\Videna\Controllers\ApiController
handles requests to provide API. - Cron job controller
\Videna\Controllers\CronJob
is responsible for cron jobs via command line or HTTP requests (test mode).
HTTP controller \Videna\Controllers\HttpController
handles HTTP requests to provide static and dynamic pages.
- handles 'POST' and 'GET' request methods;
- for 'POST' method provides CSRF protection via double submit cookies pattern;
- automatically provides a synchronizer token pattern for each active user session.
If you need to provide some logic before rendering the dynamic page or view, you may use the controller inherited from the HttpController
parent controller. Here is a step-by-step logic:
- Add the route with URL template, controller and action names in the file
/App/configs/routs.php
, for example:
use \Videna\Core\Route;
...
Route::get('/show-books', 'Tasks@ShowBooks');
In the example above we have assigned URL /show-books
(will be caught by HTTP request method GET
) with the controller Tasks
and action ShowBooks
.
- Create the controller
Tasks
that is inherited from theHttpController
controller and should be located in the folder/App/Controllers/
. The file name should match your controller name, for example, the controllerTasks
should be in the file:/App/Controllers/Tasks.php
. Also, the namespace should match the controller folder. In our case:
<?php
/**
* file: '/App/Controllers/Tasks.php'
*/
namespace App\Controllers;
class Tasks extends \Videna\Controllers\HttpController
{
}
- In the class body create the action
ShowBooks
by adding the prefix 'action' to the controller name:
public function actionShowBooks()
{
// your logic will be here
}
- Add the logic you need, set parameters you want to pass to the view, and set the view that needs to be shown, for example:
public function actionShowBooks()
{
// your logic will be here
// ...
// Pass parameters you need:
View::set([
'param' => $someVariable,
]);
// Set the view that needs to be shown
View::setPath('admin/dashboard.php');
}
Read more about how to create views in the section 'Views'.
if you need simply load a view and no controller is required, you can use the static method Route::view
.
Example of routes.php
file:
use \Videna\Core\Route;
...
Route::view('/about', 'about.php');
In this way, the view from the file /App/Views/about.php
will be provided by the framework to the browser.
Redirect to some URL from controller can be done via action actionRedirect('url')
, for example:
if (User::get('account') < USR_REG) {
$this->actionRedirect('/login');
return;
}
Redirect to other action from controller can be done via setting of the new action and force the return, for example:
Router::$action = 'Login';
return;
To redirect to Error action and show the Error page, use the action actionError(ErrorNumber)
:
if (Router::get('param') == null ) {
$this->actionError(400);
return;
}
Application controller \Videna\Controllers\AppController
handles requests to provide RESTful services.
- handles 'POST', 'GET', 'PUT', DELETE and 'PATCH' requests methods;
- returns data in JSON format;
- provides CSRF protection via double submit cookies pattern for 'POST', 'PUT', DELETE and 'PATCH' requests methods;
- automatically provides a synchronizer token pattern for each active user session.
HTML/JavaScript file:
<div id="privacy-body"></div>
...
<script>
const getModalBody = async () => {
try {
const response = await fetch('/webapp/privacy-policy');
if (response.ok) {
const jsonResponse = await response.json();
document.getElementById('privacy-body').innerHTML = jsonResponse.html;
}
}
catch (error) {
console.log(error);
}
}
getModalBody();
</script>
Routes list (/App/configs/routes.php):
use \Videna\Core\Route;
...
Route::get('/webapp/privacy-policy', 'WebApp@GetPolicy');
Controller (/App/Controllers/WebApp.php):
namespace App\Controllers;
use \Videna\Core\View;
class WebApp extends \Videna\Controllers\AppController
{
public function actionGetPolicy()
{
View::set(['html' => View::render('/webapp/privacy-policy.php')]);
}
}
In the example above, the view from file
/App/Views/webapp/privacy-policy.php
will be passed in the property.html
of the framework response in JSON format.
async function SignInUser(user) {
user.crsf_token = document.querySelector('meta[name="csrf_token"]').getAttribute("content");
let data = {
"csrf_token": "<?= $csrf->token ?>",
"email": "user@email.com"
}
try {
const response = await fetch("/WebApp/login", {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-type': 'application/json'
}
});
if(response.ok) {
const jsonResponse = await response.json();
if (jsonResponse.response != 200) throw Error(jsonResponse.status);
// User logged-in...
}
} catch (error) {
console.log(error);
}
}
Routes list (/App/configs/routes.php):
use \Videna\Core\Route;
...
Route::post('/WebApp/login', 'WebApp@Login');
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script>
$.ajax({
url: "/ajax-test",
data: {param: 'test'}
dataType: 'json',
success: function(data) {
// Response from server has been received.
console.log(data);
}
});
</script>
And to handle this request:
- Add URL into the registered routes list, for example:
use \Videna\Core\Route;
...
Route::get('/ajax-test', 'Ajax@Test');
- Add a controller
Ajax.php
to folder/App/Controllers/
namespace App\Controllers;
use \Videna\Core\Router;
class Ajax extends \Videna\Controllers\AppController
{
public function actionTest()
{
Log::info('param: ' . Router::get('param'));
}
}
Any data returned from Videna application are in JSON format. By default, two properties are always returned:
- property
.statusCode
contains the server's response status code number. - property
.response
contains the server's response state200 OK
or an error state.
Example:
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script src="/js/videna-ajax.js"></script>
<script>
$.ajax({
url: "/ajax/privacy-policy",
dataType: 'json',
success: function(data) {
console.log(data.response);
console.log(data.statusCode);
}
});
</script>
You can set data in the controller to pass them back to JS, using the static method View::set()
.
Example:
namespace App\Controllers;
use \Videna\Core\View;
class ApiTasks extends \Videna\Controllers\AppController
{
public function actionTest()
{
View::set([
'text' => 'Text test phrase',
'html' => '<p>Text test phrase</p>',
'bool' => true,
'num' => 100
]);
}
}
Also, you can pass HTML view through a parameter using the method View::render()
, for example:
$data = [ 'var1' => 'test'];
View::set([
// View is here: '/App/Views/ajax/test-view.php':
'view' => View::render('ajax/test-view.php', $data)
]);
where optional $data
- some data that your view is required.
API controller \Videna\Controllers\ApiController
handles requests to provide API service for external sources.
- handles 'POST', 'GET', 'PUT', DELETE and 'PATCH' requests methods;
- returns data in JSON format;
- DOES NOT provide CSRF protection for 'POST', 'PUT', DELETE and 'PATCH' requests methods.
This section is in work now.
Cron job controller \Videna\Controllers\CronJob
is responsible for cron jobs via the command line or HTTP requests (in test mode).
This section is in work now.