mirror of
https://github.com/nextcloud/documentation.git
synced 2026-01-03 02:09:45 +07:00
add route generation
This commit is contained in:
@@ -1,4 +1,172 @@
|
||||
===========
|
||||
Controllers
|
||||
===========
|
||||
|
||||
.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com>
|
||||
.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com>
|
||||
|
||||
Controllers are used to connect :doc:`routes <routes>` with app logic. Think of it as callbacks that are executed once a request has come in. Controllers are defined inside the **controllers/** directory.
|
||||
|
||||
Connecting a controller with a route
|
||||
====================================
|
||||
|
||||
Getting request parameters
|
||||
==========================
|
||||
Parameters can be passed in many ways:
|
||||
|
||||
* Extracted from the URL using curly braces like **{key}** inside the URL (see :doc:`routes`)
|
||||
* Appended to the URL as a GET request (e.g. ?something=true)
|
||||
* application/x-www-form-urlencoded from a form or jQuery
|
||||
* application/json from a POST, PATCH or PUT request
|
||||
|
||||
All those parameters can easily be accessed by adding them to the controller method:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace OCA\MyApp\Controller;
|
||||
|
||||
use \OCP\AppFramework\Controller;
|
||||
|
||||
class PageController extends Controller {
|
||||
|
||||
// this method will be executed with the id and name parameter taken
|
||||
// from the request
|
||||
public function doSomething($id, $name) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Casting parameters
|
||||
------------------
|
||||
URL, GET and application/x-www-form-urlencoded have the problem that every parameter is a string, meaning that *?doMore=false* would be passed in as the string *'false'* which is not what one would expect. To cast these to the correct types, simply add PHPDoc to hint the types:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace OCA\MyApp\Controller;
|
||||
|
||||
use \OCP\AppFramework\Controller;
|
||||
|
||||
class PageController extends Controller {
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param bool $doMore
|
||||
* @param float $value
|
||||
*/
|
||||
public function doSomething($id, $doMore, $value) {
|
||||
// GET /index.php/apps/myapp?id=3&doMore=false&value=3.5
|
||||
// => $id = 3
|
||||
// $doMore = false
|
||||
// $value = 3.5
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
The following types will be casted:
|
||||
|
||||
* **bool** or **bolean**
|
||||
* **float**
|
||||
* **int** or **integer**
|
||||
|
||||
|
||||
JSON parameters
|
||||
---------------
|
||||
It is possible to pass JSON using a POST, PUT or PATCH request. To do that the **Content-Type** header has to be set to **application/json**. The JSON is being parsed as an array and the first level keys will be used to pass in the arguments, e.g.::
|
||||
|
||||
POST /index.php/apps/myapp/authors
|
||||
{
|
||||
"name": "test",
|
||||
"number": 3,
|
||||
"publisher": true,
|
||||
"customFields": {
|
||||
"mail": "test@example.com",
|
||||
"address": "Somewhere"
|
||||
}
|
||||
}
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace OCA\MyApp\Controller;
|
||||
|
||||
use \OCP\AppFramework\Controller;
|
||||
|
||||
class PageController extends Controller {
|
||||
|
||||
public function create($name, $number, $publisher, $customFields) {
|
||||
// $name = 'test'
|
||||
// $number = 3
|
||||
// $publisher = true
|
||||
// $customFields = array("mail" => "test@example.com", "address" => "Somewhere")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Headers, files, cookies and session information
|
||||
-----------------------------------------------
|
||||
|
||||
Responses
|
||||
=========
|
||||
|
||||
JSON
|
||||
----
|
||||
|
||||
Templates
|
||||
---------
|
||||
|
||||
Redirects
|
||||
---------
|
||||
|
||||
Downloads
|
||||
---------
|
||||
|
||||
Creating custom responses
|
||||
-------------------------
|
||||
|
||||
Responders
|
||||
----------
|
||||
|
||||
Serializers
|
||||
-----------
|
||||
|
||||
|
||||
Authentication
|
||||
==============
|
||||
By default every controller method enforces the maximum security, which is:
|
||||
|
||||
* Ensure that the user is admin
|
||||
* Ensure that the user is logged in
|
||||
* Check the CSRF token
|
||||
|
||||
Most of the time though it makes sense to also allow normal users to access the page and the PageController->index() method should not check the CSRF token because it has not yet been sent to the client and because of that can't work.
|
||||
|
||||
To turn off checks the following *Annotations* can be added before the controller:
|
||||
|
||||
* **@NoAdminRequired**: Also users that are not admins can access the page
|
||||
* **@NoCSRFRequired**: Don't check the CSRF token (use this wisely since you might create a security hole, to understand what it does see :doc:`../general/security`)
|
||||
* **@PublicPage**: Everyone can access that page without having to log in
|
||||
|
||||
A controller method that turns of all checks would look like this:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace OCA\MyApp\Controller;
|
||||
|
||||
use \OCP\IRequest;
|
||||
use \OCP\AppFramework\Controller;
|
||||
|
||||
class PageController extends Controller {
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @PublicPage
|
||||
*/
|
||||
public function freeForAll() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,7 +31,7 @@ Afterwards the following steps are performed:
|
||||
|
||||
Router
|
||||
------
|
||||
The router parses the :doc:`apps routing files <routes>` (:file:`appinfo/routes.php`), inspects the request's **method** and **url**, queries the controller from the :doc:`container` and then passes control to the dispatcher. The dispatcher is responsible for running the hooks (called Middleware) before and after the controller, executing the controller method and rendering the output.
|
||||
The router parses the :doc:`app's routing files <routes>` (:file:`appinfo/routes.php`), inspects the request's **method** and **url**, queries the controller from the :doc:`container` and then passes control to the dispatcher. The dispatcher is responsible for running the hooks (called Middleware) before and after the controller, executing the controller method and rendering the output.
|
||||
|
||||
Middleware
|
||||
----------
|
||||
|
||||
@@ -148,4 +148,82 @@ can be abbreviated by using the **resources** key:
|
||||
'routes' => array(
|
||||
// your other routes here
|
||||
)
|
||||
));
|
||||
));
|
||||
|
||||
Using the URLGenerator
|
||||
========================
|
||||
Sometimes its useful to turn a route into a URL to make the code independent from the url design or generate an URL for an image in **img/**. For that specific usecase the ServerContainer provides a service that can be used in your container:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace OCA\MyApp\AppInfo;
|
||||
|
||||
use \OCP\AppFramework\App;
|
||||
|
||||
use \OCA\MyApp\Controller\PageController;
|
||||
|
||||
|
||||
class Application extends App {
|
||||
|
||||
public function __construct(array $urlParams=array()){
|
||||
parent::__construct('myapp', $urlParams);
|
||||
|
||||
$container = $this->getContainer();
|
||||
|
||||
/**
|
||||
* Controllers
|
||||
*/
|
||||
$container->registerService('PageController', function($c) {
|
||||
return new PageController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
|
||||
// inject the URLGenerator into the page controller
|
||||
$c->query('ServerContainer')->getURLGenerator()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Inside the PageController the URL generator can now be used to generate an URL for a redirect:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace OCA\MyApp\Controller;
|
||||
|
||||
use \OCP\IRequest;
|
||||
use \OCP\IURLGenerator;
|
||||
use \OCP\AppFramework\Controller;
|
||||
use \OCP\AppFramework\Http\RedirectResponse;
|
||||
|
||||
class PageController extends Controller {
|
||||
|
||||
private $urlGenerator;
|
||||
|
||||
public function __construct($appName, IRequest $request,
|
||||
IURLGenerator $urlGenerator) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* redirect to /apps/news/myapp/authors/3
|
||||
*/
|
||||
public function redirect() {
|
||||
// route name: author_api#do_something route
|
||||
// route url: /apps/news/myapp/authors/{id}
|
||||
|
||||
// # need to be replaced with a . due to limitations and prefix
|
||||
// with your app id
|
||||
$route = 'myapp.author_api.do_something';
|
||||
$parameters = array('id' => 3);
|
||||
|
||||
$url = $this->urlGenerator->linkToRoute($route, $parameters);
|
||||
|
||||
return new RedirectResponse($url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user