-
-
Notifications
You must be signed in to change notification settings - Fork 277
Expand file tree
/
Copy pathpresenters.texy
More file actions
512 lines (332 loc) · 23.4 KB
/
presenters.texy
File metadata and controls
512 lines (332 loc) · 23.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
Presentery
**********
<div class=perex>
Seznámíme se s tím, jak se v Nette píší presentery a šablony. Po přečtení budete vědět:
- jak funguje presenter
- co jsou persistentní parametry
- jak se kreslí šablony
</div>
[Už víme |how-it-works#Nette Application], že presenter je třída, která představuje nějakou konkrétní stránku webové aplikace, např. homepage; produkt v e-shopu; přihlašovací formulář; sitemap feed atd. Aplikace může mít od jednoho po tisíce presenterů. V jiných frameworcích se jim také říká controllery.
Obvykle se pod pojmem presenter myslí potomek třídy [api:Nette\Application\UI\Presenter], který je vhodný pro generování webových rozhraní a kterému se budeme věnovat ve zbytku této kapitoly. V obecném smyslu je presenter jakýkoliv objekt implementující rozhraní [api:Nette\Application\IPresenter].
Životní cyklus presenteru
=========================
Úkolem presenteru je vyřídit požadavek a vrátit odpověď (což může být HTML stránka, obrázek, přesměrování atd.).
Tedy na počátku je mu předán požadavek. Není to přímo HTTP požadavek, ale objekt [api:Nette\Application\Request], do kterého byl HTTP požadavek přetransformován za pomoci routeru. S tímto objektem obvykle nepřijdeme do styku, neboť presenter zpracování požadavku chytře deleguje do dalších metod, které si teď ukážeme.
[* lifecycle.svg *] *** *Životní cyklus presenteru* .<>
Obrázek představuje seznam metod, které se postupně od shora dolů volají, pokud existují. Žádná z nich existovat nemusí, můžeme mít úplně prázdný presenter bez jediné metody a postavit na něm jednoduchý statický web.
`__construct()`
---------------
Konstruktor nepatří tak úplně do životního cyklu presenteru, protože se volá v okamžiku vytváření objektu. Ale uvádíme jej kvůli důležitosti. Konstruktor (společně s [metodou inject|best-practices:inject-method-attribute]) slouží k předávání závislostí.
Presenter by neměl obstarávat byznys logiku aplikace, zapisovat a číst z databáze, provádět výpočty atd. Od toho jsou třídy z vrstvy, kterou označujeme jako model. Například třída `ArticleRepository` může mít na starosti načítání a ukládání článků. Aby s ní mohl presenter pracovat, nechá si ji [předat pomocí dependency injection |dependency-injection:passing-dependencies]:
```php
class ArticlePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private ArticleRepository $articles,
) {
}
}
```
`startup()`
-----------
Ihned po obdržení požadavku se zavolá metoda `startup()`. Můžete ji využít k inicializaci properties, ověření uživatelských oprávnění atd. Je vyžadováno, aby metoda vždy volala předka `parent::startup()`.
`action<Action>(args...)` .{toc: action<Action>()}
--------------------------------------------------
Obdoba metody `render<View>()`. Zatímco `render<View>()` je určená k tomu, aby připravila data pro konkrétní šablonu, která se následně vykreslí, tak v `action<Action>()` se zpracovává požadavek bez návaznosti na vykreslování šablony. Například se zpracují data, přihlásí či odhlásí uživatel, a tak podobně, a poté [přesměruje jinam |#Přesměrování].
Důležité je, že `action<Action>()` se volá dříve než `render<View>()`, takže v ní můžeme případně změnit další běh dějin, tj. změnit šablonu, která se bude kreslit, a také metodu `render<View>()`, která se bude volat. A to pomocí `setView('jineView')`.
Metodě se předávají parametry z požadavku. Je možné a doporučené uvést parametrům typy, např. `actionShow(int $id, ?string $slug = null)` - pokud bude parametr `id` chybět nebo pokud nebude integer, presenter vrátí [chybu 404 |#Chyba 404 a spol] a ukončí činnost.
`handle<Signal>(args...)` .{toc: handle<Signal>()}
--------------------------------------------------
Metoda zpracovává tzv. signály, se kterými se seznámíme v kapitole věnované [komponentám |components#Signál]. Je totiž určena zejména pro komponenty a zpracování AJAXových požadavků.
Metodě se předávají parametry z požadavku, jako v případě `action<Action>()`, včetně typové kontroly.
`beforeRender()`
----------------
Metoda `beforeRender`, jak už název napovídá, se volá před každou metodou `render<View>()`. Používá se pro společnou konfiguraci šablony, předání proměnných pro layout a podobně.
`render<View>(args...)` .{toc: render<View>()}
----------------------------------------------
Místo, kde připravujeme šablonu k následnému vykreslení, předáváme jí data atd.
Metodě se předávají parametry z požadavku, jako v případě `action<Action>()`, včetně typové kontroly.
```php
public function renderShow(int $id): void
{
// získáme data z modelu a předáme do šablony
$this->template->article = $this->articles->getById($id);
}
```
`afterRender()`
---------------
Metoda `afterRender`, jak název opět napovídá, se volá za každou metodou `render<View>()`. Používá se spíš výjimečně.
`shutdown()`
------------
Volá se na konci životního cyklu presenteru.
**Dobrá rada, než půjdeme dál**. Presenter jak vidno může obsluhovat více akcí/view, tedy mít více metod `render<View>()`. Ale doporučujeme navrhovat presentery s jednou nebo co nejméně akcemi.
Odeslání odpovědi
=================
Odpovědí presenteru je zpravidla [vykreslení šablony s HTML stránkou|templates], ale může jí být také odeslání souboru, JSON nebo třeba přesměrování na jinou stránku.
Kdykoliv během životního cyklu můžeme některou z následujících metod odeslat odpověď a zároveň tak ukončit presenter:
- `redirect()`, `redirectPermanent()`, `redirectUrl()` a `forward()` [přesměruje |#Přesměrování]
- `error()` ukončí presenter [kvůli chybě |#Chyba 404 a spol]
- `sendJson($data)` presenter ukončí a [odešle data |#Odeslání JSON] ve formátu JSON
- `sendTemplate()` presenter ukončí a ihned [vykreslí šablonu |templates]
- `sendResponse($response)` presenter ukončí a odešle [vlastní odpověď |#Odpovědi]
- `terminate()` presenter ukončí bez odpovědi
Každá z těchto metod okamžitě ukončí činnost presenteru vyhozením tzv. tiché ukončovací výjimky `Nette\Application\AbortException`.
Pokud žádnou z těchto metod nezavoláte, presenter automaticky přistoupí k vykreslí šablony. Proč? Protože v 99 % případů chceme vykreslit šablonu, tudíž presenter tohle chování bere jako výchozí a chce nám ulehčit práci.
Vytváření odkazů
================
Presenter disponuje metodou `link()`, pomocí které lze vytvářet URL odkazy na další presentery. Prvním parametrem je cílový presenter & akce, následují předávané argumenty, které mohou být uvedeny jako pole:
```php
$url = $this->link('Product:show', $id);
$url = $this->link('Product:show', [$id, 'lang' => 'cs']);
```
V šabloně se vytvářejí odkazy na další presentery & akce tímto způsobem:
```latte
<a n:href="Product:show $id">detail produktu</a>
```
Prostě místo reálného URL napíšete známý pár `Presenter:action` a uvedete případné parametry. Trik je v tom `n:href`, které říká, že tento atribut zpracuje Latte a vygeneruje reálné URL. V Nette tak vůbec nemusíte uvažovat nad URL, jen nad presentery a akcemi.
Více informací najdete v kapitole [Vytváření odkazů URL|creating-links].
Přesměrování
============
K přechodu na jiný presenter slouží metody `redirect()` a `forward()`, které mají velmi podobnou syntax jako metoda [link() |#Vytváření odkazů].
Metoda `forward()` přejde na nový presenter okamžitě bez HTTP přesměrování:
```php
$this->forward('Product:show');
```
Příklad tzv. dočasného přesměrování s HTTP kódem 302 (nebo 303, je-li metoda aktuálního požadavku POST):
```php
$this->redirect('Product:show', $id);
```
Permanentní přesměrování s HTTP kódem 301 docílíte takto:
```php
$this->redirectPermanent('Product:show', $id);
```
Na jinou URL mimo aplikaci lze přesměrovat metodou `redirectUrl()`. Jako druhý parametr lze uvést HTTP kód, výchozí je 302 (nebo 303, je-li metoda aktuálního požadavku POST):
```php
$this->redirectUrl('https://nette.org');
```
Přesměrování okamžitě ukončí činnost presenteru vyhozením tzv. tiché ukončovací výjimky `Nette\Application\AbortException`.
Před přesměrováním lze odeslat [flash message |#Flash zprávy], tedy zprávy, které budou po přesměrování zobrazeny v šabloně.
Flash zprávy
============
Jde o zprávy obvykle informující o výsledku nějaké operace. Důležitým rysem flash zpráv je to, že jsou v šabloně k dispozici i po přesměrování. I po zobrazení zůstanou živé ještě dalších 30 sekund – například pro případ, že by z důvodu chybného přenosu uživatel dal stránku obnovit - zpráva mu tedy hned nezmizí.
Stačí zavolat metodu [flashMessage() |api:Nette\Application\UI\Control::flashMessage()] a o předání do šablony se postará presenter. Prvním parametrem je text zprávy a nepovinným druhým parametrem její typ (error, warning, info apod.). Metoda `flashMessage()` vrací instanci flash zprávy, které je možné přidávat další informace.
```php
$this->flashMessage('Položka byla smazána.');
$this->redirect(/* ... */); // a přesměrujeme
```
Šabloně jsou tyto zprávy k dispozici v proměnné `$flashes` jako objekty `stdClass`, které obsahují vlastnosti `message` (text zprávy), `type` (typ zprávy) a mohou obsahovat již zmíněné uživatelské informace. Vykreslíme je třeba takto:
```latte
{foreach $flashes as $flash}
<div class="flash {$flash->type}">{$flash->message}</div>
{/foreach}
```
Chyba 404 a spol.
=================
Pokud nelze splnit požadavek, třeba z důvodu, že článek který chceme zobrazit neexistuje v databázi, vyhodíme chybu 404 metodou `error(?string $message = null, int $httpCode = 404)`.
```php
public function renderShow(int $id): void
{
$article = $this->articles->getById($id);
if (!$article) {
$this->error();
}
// ...
}
```
HTTP kód chyby lze předat jako druhý parametr, výchozí je 404. Metoda funguje tak, že vyhodí výjimku `Nette\Application\BadRequestException`, načež `Application` předá řízení error-presenteru. Což je presenter, jehož úkolem je zobrazit stránku informující o nastalé chybě. Nastavení error-preseteru se provádí v [konfiguraci application|configuration].
Odeslání JSON
=============
Příklad action-metody, která odešle data ve formátu JSON a ukončí presenter:
```php
public function actionData(): void
{
$data = ['hello' => 'nette'];
$this->sendJson($data);
}
```
Parametry požadavku .{data-version:3.1.14}
==========================================
Presenter a také každá komponenta získává z HTTP požadavku své parametry. Jejich hodnotu zjistíte metodou `getParameter($name)` nebo `getParameters()`. Hodnoty jsou řetězce či pole řetězců, jde v podstatě o surové data získané přímo z URL.
Pro větší pohodlí doporučujeme parametry zpřístupnit přes property. Stačí je označit atributem `#[Parameter]`:
```php
use Nette\Application\Attributes\Parameter; // tento řádek je důležitý
class HomePresenter extends Nette\Application\UI\Presenter
{
#[Parameter]
public string $theme; // musí být public
}
```
U property doporučujeme uvádět i datový typ (např. `string`) a Nette podle něj hodnotu automaticky přetypuje. Hodnoty parametrů lze také [validovat |#Validace parametrů].
Při vytváření odkazu lze parametrům hodnotu přímo nastavit:
```latte
<a n:href="Home:default theme: dark">click</a>
```
Persistentní parametry
======================
Persistentní parametry slouží k udržování stavu mezi různými požadavky. Jejich hodnota zůstává stejná i po kliknutí na odkaz. Na rozdíl od dat v session se přenášejí v URL. A to zcela automaticky, není tedy potřeba je explicitně uvádět v `link()` nebo `n:href`.
Příklad použití? Máte multijazyčnou aplikaci. Aktuální jazyk je parameter, který musí být neustále součástí URL. Ale bylo by neskutečně únavné ho v každém odkazu uvádět. Tak z něj uděláte persistentní parametr `lang` a bude se přenášet sám. Paráda!
Vytvoření persistentního parametru je v Nette nesmírně jednoduché. Stačí vytvořit veřejnou property a označit ji atributem: (dříve se používalo `/** @persistent */`)
```php
use Nette\Application\Attributes\Persistent; // tento řádek je důležitý
class ProductPresenter extends Nette\Application\UI\Presenter
{
#[Persistent]
public string $lang; // musí být public
}
```
Pokud bude `$this->lang` mít hodnotu například `'en'`, tak i odkazy vytvořené pomocí `link()` nebo `n:href` budou obsahovat parameter `lang=en`. A po kliknutí na odkaz bude opět `$this->lang = 'en'`.
U property doporučujeme uvádět i datový typ (např. `string`) a můžete uvést i výchozí hodnotu. Hodnoty parametrů lze [validovat |#Validace parametrů].
Persistentní parametry se standardně přenášejí mezi všemi akcemi daného presenteru. Aby se přenášely i mezi více presentery, je potřeba je definovat buď:
- ve společném předkovi, od kterého presentery dědí
- v traitě, kterou presentery použijí:
```php
trait LanguageAware
{
#[Persistent]
public string $lang;
}
class ProductPresenter extends Nette\Application\UI\Presenter
{
use LanguageAware;
}
```
Při vytváření odkazu lze persistentnímu parametru změnit hodnotu:
```latte
<a n:href="Product:show $id, lang: cs">detail v češtině</a>
```
Nebo jej lze *vyresetovat*, tj. odstranit z URL. Pak bude nabývat svou výchozí hodnotu:
```latte
<a n:href="Product:show $id, lang: null">klikni</a>
```
Interaktivní komponenty
=======================
Presentery v sobě mají zabudovaný komponentový systém. Komponenty jsou samostatné znovupoužitelné celky, které vkládáme do presenterů. Mohou to být [formuláře |forms:in-presenter], datagridy, menu, vlastně cokoliv, co má smysl používat opakovaně.
Jak se do presenteru komponenty vkládají a následně používají? To se dozvíte v kapitole [Komponenty |components]. Dokonce zjistíte, co mají společného s Hollywoodem.
A kde mohu získat komponenty? Na stránce [Componette |https://componette.org/search/component] najdete open-source komponenty a také řadu dalších doplňku pro Nette, které sem umístili dobrovolníci z komunity okolo frameworku.
Jdeme do hloubky
================
.[tip]
S tím, co jsme si dosud v této kapitole ukázali, si nejspíš úplně vystačíte. Následující řádky jsou určeny těm, kdo se zajímají o presentery do hloubky a chtějí vědět úplně všechno.
Validace parametrů
------------------
Hodnoty [parametrů požadavku |#Parametry požadavku] a [persistentních parametrů |#Persistentní parametry] přijatých z URL zapisuje do properties metoda `loadState()`. Ta také kontroluje, zda odpovídá datový typ uvedený u property, jinak odpoví chybou 404 a stránka se nezobrazí.
Nikdy slepě nevěřte parametrům, protože mohou být snadno uživatelem přepsány v URL. Takto například ověříme, zda je jazyk `$this->lang` mezi podporovanými. Vhodnou cestou je přepsat zmíněnou metodu `loadState()`:
```php
class ProductPresenter extends Nette\Application\UI\Presenter
{
#[Persistent]
public string $lang;
public function loadState(array $params): void
{
parent::loadState($params); // zde se nastaví $this->lang
// následuje vlastní kontrola hodnoty:
if (!in_array($this->lang, ['en', 'cs'])) {
$this->error();
}
}
}
```
Uložení a obnovení požadavku
----------------------------
Požadavek, který vyřizuje presenter, je objekt [api:Nette\Application\Request] a vrací ho metoda presenteru `getRequest()`.
Aktuální požadavek lze uložit do session nebo naopak z ní obnovit a nechat jej presenter znovu vykonat. To se hodí například v situaci, když uživatel vyplňuje formulář a vyprší mu přihlášení. Aby o data nepřišel, před přesměrováním na přihlašovací stránku aktuální požadavek uložíme do session pomocí `$reqId = $this->storeRequest()`, které vrátí jeho identifikátor v podobě krátkého řetězce a ten předáme jako parameter přihlašovacímu presenteru.
Po přihlášení zavoláme metodu `$this->restoreRequest($reqId)`, která požadavek vyzvedne ze session a forwarduje na něj. Metoda přitom ověří, že požadavek vytvořil stejný uživatel, jako se nyní přihlásil. Pokud by se přihlásil jiný uživatel nebo klíč byl neplatný, neudělá nic a program pokračuje dál.
Podívejte se na návod [Jak se vrátit k dřívější stránce |best-practices:restore-request].
Kanonizace
----------
Presentery mají jednu opravdu skvělou vlastnost, která přispívá k lepšímu SEO (optimalizaci nalezitelnosti na internetu). Automaticky zabraňují existenci duplicitního obsahu na různých URL. Pokud k určitému cíli vede více URL adres, např. `/index` a `/index?page=1`, framework určí jednu z nich za primární (kanonickou) a ostatní na ni přesměruje pomocí HTTP kódu 301. Díky tomu vám vyhledávače stránky neindexují dvakrát a nerozmělní jejich page rank.
Tomuto procesu se říká kanonizace. Kanonickou URL je ta, kterou vygeneruje [router|routing], zpravidla tedy první odpovídající routa v kolekci.
Kanonizace je ve výchozím nastavení zapnutá a lze ji vypnout přes `$this->autoCanonicalize = false`.
K přesměrování nedojde při AJAXovém nebo POST požadavku, protože by došlo ke ztrátě dat nebo by to nemělo přidanou hodnotu z hlediska SEO.
Kanonizaci můžete vyvolat i manuálně pomocí metody `canonicalize()`, které se podobně jako metodě `link()` předá presenter, akce a parametry. Vyrobí odkaz a porovná ho s aktuální URL adresou. Pokud se liší, tak přesměruje na vygenerovaný odkaz.
```php
public function actionShow(int $id, ?string $slug = null): void
{
$realSlug = $this->facade->getSlugForId($id);
// přesměruje, pokud $slug se liší od $realSlug
$this->canonicalize('Product:show', [$id, $realSlug]);
}
```
Kompletní vzor, který kombinuje routovací filtry s `canonicalize()` pro generování SEO-friendly URL, najdete v návodu [Hezké URL se slugem |best-practices:pretty-urls].
Události
--------
Kromě metod `startup()`, `beforeRender()` a `shutdown()`, které se volají jako součást životního cyklu presenteru, lze definovat ještě další funkce, které se mají automaticky zavolat. Presenter definuje tzv. [událost |nette:glossary#události], jejichž handlery přidáte do polí `$onStartup`, `$onRender` a `$onShutdown`.
```php
class ArticlePresenter extends Nette\Application\UI\Presenter
{
public function __construct()
{
$this->onStartup[] = function () {
// ...
};
}
}
```
Handlery v poli `$onStartup` se volají těsně před metodou `startup()`, dále `$onRender` mezi `beforeRender()` a `render<View>()` a nakonec `$onShutdown` těsně před `shutdown()`.
Odpovědi
--------
Odpověď, kterou vrací presenter, je objekt implementující rozhraní [api:Nette\Application\Response]. K dispozici je řada připravených odpovědí:
- [api:Nette\Application\Responses\CallbackResponse] - odešle callback
- [api:Nette\Application\Responses\FileResponse] - odešle soubor
- [api:Nette\Application\Responses\ForwardResponse] - forward()
- [api:Nette\Application\Responses\JsonResponse] - odešle JSON
- [api:Nette\Application\Responses\RedirectResponse] - přesměrování
- [api:Nette\Application\Responses\TextResponse] - odešle text
- [api:Nette\Application\Responses\VoidResponse] - prázdná odpověď
Odpovědi se odesílají metodou `sendResponse()`:
```php
use Nette\Application\Responses;
// Prostý text
$this->sendResponse(new Responses\TextResponse('Hello Nette!'));
// Odešle soubor
$this->sendResponse(new Responses\FileResponse(__DIR__ . '/invoice.pdf', 'Invoice13.pdf'));
// Odpovědí bude callback
$callback = function (Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse) {
if ($httpResponse->getHeader('Content-Type') === 'text/html') {
echo '<h1>Hello</h1>';
}
};
$this->sendResponse(new Responses\CallbackResponse($callback));
```
Omezení přístupu pomocí `#[Requires]` .{data-version:3.2.2}
-----------------------------------------------------------
Atribut `#[Requires]` poskytuje pokročilé možnosti pro omezení přístupu k presenterům a jejich metodám. Lze jej použít pro specifikaci HTTP metod, vyžadování AJAXového požadavku, omezení na stejný původ (same origin), a přístup pouze přes forwardování. Atribut lze aplikovat jak na třídy presenterů, tak na jednotlivé metody `action<Action>()`, `render<View>()`, `handle<Signal>()` a `createComponent<Name>()`.
Můžete určit tyto omezení:
- na HTTP metody: `#[Requires(methods: ['GET', 'POST'])]`
- vyžadování AJAXového požadavku: `#[Requires(ajax: true)]`
- přístup pouze ze stejného původu: `#[Requires(sameOrigin: true)]`
- přístup pouze přes forward: `#[Requires(forward: true)]`
- omezení na konkrétní akce: `#[Requires(actions: 'default')]`
Podrobnosti najdete v návodu [Jak používat atribut Requires |best-practices:attribute-requires].
Kontrola HTTP metody
--------------------
Presentery v Nette automaticky ověřují HTTP metodu každého příchozího požadavku. Důvodem pro tuto kontrolu je především bezpečnost. Standardně jsou povoleny metody `GET`, `POST`, `HEAD`, `PUT`, `DELETE`, `PATCH`.
Chcete-li povolit navíc například metodu `OPTIONS`, použijte k tomu atribut `#[Requires]` (od Nette Application v3.2):
```php
#[Requires(methods: ['GET', 'POST', 'HEAD', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])]
class MyPresenter extends Nette\Application\UI\Presenter
{
}
```
Ve verzi 3.1 se ověření provádí v `checkHttpMethod()`, která zjišťuje, zda je metoda specifikovaná v požadavku obsažena v poli `$presenter->allowedMethods`. Přidání metody udělejte takto:
```php
class MyPresenter extends Nette\Application\UI\Presenter
{
protected function checkHttpMethod(): void
{
$this->allowedMethods[] = 'OPTIONS';
parent::checkHttpMethod();
}
}
```
Je důležité zdůraznit, že pokud povolíte metodu `OPTIONS`, musíte ji následně také patřičně obsloužit v rámci svého presenteru. Metoda je často používána jako tzv. preflight request, který prohlížeč automaticky odesílá před skutečným požadavkem, když je potřeba zjistit, zda je požadavek povolený z hlediska CORS (Cross-Origin Resource Sharing) politiky. Pokud metodu povolíte, ale neimplementujete správnou odpověď, může to vést k nekonzistencím a potenciálním bezpečnostním problémům.
Označení zastaralých akcí .{data-version:3.2.3}
-----------------------------------------------
Atribut `#[Deprecated]` slouží k označení akcí, signálů nebo celých presenterů, které jsou zastaralé a měly by být v budoucnu odstraněny. Při generování odkazů na takto označené části aplikace Nette vyhodí varování, které vývojáře upozorní.
Atribut lze aplikovat jak na celou třídu presenteru, tak na jednotlivé metody `action<Action>()`, `render<View>()` a `handle<Signal>()`.
Další četba
===========
- [Metody a atributy inject |best-practices:inject-method-attribute]
- [Skládání presenterů z trait |best-practices:presenter-traits]
- [Předání nastavení do presenterů |best-practices:passing-settings-to-presenters]
- [Jak se vrátit k dřívější stránce |best-practices:restore-request]