diff --git a/application/bg/bootstrap.texy b/application/bg/bootstrap.texy index a7989b2d15..c2cd01ec7e 100644 --- a/application/bg/bootstrap.texy +++ b/application/bg/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ $configurator->setDebugMode(false); За да улесним дебъгването, ще включим чудесния инструмент [Tracy |tracy:]. В режим за разработчици той визуализира грешките, а в производствен режим записва грешките в определена директория: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ $configurator->enableTracy($appDir . '/log'); Nette използва кеш за DI-контейнер, RobotLoader, шаблони и др. Затова е необходимо да се зададе пътят до директорията, в която се съхранява кешът: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` В Linux или macOS задайте [разрешения за запис |nette:troubleshooting#Setting-Directory-Permissions] за директориите `log/` и `temp/`. @@ -143,16 +143,16 @@ $configurator->setTimeZone('Europe/Prague'); Файловете за конфигурация се зареждат с помощта на `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Методът `addConfig()` може да се извика няколко пъти, за да се добавят няколко файла. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ $configurator->addDynamicParameters([ - `%wwwDir%` е абсолютният път до директорията, съдържаща входния файл `index.php` - `%tempDir%` е абсолютният път до директорията за временни файлове - `%vendorDir%` е абсолютният път до директорията, в която Composer инсталира библиотеки +- `%rootDir%` е абсолютният път до главната директория на проекта - `%debugMode%` показва дали приложението е в режим на отстраняване на грешки - `%consoleMode%` показва дали заявката е постъпила от командния ред diff --git a/application/bg/configuration.texy b/application/bg/configuration.texy index 30bc0d30c0..a760566241 100644 --- a/application/bg/configuration.texy +++ b/application/bg/configuration.texy @@ -104,7 +104,7 @@ latte: ```neon latte: расширения: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/bg/presenters.texy b/application/bg/presenters.texy index efcce1d904..a138f522a3 100644 --- a/application/bg/presenters.texy +++ b/application/bg/presenters.texy @@ -452,17 +452,6 @@ $this->sendResponse(new Responses\CallbackResponse($callback)); В `#[Requires]` предоставя разширени опции за ограничаване на достъпа до презентаторите и техните методи. Той може да се използва за определяне на HTTP методи, изискване на AJAX заявки, ограничаване на достъпа до същия произход и ограничаване на достъпа само до препращане. Атрибутът може да се прилага към класове на презентатори, както и към отделни методи, като например `action()`, `render()`, `handle()`, и `createComponent()`. -Ето един пример за използването му за ограничаване на достъпа само до метода HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Можете да зададете тези ограничения: - на HTTP методите: `#[Requires(methods: ['GET', 'POST'])]` - изискващи AJAX заявка: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ class MyPresenter extends Nette\Application\UI\Presenter - достъп само чрез препращане: `#[Requires(forward: true)]` - ограничения за конкретни действия: `#[Requires(actions: 'default')]` -Условията могат да се комбинират чрез изброяване на няколко атрибута или чрез обединяването им в един: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +За подробности вижте [Как да използвате Requires атрибут |добри практики:атрибут- изисква]. Проверка на метода HTTP .[#toc-http-method-check] diff --git a/application/bg/routing.texy b/application/bg/routing.texy index e71cd50516..26abc2fb5d 100644 --- a/application/bg/routing.texy +++ b/application/bg/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Или можем да използваме тази форма, като отбележим пренаписването на израза за регулярна проверка: +За по-подробна спецификация може да се използва още по-разширена форма, в която освен стойностите по подразбиране могат да се задават и други свойства на параметъра, например регулярен израз за валидиране (вж. параметъра `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Тези по-подробни формати са полезни за добавяне на повече метаданни. +Важно е да се отбележи, че ако параметрите, дефинирани в масива, не са включени в маската на пътя, техните стойности не могат да бъдат променени, дори и чрез използване на параметри на заявката, зададени след въпросителен знак в URL адреса. Филтри и преводи .[#toc-filters-and-translations] diff --git a/application/bg/templates.texy b/application/bg/templates.texy index 584b6cbff3..0be4f81857 100644 --- a/application/bg/templates.texy +++ b/application/bg/templates.texy @@ -285,7 +285,7 @@ protected function beforeRender(): void ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` След това транслаторът може да се използва например като филтър `|translate`, като на метода `translate()` се предават допълнителни параметри (вж. `foo, bar`): diff --git a/application/cs/ajax.texy b/application/cs/ajax.texy index 407622ab95..e9a0ee7835 100644 --- a/application/cs/ajax.texy +++ b/application/cs/ajax.texy @@ -77,6 +77,8 @@ npm install naja ``` +I v případě přímého vložení je nutné knihovnu [inicializovat |https://naja.js.org/#/guide/01-install-setup-naja?id=initialization]. + Aby se z obyčejného odkazu (signálu) nebo odeslání formuláře vytvořil AJAXový požadavek, stačí označit příslušný odkaz, formulář nebo tlačítko třídou `ajax`: ```html @@ -240,4 +242,4 @@ A handle metoda s odpovídajícími parametry v komponentě: public function handleFoo(int $bar): void { } -``` +``` \ No newline at end of file diff --git a/application/cs/bootstrap.texy b/application/cs/bootstrap.texy index a0b9db0792..7ed9569e3c 100644 --- a/application/cs/bootstrap.texy +++ b/application/cs/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Debugovací nástroj Tracy Pro snadné debugování ještě zapneme skvělý nástroj [Tracy |tracy:]. Ve vývojářském režimu chyby vizualizuje a v produkčním režimu chyby loguje do uvedeného adresáře: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Dočasné soubory Nette využívá cache pro DI kontejner, RobotLoader, šablony atd. Proto je nutné nastavit cestu k adresáři, kam se bude cache ukládat: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` Na Linuxu nebo macOS nastavte adresářům `log/` a `temp/` [práva pro zápis |nette:troubleshooting#Nastavení práv adresářů]. @@ -143,16 +143,16 @@ Ve vývojářském režimu se kontejner automaticky aktualizuje při každé zm Konfigurační soubory načteme pomocí `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Pokud chceme přidat více konfiguračních souborů, můžeme funkci `addConfig()` zavolat vícekrát. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ V konfiguračních souborech můžete využít tyto statické parametry: - `%wwwDir%` je absolutní cesta k adresáři se vstupním souborem `index.php` - `%tempDir%` je absolutní cesta k adresáři pro dočasné soubory - `%vendorDir%` je absolutní cesta k adresáři, kam Composer instaluje knihovny +- `%rootDir%` je absolutní cesta ke kořenovému adresáři projektu - `%debugMode%` udává, zda je aplikace v debugovacím režimu - `%consoleMode%` udává, zda request přišel přes příkazovou řádku diff --git a/application/cs/configuration.texy b/application/cs/configuration.texy index acab7d7adf..2e68ddd536 100644 --- a/application/cs/configuration.texy +++ b/application/cs/configuration.texy @@ -104,7 +104,7 @@ Pokud používáte Latte verze 3, můžete přidávat nové [rozšíření |latt ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Pokud používáte Latte verze 2, můžete registrovat nové tagy (makra) buď uvedením jména třídy, nebo referencí na službu. Jako výchozí je zavolána metoda `install()`, ale to lze změnit tím, že uvedeme jméno jiné metody: diff --git a/application/cs/presenters.texy b/application/cs/presenters.texy index 4936a85634..cb8a415b75 100644 --- a/application/cs/presenters.texy +++ b/application/cs/presenters.texy @@ -452,17 +452,6 @@ 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()`, `render()`, `handle()` a `createComponent()`. -Příklad použití pro omezení přístupu pouze HTTP metodou `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Můžete určit tyto omezení: - na HTTP metody: `#[Requires(methods: ['GET', 'POST'])]` - vyžadování AJAXového požadavku: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Můžete určit tyto omezení: - přístup pouze přes forward: `#[Requires(forward: true)]` - omezení na konkrétní akce: `#[Requires(actions: 'default')]` -Kombinovat podmínky lze uvedením více atributů nebo spojením do jednoho: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// nebo - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Podrobnosti najdete v návodu [Jak používat atribut Requires |best-practices:attribute-requires]. Kontrola HTTP metody diff --git a/application/cs/routing.texy b/application/cs/routing.texy index adb92c1cae..ac3cc3aa7a 100644 --- a/application/cs/routing.texy +++ b/application/cs/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Nebo můžeme použít tuto formu, všimněte si přepisu validačního regulárního výrazu: +Pro detailnější specifikaci lze použít ještě rozšířenější formu, kde kromě výchozích hodnot můžeme nastavit i další vlastnosti parametrů, jako třeba validační regulární výraz (viz parametr `id`): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Tyto upovídanější formáty se hodí pro doplnění dalších metadat. +Je důležité poznamenat, že pokud parametry definované v poli nejsou uvedeny v masce cesty, jejich hodnoty nelze změnit, ani pomocí query parametrů uvedených za otazníkem v URL. Filtry a překlady diff --git a/application/cs/templates.texy b/application/cs/templates.texy index 8caa687b44..470c68748b 100644 --- a/application/cs/templates.texy +++ b/application/cs/templates.texy @@ -285,7 +285,7 @@ Translator je alternativně možné nastavit pomocí [konfigurace |configuration ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Poté lze překladač používat například jako filtr `|translate`, a to včetně doplňujících parametrů, které se předají metodě `translate()` (viz `foo, bar`): diff --git a/application/de/bootstrap.texy b/application/de/bootstrap.texy index a5ddc1e604..6b1fa8f7e6 100644 --- a/application/de/bootstrap.texy +++ b/application/de/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Debugging-Werkzeug Tracy .[#toc-debugging-tool-tracy] Zur einfachen Fehlersuche werden wir das großartige Tool [Tracy |tracy:] einschalten. Im Entwicklermodus zeigt es Fehler an und im Produktionsmodus protokolliert es Fehler in das angegebene Verzeichnis: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Temporäre Dateien .[#toc-temporary-files] Nette verwendet den Cache für DI-Container, RobotLoader, Vorlagen usw. Daher ist es notwendig, den Pfad zu dem Verzeichnis festzulegen, in dem der Cache gespeichert werden soll: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` Unter Linux oder macOS setzen Sie die [Schreibrechte |nette:troubleshooting#Setting directory permissions] für die Verzeichnisse `log/` und `temp/`. @@ -143,16 +143,16 @@ Im Entwicklungsmodus wird der Container jedes Mal automatisch aktualisiert, wenn Konfigurationsdateien werden mit `addConfig()` geladen: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Die Methode `addConfig()` kann mehrfach aufgerufen werden, um mehrere Dateien hinzuzufügen. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ Sie können die folgenden statischen Parameter in den Konfigurationsdateien verw - `%wwwDir%` ist der absolute Pfad zu dem Verzeichnis, das die `index.php` Eintragsdatei enthält - `%tempDir%` ist der absolute Pfad zu dem Verzeichnis für temporäre Dateien - `%vendorDir%` ist der absolute Pfad zu dem Verzeichnis, in dem Composer die Bibliotheken installiert +- `%rootDir%` ist der absolute Pfad zum Stammverzeichnis des Projekts - `%debugMode%` gibt an, ob sich die Anwendung im Debug-Modus befindet - `%consoleMode%` zeigt an, ob die Anfrage über die Befehlszeile kam diff --git a/application/de/configuration.texy b/application/de/configuration.texy index d5b665b684..2ad3130b02 100644 --- a/application/de/configuration.texy +++ b/application/de/configuration.texy @@ -104,7 +104,7 @@ Wenn Sie Latte Version 3 verwenden, können Sie neue [Erweiterungen |latte:creat ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/de/presenters.texy b/application/de/presenters.texy index 2407021005..026ebee737 100644 --- a/application/de/presenters.texy +++ b/application/de/presenters.texy @@ -452,17 +452,6 @@ Zugangsbeschränkung mit `#[Requires]` .[#toc-access-restriction-using-requires] Das Attribut `#[Requires]` Attribut bietet erweiterte Optionen zur Einschränkung des Zugriffs auf Präsentatoren und ihre Methoden. Es kann verwendet werden, um HTTP-Methoden zu spezifizieren, AJAX-Anfragen zu verlangen, den Zugriff auf denselben Ursprung zu beschränken und den Zugriff nur auf Weiterleitungen zu beschränken. Das Attribut kann sowohl auf Presenter-Klassen als auch auf einzelne Methoden angewendet werden, z. B. `action()`, `render()`, `handle()`, und `createComponent()`. -Hier ein Beispiel für die Beschränkung des Zugriffs nur auf die Methode HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Sie können diese Einschränkungen angeben: - auf HTTP-Methoden: `#[Requires(methods: ['GET', 'POST'])]` - die eine AJAX-Anfrage erfordern: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Sie können diese Einschränkungen angeben: - Zugriff nur über Weiterleitung: `#[Requires(forward: true)]` - Einschränkungen für bestimmte Aktionen: `#[Requires(actions: 'default')]` -Bedingungen können kombiniert werden, indem mehrere Attribute aufgelistet oder zu einem einzigen zusammengefasst werden: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Für Einzelheiten siehe [Verwendung des Requires Attributs |best-practices:attribute-requires]. HTTP-Methodenprüfung .[#toc-http-method-check] diff --git a/application/de/routing.texy b/application/de/routing.texy index d398f7f759..f3b4ae88de 100644 --- a/application/de/routing.texy +++ b/application/de/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Oder wir können diese Form verwenden, beachten Sie die Umschreibung des regulären Ausdrucks für die Validierung: +Für eine detailliertere Spezifikation kann eine noch umfangreichere Form verwendet werden, bei der zusätzlich zu den Standardwerten weitere Parametereigenschaften festgelegt werden können, wie z. B. ein regulärer Ausdruck für die Validierung (siehe den Parameter `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Diese gesprächigeren Formate sind nützlich, um andere Metadaten hinzuzufügen. +Es ist wichtig zu beachten, dass, wenn die im Array definierten Parameter nicht in der Pfadmaske enthalten sind, ihre Werte nicht geändert werden können, auch nicht mit Abfrageparametern, die nach einem Fragezeichen in der URL angegeben werden. Filter und Übersetzungen .[#toc-filters-and-translations] diff --git a/application/de/templates.texy b/application/de/templates.texy index 8860819f5f..466cb501c3 100644 --- a/application/de/templates.texy +++ b/application/de/templates.texy @@ -285,7 +285,7 @@ Alternativ kann der Übersetzer auch über die [Konfiguration |configuration#Lat ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Der Übersetzer kann dann z.B. als Filter `|translate` verwendet werden, wobei zusätzliche Parameter an die Methode `translate()` übergeben werden (siehe `foo, bar`): diff --git a/application/el/bootstrap.texy b/application/el/bootstrap.texy index 7ee2f81c13..91cc3f41db 100644 --- a/application/el/bootstrap.texy +++ b/application/el/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ $configurator->setDebugMode(false); Για εύκολη αποσφαλμάτωση, θα ενεργοποιήσουμε το σπουδαίο εργαλείο [Tracy |tracy:]. Στη λειτουργία προγραμματιστή απεικονίζει τα σφάλματα και στη λειτουργία παραγωγής καταγράφει τα σφάλματα στον καθορισμένο κατάλογο: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ $configurator->enableTracy($appDir . '/log'); Η Nette χρησιμοποιεί την κρυφή μνήμη για το DI container, το RobotLoader, τα πρότυπα κ.λπ. Ως εκ τούτου, είναι απαραίτητο να ορίσετε τη διαδρομή προς τον κατάλογο όπου θα αποθηκεύεται η προσωρινή μνήμη: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` Σε Linux ή macOS, ορίστε τα [δικαιώματα εγγραφής |nette:troubleshooting#Setting directory permissions] για τους καταλόγους `log/` και `temp/`. @@ -143,16 +143,16 @@ $configurator->setTimeZone('Europe/Prague'); Τα αρχεία διαμόρφωσης φορτώνονται με τη χρήση του `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Η μέθοδος `addConfig()` μπορεί να κληθεί πολλές φορές για την προσθήκη πολλών αρχείων. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ $configurator->addDynamicParameters([ - `%wwwDir%` είναι η απόλυτη διαδρομή προς τον κατάλογο που περιέχει το αρχείο καταχώρησης `index.php` - `%tempDir%` είναι η απόλυτη διαδρομή προς τον κατάλογο για τα προσωρινά αρχεία - `%vendorDir%` είναι η απόλυτη διαδρομή προς τον κατάλογο όπου ο Composer εγκαθιστά τις βιβλιοθήκες +- `%rootDir%` είναι η απόλυτη διαδρομή προς τον ριζικό κατάλογο του έργου - Το `%debugMode%` δηλώνει αν η εφαρμογή βρίσκεται σε κατάσταση αποσφαλμάτωσης. - Το `%consoleMode%` δηλώνει αν η αίτηση υποβλήθηκε μέσω της γραμμής εντολών. diff --git a/application/el/configuration.texy b/application/el/configuration.texy index 99bea2563d..6f7ece692a 100644 --- a/application/el/configuration.texy +++ b/application/el/configuration.texy @@ -104,7 +104,7 @@ latte: ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/el/presenters.texy b/application/el/presenters.texy index 3f55886ec4..b2db7f0af6 100644 --- a/application/el/presenters.texy +++ b/application/el/presenters.texy @@ -452,17 +452,6 @@ $this->sendResponse(new Responses\CallbackResponse($callback)); Το `#[Requires]` παρέχει προηγμένες επιλογές για τον περιορισμό της πρόσβασης στους παρουσιαστές και τις μεθόδους τους. Μπορεί να χρησιμοποιηθεί για τον προσδιορισμό μεθόδων HTTP, την απαίτηση αιτήσεων AJAX, τον περιορισμό της πρόσβασης στην ίδια προέλευση και τον περιορισμό της πρόσβασης μόνο στην προώθηση. Το χαρακτηριστικό μπορεί να εφαρμοστεί σε κλάσεις παρουσιαστών καθώς και σε μεμονωμένες μεθόδους όπως οι `action()`, `render()`, `handle()`, και `createComponent()`. -Ακολουθεί ένα παράδειγμα χρήσης της για να περιορίσετε την πρόσβαση μόνο στη μέθοδο HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Μπορείτε να καθορίσετε αυτούς τους περιορισμούς: - σε μεθόδους HTTP: `#[Requires(methods: ['GET', 'POST'])]` - AJAX: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ class MyPresenter extends Nette\Application\UI\Presenter - πρόσβαση μόνο μέσω προώθησης: `#[Requires(forward: true)]` - περιορισμοί σε συγκεκριμένες ενέργειες: `#[Requires(actions: 'default')]` -Οι συνθήκες μπορούν να συνδυαστούν με την απαρίθμηση πολλαπλών χαρακτηριστικών ή με τη συνένωσή τους σε ένα: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Για λεπτομέρειες, ανατρέξτε στην ενότητα [Πώς να χρησιμοποιήσετε το Requires attribute |best-practices:attribute-requires]. Έλεγχος μεθόδου HTTP .[#toc-http-method-check] diff --git a/application/el/routing.texy b/application/el/routing.texy index cb79da06a4..78ebb607a0 100644 --- a/application/el/routing.texy +++ b/application/el/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Ή μπορούμε να χρησιμοποιήσουμε αυτή τη μορφή, παρατηρήστε την αναδιατύπωση της κανονικής έκφρασης επικύρωσης: +Για μια πιο λεπτομερή προδιαγραφή, μπορεί να χρησιμοποιηθεί μια ακόμη πιο εκτεταμένη μορφή, όπου εκτός από τις προεπιλεγμένες τιμές, μπορούν να οριστούν και άλλες ιδιότητες παραμέτρων, όπως μια κανονική έκφραση επικύρωσης (βλ. την παράμετρο `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Αυτές οι πιο ομιλητικές μορφές είναι χρήσιμες για την προσθήκη άλλων μεταδεδομένων. +Είναι σημαντικό να σημειωθεί ότι εάν οι παράμετροι που ορίζονται στον πίνακα δεν περιλαμβάνονται στη μάσκα διαδρομής, οι τιμές τους δεν μπορούν να αλλάξουν, ούτε καν με τη χρήση παραμέτρων ερωτήματος που καθορίζονται μετά από ένα ερωτηματικό στη διεύθυνση URL. Φίλτρα και μεταφράσεις .[#toc-filters-and-translations] diff --git a/application/el/templates.texy b/application/el/templates.texy index 39c2ddca2e..dfe884dd1b 100644 --- a/application/el/templates.texy +++ b/application/el/templates.texy @@ -285,7 +285,7 @@ protected function beforeRender(): void ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Ο μεταφραστής μπορεί στη συνέχεια να χρησιμοποιηθεί, για παράδειγμα, ως φίλτρο `|translate`, με πρόσθετες παραμέτρους που περνούν στη μέθοδο `translate()` (βλ. `foo, bar`): diff --git a/application/en/ajax.texy b/application/en/ajax.texy index a62ed95cfc..7ef5b0fa3d 100644 --- a/application/en/ajax.texy +++ b/application/en/ajax.texy @@ -77,6 +77,8 @@ npm install naja ``` +Even in this case it is necessary to [initialize |https://naja.js.org/#/guide/01-install-setup-naja?id=initialization] the library. + To make an ordinary link (signal) or form submission an AJAX request, simply mark the respective link, form, or button with the `ajax` class: ```html diff --git a/application/en/bootstrap.texy b/application/en/bootstrap.texy index 14a412cd6f..f0b54d49b9 100644 --- a/application/en/bootstrap.texy +++ b/application/en/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Debugging Tool Tracy For easy debugging, we will turn on the great tool [Tracy |tracy:]. In developer mode it visualizes errors and in production mode it logs errors to the specified directory: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Temporary Files Nette uses the cache for DI container, RobotLoader, templates, etc. Therefore it is necessary to set the path to the directory where the cache will be stored: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` On Linux or macOS, set the [write permissions |nette:troubleshooting#Setting directory permissions] for directories `log/` and `temp/`. @@ -143,16 +143,16 @@ In the development mode, the container is automatically updated each time you ch Configuration files are loaded using `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` The method `addConfig()` can be called multiple times to add multiple files. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ You can use the following static parameters in the configuration files: - `%wwwDir%` is the absolute path to the directory containing the `index.php` entry file - `%tempDir%` is the absolute path to the directory for temporary files - `%vendorDir%` is the absolute path to the directory where Composer installs libraries +- `%rootDir%` is the absolute path to the root directory of the project - `%debugMode%` indicates whether the application is in debug mode - `%consoleMode%` indicates whether the request came through the command line diff --git a/application/en/configuration.texy b/application/en/configuration.texy index fba71aa4fd..635e327897 100644 --- a/application/en/configuration.texy +++ b/application/en/configuration.texy @@ -104,7 +104,7 @@ If you are using Latte version 3, you can add new [extension |latte:creating-ext ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` If you are using Latte version 2, you can register new tags either by entering the class name or by referring to the service. Method `install()` is called by default, but this can be changed by specifying the name of another method: diff --git a/application/en/presenters.texy b/application/en/presenters.texy index 324d00441d..65a0dcf131 100644 --- a/application/en/presenters.texy +++ b/application/en/presenters.texy @@ -452,17 +452,6 @@ Access Restriction Using `#[Requires]` .{data-version:3.2.2} The `#[Requires]` attribute provides advanced options for restricting access to presenters and their methods. It can be used to specify HTTP methods, require AJAX requests, limit access to the same origin, and restrict access to forwarding only. The attribute can be applied to presenter classes as well as individual methods such as `action()`, `render()`, `handle()`, and `createComponent()`. -Here’s an example of using it to restrict access to only the HTTP `POST` method: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - You can specify these restrictions: - on HTTP methods: `#[Requires(methods: ['GET', 'POST'])]` - requiring an AJAX request: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ You can specify these restrictions: - access only via forwarding: `#[Requires(forward: true)]` - restrictions on specific actions: `#[Requires(actions: 'default')]` -Conditions can be combined by listing multiple attributes or by joining them into one: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +For details, see [How to use the Requires attribute |best-practices:attribute-requires]. HTTP Method Check diff --git a/application/en/routing.texy b/application/en/routing.texy index 9c49994566..f9af18510b 100644 --- a/application/en/routing.texy +++ b/application/en/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Or we can use this form, notice the rewriting of the validation regular expression: +For a more detailed specification, an even more extended form can be used, where in addition to default values, other parameter properties can be set, such as a validation regular expression (see the `id` parameter): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -These more talkative formats are useful for adding other metadata. +It is important to note that if the parameters defined in the array are not included in the path mask, their values cannot be changed, not even using query parameters specified after a question mark in the URL. Filters and Translations diff --git a/application/en/templates.texy b/application/en/templates.texy index 8069d6b23d..bdc524c4e4 100644 --- a/application/en/templates.texy +++ b/application/en/templates.texy @@ -285,7 +285,7 @@ Alternatively, the translator can be set using the [configuration |configuration ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` The translator can then be used, for example, as a filter `|translate`, with additional parameters passed to the `translate()` method (see `foo, bar`): diff --git a/application/es/bootstrap.texy b/application/es/bootstrap.texy index bed14d1d22..d1753e0a9f 100644 --- a/application/es/bootstrap.texy +++ b/application/es/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Herramienta de depuración Tracy .[#toc-debugging-tool-tracy] Para facilitar la depuración, activaremos la gran herramienta [Tracy |tracy:]. En modo desarrollador visualiza los errores y en modo producción los registra en el directorio especificado: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Archivos temporales .[#toc-temporary-files] Nette utiliza la caché para el contenedor DI, RobotLoader, plantillas, etc. Por lo tanto es necesario establecer la ruta al directorio donde se almacenará la caché: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` En Linux o macOS, establezca los [permisos de escritura |nette:troubleshooting#Setting directory permissions] para los directorios `log/` y `temp/`. @@ -143,16 +143,16 @@ En el modo de desarrollo, el contenedor se actualiza automáticamente cada vez q Los archivos de configuración se cargan utilizando `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` El método `addConfig()` se puede llamar varias veces para añadir varios archivos. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ Puede utilizar los siguientes parámetros estáticos en los archivos de configur - `%wwwDir%` es la ruta absoluta al directorio que contiene el archivo de entrada `index.php` - `%tempDir%` es la ruta absoluta al directorio para los archivos temporales - `%vendorDir%` es la ruta absoluta al directorio donde Composer instala las bibliotecas +- `%rootDir%` es la ruta absoluta al directorio raíz del proyecto - `%debugMode%` indica si la aplicación está en modo depuración - `%consoleMode%` indica si la solicitud llegó a través de la línea de comandos diff --git a/application/es/configuration.texy b/application/es/configuration.texy index bbde2bac4e..6a0da2c1f1 100644 --- a/application/es/configuration.texy +++ b/application/es/configuration.texy @@ -104,7 +104,7 @@ Si está utilizando la versión 3 de Latte, puede añadir una nueva [extensión ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/es/presenters.texy b/application/es/presenters.texy index 22cb178aa9..030cd85b9c 100644 --- a/application/es/presenters.texy +++ b/application/es/presenters.texy @@ -452,17 +452,6 @@ Restricción de acceso mediante `#[Requires]` .[#toc-access-restriction-using-re El atributo `#[Requires]` ofrece opciones avanzadas para restringir el acceso a los presentadores y sus métodos. Puede utilizarse para especificar métodos HTTP, requerir solicitudes AJAX, limitar el acceso al mismo origen y restringir el acceso sólo al reenvío. El atributo puede aplicarse a clases de presentadores, así como a métodos individuales como `action()`, `render()`, `handle()`y `createComponent()`. -He aquí un ejemplo de su uso para restringir el acceso únicamente al método HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Puede especificar estas restricciones - en los métodos HTTP: `#[Requires(methods: ['GET', 'POST'])]` - que requieren una petición AJAX: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Puede especificar estas restricciones - acceso sólo mediante reenvío: `#[Requires(forward: true)]` - restricciones sobre acciones específicas: `#[Requires(actions: 'default')]` -Las condiciones pueden combinarse enumerando varios atributos o uniéndolos en uno solo: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Para obtener más información, consulte [Cómo utilizar el atributo Requires atributo |best-practices:attribute-requires]. Comprobación del método HTTP .[#toc-http-method-check] diff --git a/application/es/routing.texy b/application/es/routing.texy index 8898449791..417438e650 100644 --- a/application/es/routing.texy +++ b/application/es/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -O podemos utilizar esta forma, observe la reescritura de la expresión regular de validación: +Para una especificación más detallada, se puede utilizar una forma aún más extendida, en la que además de los valores por defecto, se pueden establecer otras propiedades de los parámetros, como una expresión regular de validación (véase el parámetro `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Estos formatos más locuaces son útiles para añadir otros metadatos. +Es importante señalar que si los parámetros definidos en la matriz no se incluyen en la máscara de ruta, sus valores no podrán modificarse, ni siquiera utilizando parámetros de consulta especificados tras un signo de interrogación en la URL. Filtros y traducciones .[#toc-filters-and-translations] diff --git a/application/es/templates.texy b/application/es/templates.texy index 44a0bbeb7a..af06db6505 100644 --- a/application/es/templates.texy +++ b/application/es/templates.texy @@ -285,7 +285,7 @@ Alternativamente, el traductor se puede establecer utilizando la [configuración ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` El traductor puede utilizarse, por ejemplo, como un filtro `|translate`, con parámetros adicionales pasados al método `translate()` (véase `foo, bar`): diff --git a/application/fr/bootstrap.texy b/application/fr/bootstrap.texy index 3b80608880..dbe7e4bc85 100644 --- a/application/fr/bootstrap.texy +++ b/application/fr/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Outil de débogage Tracy .[#toc-debugging-tool-tracy] Pour faciliter le débogage, nous allons activer l'excellent outil [Tracy |tracy:]. En mode développeur, il visualise les erreurs et en mode production, il enregistre les erreurs dans le répertoire spécifié : ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Fichiers temporaires .[#toc-temporary-files] Nette utilise le cache pour le conteneur DI, RobotLoader, les modèles, etc. Il est donc nécessaire de définir le chemin d'accès au répertoire où le cache sera stocké : ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` Sous Linux ou macOS, définissez les [droits d'écriture |nette:troubleshooting#Setting directory permissions] pour les répertoires `log/` et `temp/`. @@ -143,16 +143,16 @@ En mode développement, le conteneur est automatiquement mis à jour chaque fois Les fichiers de configuration sont chargés à l'aide de `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` La méthode `addConfig()` peut être appelée plusieurs fois pour ajouter plusieurs fichiers. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ Vous pouvez utiliser les paramètres statiques suivants dans les fichiers de con - `%wwwDir%` est le chemin absolu vers le répertoire contenant le fichier d'entrée `index.php` - `%tempDir%` est le chemin absolu vers le répertoire des fichiers temporaires - `%vendorDir%` est le chemin absolu vers le répertoire où Composer installe les bibliothèques +- `%rootDir%` est le chemin absolu vers le répertoire racine du projet - `%debugMode%` indique si l'application est en mode débogage - `%consoleMode%` indique si la demande provient de la ligne de commande diff --git a/application/fr/configuration.texy b/application/fr/configuration.texy index 4398c0e7fe..5d6c1543fa 100644 --- a/application/fr/configuration.texy +++ b/application/fr/configuration.texy @@ -104,7 +104,7 @@ Si vous utilisez la version 3 de Latte, vous pouvez ajouter une nouvelle [extens ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/fr/presenters.texy b/application/fr/presenters.texy index bf1050cfa2..bb0010a1f0 100644 --- a/application/fr/presenters.texy +++ b/application/fr/presenters.texy @@ -452,17 +452,6 @@ Restriction d'accès à l'aide de `#[Requires]` .[#toc-access-restriction-using- L'attribut `#[Requires]` fournit des options avancées pour restreindre l'accès aux présentateurs et à leurs méthodes. Il peut être utilisé pour spécifier des méthodes HTTP, exiger des requêtes AJAX, limiter l'accès à la même origine et restreindre l'accès à la transmission uniquement. L'attribut peut être appliqué aux classes de présentateurs ainsi qu'aux méthodes individuelles telles que `action()`, `render()`, `handle()`, et `createComponent()`. -Voici un exemple d'utilisation pour restreindre l'accès à la seule méthode HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Vous pouvez spécifier ces restrictions : - sur les méthodes HTTP : `#[Requires(methods: ['GET', 'POST'])]` - nécessitant une requête AJAX : `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Vous pouvez spécifier ces restrictions : - accès uniquement par le biais d'une redirection : `#[Requires(forward: true)]` - restrictions sur des actions spécifiques : `#[Requires(actions: 'default')]` -Les conditions peuvent être combinées en énumérant plusieurs attributs ou en les réunissant en un seul : - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Pour plus de détails, voir [Comment utiliser l'attribut Requires |best-practices:attribute-requires]. Vérification de la méthode HTTP .[#toc-http-method-check] diff --git a/application/fr/routing.texy b/application/fr/routing.texy index 3f1cb29675..29541d7fb9 100644 --- a/application/fr/routing.texy +++ b/application/fr/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Ou nous pouvons utiliser cette forme, remarquez la réécriture de l'expression régulière de validation : +Pour une spécification plus détaillée, une forme encore plus étendue peut être utilisée, où en plus des valeurs par défaut, d'autres propriétés de paramètres peuvent être définies, telles qu'une expression régulière de validation (voir le paramètre `id` ) : ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Ces formats plus bavards sont utiles pour ajouter d'autres métadonnées. +Il est important de noter que si les paramètres définis dans le tableau ne sont pas inclus dans le masque de chemin, leurs valeurs ne peuvent pas être modifiées, même en utilisant des paramètres de requête spécifiés après un point d'interrogation dans l'URL. Filtres et traductions .[#toc-filters-and-translations] diff --git a/application/fr/templates.texy b/application/fr/templates.texy index dc2ccff07f..494ea2da09 100644 --- a/application/fr/templates.texy +++ b/application/fr/templates.texy @@ -285,7 +285,7 @@ Alternativement, le traducteur peut être défini à l'aide de la [configuration ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Le traducteur peut alors être utilisé, par exemple, comme un filtre `|translate`, avec des paramètres supplémentaires transmis à la méthode `translate()` (voir `foo, bar`) : diff --git a/application/hu/bootstrap.texy b/application/hu/bootstrap.texy index 1ef07fd756..49be7dca25 100644 --- a/application/hu/bootstrap.texy +++ b/application/hu/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Hibakereső eszköz Tracy .[#toc-debugging-tool-tracy] Az egyszerű hibakeresés érdekében bekapcsoljuk a [Tracy |tracy:] nevű nagyszerű eszközt. Fejlesztői módban megjeleníti a hibákat, termelési módban pedig a megadott könyvtárba naplózza a hibákat: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Ideiglenes fájlok .[#toc-temporary-files] A Nette a DI konténer, a RobotLoader, a sablonok stb. számára használja a gyorsítótárat. Ezért szükséges annak a könyvtárnak az elérési útvonalát beállítani, ahol a gyorsítótár tárolásra kerül: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` Linuxon vagy macOS-en állítsa be a `log/` és a `temp/` könyvtárak [írási engedélyeit |nette:troubleshooting#Setting directory permissions]. @@ -143,16 +143,16 @@ Fejlesztői üzemmódban a konténer automatikusan frissül minden alkalommal, a A konfigurációs fájlok betöltése a `addConfig()` segítségével történik: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` A `addConfig()` metódus többször is meghívható több fájl hozzáadásához. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ A konfigurációs fájlokban a következő statikus paramétereket használhatja - `%wwwDir%` a `index.php` beviteli fájlt tartalmazó könyvtár abszolút elérési útja. - `%tempDir%` az ideiglenes fájlok könyvtárának abszolút elérési útja. - `%vendorDir%` az abszolút elérési út a könyvtárak Composer általi telepítésének könyvtárához. +- `%rootDir%` a projekt gyökérkönyvtárának abszolút elérési útvonala. - `%debugMode%` jelzi, hogy az alkalmazás hibakeresési módban van-e. - `%consoleMode%` jelzi, hogy a kérés a parancssoron keresztül érkezett-e. diff --git a/application/hu/configuration.texy b/application/hu/configuration.texy index 2dc8e2a87a..f6bfe103f6 100644 --- a/application/hu/configuration.texy +++ b/application/hu/configuration.texy @@ -104,7 +104,7 @@ Ha a Latte 3. verzióját használja, akkor új [bővítményt |latte:creating-e ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/hu/presenters.texy b/application/hu/presenters.texy index f66a220e73..f38a06450a 100644 --- a/application/hu/presenters.texy +++ b/application/hu/presenters.texy @@ -452,17 +452,6 @@ Hozzáférés korlátozása `#[Requires]` .[#toc-access-restriction-using-requir A `#[Requires]` attribútum speciális lehetőségeket biztosít az előadókhoz és módszereikhez való hozzáférés korlátozására. Használható HTTP-módszerek megadására, AJAX-kérések megkövetelésére, az azonos eredetű hozzáférések korlátozására és a hozzáférésnek csak a továbbításra való korlátozására. Az attribútum alkalmazható a prezenter osztályokra, valamint az egyes metódusokra, mint például a `action()`, `render()`, `handle()`, és `createComponent()`. -Íme egy példa arra, hogy csak a HTTP `POST` módszerre korlátozzuk a hozzáférést: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Ezeket a korlátozásokat megadhatja: - a HTTP-módszerekre: `#[Requires(methods: ['GET', 'POST'])]` - AJAX-kérést igényel: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Ezeket a korlátozásokat megadhatja: - hozzáférés csak továbbítással: `#[Requires(forward: true)]` - korlátozások bizonyos műveletekre: `#[Requires(actions: 'default')]` -A feltételek kombinálhatók több attribútum felsorolásával vagy azok egyesítésével: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +A részletekért lásd [Hogyan használjuk a Requires attribútum használata |best-practices:attribute-requires]. HTTP módszer ellenőrzése .[#toc-http-method-check] diff --git a/application/hu/routing.texy b/application/hu/routing.texy index c2b8f71eda..bb4a347148 100644 --- a/application/hu/routing.texy +++ b/application/hu/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Vagy használhatjuk ezt a formát, vegyük észre az érvényesítési reguláris kifejezés átírását: +Részletesebb specifikációhoz egy még bővebb formát lehet használni, ahol az alapértelmezett értékek mellett más paramétertulajdonságok is megadhatók, például egy érvényesítési reguláris kifejezés (lásd a `id` paramétert): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Ezek a beszédesebb formátumok hasznosak más metaadatok hozzáadásához. +Fontos megjegyezni, hogy ha a tömbben definiált paraméterek nem szerepelnek az elérési útvonal maszkjában, akkor értékük nem módosítható, még az URL-ben kérdőjel után megadott lekérdezési paraméterekkel sem. Szűrők és fordítások .[#toc-filters-and-translations] diff --git a/application/hu/templates.texy b/application/hu/templates.texy index d51d03bbc6..3f46d2d377 100644 --- a/application/hu/templates.texy +++ b/application/hu/templates.texy @@ -285,7 +285,7 @@ Alternatívaként a fordítót a [konfiguráció |configuration#Latte] segítsé ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` A fordító ekkor például a `|translate` szűrőként használható, a `translate()` metódusnak átadott további paraméterekkel (lásd `foo, bar`): diff --git a/application/it/bootstrap.texy b/application/it/bootstrap.texy index b2c87a4373..4459c3c534 100644 --- a/application/it/bootstrap.texy +++ b/application/it/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Strumento di debug Tracy .[#toc-debugging-tool-tracy] Per facilitare il debug, attiviamo l'ottimo strumento [Tracy |tracy:]. In modalità sviluppatore visualizza gli errori e in modalità produzione li registra nella directory specificata: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ File temporanei .[#toc-temporary-files] Nette utilizza la cache per il contenitore DI, il RobotLoader, i modelli, ecc. Per questo motivo è necessario impostare il percorso della cartella in cui verrà memorizzata la cache: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` Su Linux o macOS, impostare i [permessi di scrittura |nette:troubleshooting#Setting directory permissions] per le directory `log/` e `temp/`. @@ -143,16 +143,16 @@ In modalità di sviluppo, il contenitore viene aggiornato automaticamente ogni v I file di configurazione vengono caricati usando `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Il metodo `addConfig()` può essere richiamato più volte per aggiungere più file. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ Parametri predefiniti .[#toc-default-parameters] - `%wwwDir%` è il percorso assoluto della directory contenente il file di ingresso `index.php` - `%tempDir%` è il percorso assoluto della directory per i file temporanei - `%vendorDir%` è il percorso assoluto della directory in cui Composer installa le librerie +- `%rootDir%` è il percorso assoluto della directory principale del progetto - `%debugMode%` indica se l'applicazione è in modalità debug - `%consoleMode%` indica se la richiesta è arrivata attraverso la riga di comando diff --git a/application/it/configuration.texy b/application/it/configuration.texy index be8d2ebc12..f9cb13b6fd 100644 --- a/application/it/configuration.texy +++ b/application/it/configuration.texy @@ -104,7 +104,7 @@ Se si utilizza la versione 3 di Latte, è possibile aggiungere nuove [estensioni ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/it/presenters.texy b/application/it/presenters.texy index 874bdb7ccf..fd2970ef16 100644 --- a/application/it/presenters.texy +++ b/application/it/presenters.texy @@ -452,17 +452,6 @@ Limitazione dell'accesso tramite `#[Requires]` .[#toc-access-restriction-using-r L'attributo `#[Requires]` fornisce opzioni avanzate per limitare l'accesso ai presentatori e ai loro metodi. Può essere usato per specificare metodi HTTP, richiedere richieste AJAX, limitare l'accesso alla stessa origine e limitare l'accesso al solo inoltro. L'attributo può essere applicato alle classi di presentatori e ai singoli metodi, come ad esempio `action()`, `render()`, `handle()`, e `createComponent()`. -Ecco un esempio di utilizzo per limitare l'accesso al solo metodo HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - È possibile specificare queste restrizioni: - sui metodi HTTP: `#[Requires(methods: ['GET', 'POST'])]` - che richiedono una richiesta AJAX: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ class MyPresenter extends Nette\Application\UI\Presenter - accesso solo tramite inoltro: `#[Requires(forward: true)]` - restrizioni su azioni specifiche: `#[Requires(actions: 'default')]` -Le condizioni possono essere combinate elencando più attributi o unendoli in uno solo: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Per i dettagli, vedere [Come usare l'attributo Requires |best-practices:attributo-requisiti]. Controllo del metodo HTTP .[#toc-http-method-check] diff --git a/application/it/routing.texy b/application/it/routing.texy index 128e2edf26..f938a3e902 100644 --- a/application/it/routing.texy +++ b/application/it/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Oppure possiamo usare questa forma, notando la riscrittura dell'espressione regolare di validazione: +Per una specifica più dettagliata, si può usare una forma ancora più estesa, in cui oltre ai valori predefiniti si possono impostare altre proprietà dei parametri, come un'espressione regolare di validazione (vedere il parametro `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Questi formati più loquaci sono utili per aggiungere altri metadati. +È importante notare che se i parametri definiti nell'array non sono inclusi nella maschera del percorso, i loro valori non possono essere modificati, nemmeno utilizzando i parametri di query specificati dopo un punto interrogativo nell'URL. Filtri e traduzioni .[#toc-filters-and-translations] diff --git a/application/it/templates.texy b/application/it/templates.texy index 2d3412da33..55e31fa8b9 100644 --- a/application/it/templates.texy +++ b/application/it/templates.texy @@ -285,7 +285,7 @@ In alternativa, il traduttore può essere impostato utilizzando la [configurazio ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Il traduttore può essere utilizzato, ad esempio, come filtro `|translate`, con parametri aggiuntivi passati al metodo `translate()` (vedere `foo, bar`): diff --git a/application/pl/bootstrap.texy b/application/pl/bootstrap.texy index 4b23e1f658..cfbd2d5f09 100644 --- a/application/pl/bootstrap.texy +++ b/application/pl/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Narzędzie do debugowania Tracy .[#toc-debugging-tool-tracy] Aby ułatwić debugowanie, włączmy wspaniałe narzędzie [Tracy |tracy:]. Wizualizuje błędy w trybie deweloperskim i loguje błędy w trybie produkcyjnym do podanego katalogu: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Pliki tymczasowe .[#toc-temporary-files] Nette używa buforowania dla kontenera DI, RobotLoader, szablonów itp. Dlatego musisz ustawić ścieżkę do katalogu, w którym będzie przechowywany cache: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` W systemach Linux lub macOS ustaw katalogi `log/` i `temp/` na uprawnienia do [zapisu |nette:troubleshooting#Setting-Directory-Permissions]. @@ -143,16 +143,16 @@ W trybie deweloperskim kontener jest automatycznie aktualizowany przy każdej zm Pliki konfiguracyjne są ładowane za pomocą `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Jeśli chcemy dodać więcej plików konfiguracyjnych, możemy wywołać funkcję `addConfig()` wielokrotnie. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ W plikach konfiguracyjnych można używać następujących parametrów statyczny - `%wwwDir%` jest bezwzględną ścieżką do katalogu zawierającego plik wejściowy `index.php` - `%tempDir%` jest bezwzględną ścieżką do katalogu plików tymczasowych - `%vendorDir%` to bezwzględna ścieżka do katalogu, w którym Composer instaluje biblioteki +- `%rootDir%` to bezwzględna ścieżka do katalogu głównego projektu - `%debugMode%` wskazuje, czy aplikacja jest w trybie debugowania - `%consoleMode%` wskazuje, czy żądanie przyszło z linii poleceń diff --git a/application/pl/configuration.texy b/application/pl/configuration.texy index 7986b64e24..faf5417f94 100644 --- a/application/pl/configuration.texy +++ b/application/pl/configuration.texy @@ -104,7 +104,7 @@ Jeśli używasz Latte w wersji 3, możesz dodać nowe [rozszerzenia |latte:creat ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/pl/presenters.texy b/application/pl/presenters.texy index 62d76b71a0..7f366882c7 100644 --- a/application/pl/presenters.texy +++ b/application/pl/presenters.texy @@ -452,17 +452,6 @@ Ograniczenie dostępu przy użyciu `#[Requires]` .[#toc-access-restriction-using Atrybut `#[Requires]` zapewnia zaawansowane opcje ograniczania dostępu do prezenterów i ich metod. Można go użyć do określenia metod HTTP, wymagania żądań AJAX, ograniczenia dostępu do tego samego źródła i ograniczenia dostępu tylko do przekazywania. Atrybut może być stosowany do klas prezenterów, jak również poszczególnych metod, takich jak `action()`, `render()`, `handle()`, i `createComponent()`. -Oto przykład użycia go do ograniczenia dostępu tylko do metody HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Można określić te ograniczenia: - na metodach HTTP: `#[Requires(methods: ['GET', 'POST'])]` - wymagające żądania AJAX: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Można określić te ograniczenia: - dostęp tylko przez przekierowanie: `#[Requires(forward: true)]` - ograniczenia dotyczące określonych działań: `#[Requires(actions: 'default')]` -Warunki można łączyć, wymieniając wiele atrybutów lub łącząc je w jeden: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Aby uzyskać szczegółowe informacje, zobacz [Jak używać atrybutu Requires atrybut |best-practices:attribute-requires]. Sprawdzanie metod HTTP .[#toc-http-method-check] diff --git a/application/pl/routing.texy b/application/pl/routing.texy index 699114b6e0..ede7479898 100644 --- a/application/pl/routing.texy +++ b/application/pl/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Możemy też użyć tego formularza, zauważając nadpisanie wyrażenia regularnego walidacji: +Aby uzyskać bardziej szczegółową specyfikację, można użyć jeszcze bardziej rozszerzonej formy, w której oprócz wartości domyślnych można ustawić inne właściwości parametru, takie jak wyrażenie regularne walidacji (patrz parametr `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Te bardziej verbose formaty są przydatne do dodawania dodatkowych metadanych. +Ważne jest, aby pamiętać, że jeśli parametry zdefiniowane w tablicy nie są zawarte w masce ścieżki, ich wartości nie mogą zostać zmienione, nawet przy użyciu parametrów zapytania określonych po znaku zapytania w adresie URL. Filtry i tłumaczenia .[#toc-filters-and-translations] diff --git a/application/pl/templates.texy b/application/pl/templates.texy index cb89c8cf68..51705f00d3 100644 --- a/application/pl/templates.texy +++ b/application/pl/templates.texy @@ -285,7 +285,7 @@ Alternatywnie, tłumacz może być ustawiony za pomocą [konfiguracji |configura ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Translator może być wtedy użyty np. jako filtr `|translate`, z dodatkowymi parametrami przekazywanymi do metody `translate()` (patrz `foo, bar`): diff --git a/application/pt/bootstrap.texy b/application/pt/bootstrap.texy index 85dca58e88..e95d09a093 100644 --- a/application/pt/bootstrap.texy +++ b/application/pt/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Ferramenta de depuração Tracy .[#toc-debugging-tool-tracy] Para facilitar a depuração, vamos acionar a grande ferramenta [Tracy |tracy:]. No modo desenvolvedor ela visualiza os erros e no modo de produção registra os erros no diretório especificado: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Arquivos temporários .[#toc-temporary-files] Nette utiliza o cache para contêiner DI, RobotLoader, modelos, etc. Portanto, é necessário definir o caminho para o diretório onde o cache será armazenado: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` No Linux ou macOS, defina as [permissões de escrita |nette:troubleshooting#Setting directory permissions] para os diretórios `log/` e `temp/`. @@ -143,16 +143,16 @@ No modo de desenvolvimento, o recipiente é atualizado automaticamente cada vez Os arquivos de configuração são carregados usando `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` O método `addConfig()` pode ser chamado várias vezes para adicionar vários arquivos. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ Você pode usar os seguintes parâmetros estáticos nos arquivos de configuraç - `%wwwDir%` é o caminho absoluto para o diretório que contém o arquivo de entrada `index.php` - `%tempDir%` é o caminho absoluto para o diretório de arquivos temporários - `%vendorDir%` é o caminho absoluto para o diretório onde o Composer instala as bibliotecas +- `%rootDir%` é o caminho absoluto para o diretório raiz do projeto - `%debugMode%` indica se a aplicação está em modo de depuração - `%consoleMode%` indica se o pedido veio através da linha de comando diff --git a/application/pt/configuration.texy b/application/pt/configuration.texy index d83543aca8..a0ab9934ca 100644 --- a/application/pt/configuration.texy +++ b/application/pt/configuration.texy @@ -104,7 +104,7 @@ Se você estiver usando Latte versão 3, você pode adicionar uma nova [extensã ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/pt/presenters.texy b/application/pt/presenters.texy index 655e650b6f..58df8e8539 100644 --- a/application/pt/presenters.texy +++ b/application/pt/presenters.texy @@ -452,17 +452,6 @@ Restrição de acesso usando `#[Requires]` .[#toc-access-restriction-using-requi O atributo `#[Requires]` fornece opções avançadas para restringir o acesso aos apresentadores e seus métodos. Ele pode ser usado para especificar métodos HTTP, exigir solicitações AJAX, limitar o acesso à mesma origem e restringir o acesso somente ao encaminhamento. O atributo pode ser aplicado a classes de apresentadores, bem como a métodos individuais, como `action()`, `render()`, `handle()`, e `createComponent()`. -Veja a seguir um exemplo de uso para restringir o acesso apenas ao método HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Você pode especificar essas restrições: - em métodos HTTP: `#[Requires(methods: ['GET', 'POST'])]` - que exigem uma solicitação AJAX: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Você pode especificar essas restrições: - acesso somente por meio de encaminhamento: `#[Requires(forward: true)]` - restrições a ações específicas: `#[Requires(actions: 'default')]` -As condições podem ser combinadas listando vários atributos ou unindo-os em um só: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Para obter detalhes, consulte [Como usar o atributo Requires |best-practices:attribute-requires]. Verificação do método HTTP .[#toc-http-method-check] diff --git a/application/pt/routing.texy b/application/pt/routing.texy index d9c249abe6..6a81076903 100644 --- a/application/pt/routing.texy +++ b/application/pt/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Ou podemos usar este formulário, observando a reescrita da expressão regular de validação: +Para uma especificação mais detalhada, é possível usar um formulário ainda mais extenso, no qual, além dos valores padrão, outras propriedades de parâmetro podem ser definidas, como uma expressão regular de validação (consulte o parâmetro `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Estes formatos mais faladores são úteis para adicionar outros metadados. +É importante observar que, se os parâmetros definidos na matriz não estiverem incluídos na máscara de caminho, seus valores não poderão ser alterados, nem mesmo usando parâmetros de consulta especificados após um ponto de interrogação no URL. Filtros e Traduções .[#toc-filters-and-translations] diff --git a/application/pt/templates.texy b/application/pt/templates.texy index 75e73e1d98..2886c6740e 100644 --- a/application/pt/templates.texy +++ b/application/pt/templates.texy @@ -285,7 +285,7 @@ Alternativamente, o tradutor pode ser definido usando a [configuração |configu ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` O tradutor pode então ser usado, por exemplo, como um filtro `|translate`, com parâmetros adicionais passados para o método `translate()` (ver `foo, bar`): diff --git a/application/ro/bootstrap.texy b/application/ro/bootstrap.texy index a13e217c3c..9daa091f0e 100644 --- a/application/ro/bootstrap.texy +++ b/application/ro/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Instrumentul de depanare Tracy .[#toc-debugging-tool-tracy] Pentru o depanare mai ușoară, vom porni minunata unealtă [Tracy |tracy:]. În modul dezvoltator, acesta vizualizează erorile, iar în modul de producție înregistrează erorile în directorul specificat: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Temporary Files .[#toc-temporary-files] Nette utilizează memoria cache pentru DI container, RobotLoader, șabloane etc. Prin urmare, este necesar să setați calea către directorul în care va fi stocată memoria cache: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` Pe Linux sau macOS, setați [permisiunile de scriere |nette:troubleshooting#Setting directory permissions] pentru directoarele `log/` și `temp/`. @@ -143,16 +143,16 @@ Fișierele de configurare sunt de obicei scrise în [formatul NEON |neon:format] Fișierele de configurare sunt încărcate utilizând `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Metoda `addConfig()` poate fi apelată de mai multe ori pentru a adăuga mai multe fișiere. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ Puteți utiliza următorii parametri statici în fișierele de configurare: - `%wwwDir%` este calea absolută către directorul care conține fișierul de intrare `index.php` - `%tempDir%` este calea absolută către directorul pentru fișierele temporare - `%vendorDir%` este calea absolută către directorul în care Composer instalează bibliotecile +- `%rootDir%` este calea absolută către directorul rădăcină al proiectului - `%debugMode%` indică dacă aplicația se află în modul de depanare - `%consoleMode%` indică dacă cererea a venit prin linia de comandă diff --git a/application/ro/configuration.texy b/application/ro/configuration.texy index 4783df2ade..f7c610ea87 100644 --- a/application/ro/configuration.texy +++ b/application/ro/configuration.texy @@ -104,7 +104,7 @@ Dacă utilizați Latte versiunea 3, puteți adăuga o nouă [extensie |latte:cre ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/ro/presenters.texy b/application/ro/presenters.texy index 76c214a56a..ff6009176f 100644 --- a/application/ro/presenters.texy +++ b/application/ro/presenters.texy @@ -452,17 +452,6 @@ Restricții de acces Utilizarea `#[Requires]` .[#toc-access-restriction-using-re Aplicația `#[Requires]` oferă opțiuni avansate pentru restricționarea accesului la prezentatori și la metodele acestora. Acesta poate fi utilizat pentru a specifica metodele HTTP, pentru a solicita cereri AJAX, pentru a limita accesul la aceeași origine și pentru a restricționa accesul doar la redirecționare. Atributul poate fi aplicat atât claselor de prezentatori, cât și metodelor individuale, cum ar fi `action()`, `render()`, `handle()`, și `createComponent()`. -Iată un exemplu de utilizare pentru a restricționa accesul doar la metoda HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Puteți specifica aceste restricții: - pe metodele HTTP: `#[Requires(methods: ['GET', 'POST'])]` - care necesită o cerere AJAX: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Puteți specifica aceste restricții: - acces numai prin redirecționare: `#[Requires(forward: true)]` - restricții privind anumite acțiuni: `#[Requires(actions: 'default')]` -Condițiile pot fi combinate prin enumerarea mai multor atribute sau prin unirea lor într-unul singur: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Pentru detalii, consultați [Cum se utilizează Requires |best-practices:attribute-requires]. Verificarea metodei HTTP .[#toc-http-method-check] diff --git a/application/ro/routing.texy b/application/ro/routing.texy index 125ac60d22..d70bec707c 100644 --- a/application/ro/routing.texy +++ b/application/ro/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Sau putem folosi această formă, observați rescrierea expresiei regulate de validare: +Pentru o specificație mai detaliată, se poate utiliza o formă și mai extinsă, în care, pe lângă valorile implicite, pot fi stabilite și alte proprietăți ale parametrilor, cum ar fi o expresie regulată de validare (a se vedea parametrul `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Aceste formate mai vorbărețe sunt utile pentru adăugarea altor metadate. +Este important de reținut faptul că, dacă parametrii definiți în matrice nu sunt incluși în masca de cale, valorile lor nu pot fi modificate, nici măcar folosind parametrii de interogare specificați după un semn de întrebare în URL. Filtre și traduceri .[#toc-filters-and-translations] diff --git a/application/ro/templates.texy b/application/ro/templates.texy index a12657b6f9..043a5fb016 100644 --- a/application/ro/templates.texy +++ b/application/ro/templates.texy @@ -285,7 +285,7 @@ Alternativ, traducătorul poate fi setat cu ajutorul [configurației |configurat ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Traducătorul poate fi apoi utilizat, de exemplu, ca filtru `|translate`, cu parametri suplimentari trecuți la metoda `translate()` (a se vedea `foo, bar`): diff --git a/application/ru/bootstrap.texy b/application/ru/bootstrap.texy index 6e041613e9..a0036cf7a1 100644 --- a/application/ru/bootstrap.texy +++ b/application/ru/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ $configurator->setDebugMode(false); Для облегчения отладки мы включим замечательный инструмент [Tracy |tracy:]. В режиме разработчика он визуализирует ошибки, а в режиме производства — записывает ошибки в указанный каталог: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ $configurator->enableTracy($appDir . '/log'); Nette использует кэш для DI-контейнера, RobotLoader, шаблонов и т. д. Поэтому необходимо задать путь к директории, где будет храниться кэш: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` В Linux или macOS установите [права на запись |nette:troubleshooting#Setting-Directory-Permissions] для каталогов `log/` и `temp/`. @@ -143,16 +143,16 @@ $configurator->setTimeZone('Europe/Prague'); Файлы конфигурации загружаются с помощью `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Метод `addConfig()` может быть вызван несколько раз для добавления нескольких файлов. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ $configurator->addDynamicParameters([ - `%wwwDir%` - абсолютный путь к директории, содержащей входной файл `index.php` - `%tempDir%` - абсолютный путь к директории для временных файлов. - `%vendorDir%` - абсолютный путь к директории, в которую Composer устанавливает библиотеки. +- `%rootDir%` - абсолютный путь к корневому каталогу проекта. - `%debugMode%` указывает, находится ли приложение в режиме отладки - `%consoleMode%` указывает, поступил ли запрос через командную строку diff --git a/application/ru/configuration.texy b/application/ru/configuration.texy index 9cb80fc192..75bc92436d 100644 --- a/application/ru/configuration.texy +++ b/application/ru/configuration.texy @@ -104,7 +104,7 @@ latte: ```neon latte: расширения: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/ru/presenters.texy b/application/ru/presenters.texy index 1e75735ac8..e2341e5446 100644 --- a/application/ru/presenters.texy +++ b/application/ru/presenters.texy @@ -452,17 +452,6 @@ $this->sendResponse(new Responses\CallbackResponse($callback)); Атрибут `#[Requires]` предоставляет расширенные возможности для ограничения доступа к ведущим и их методам. С его помощью можно указать HTTP-методы, потребовать AJAX-запросы, ограничить доступ к одному и тому же источнику и ограничить доступ только пересылкой. Атрибут может применяться как к классам ведущих, так и к отдельным методам, таким как `action()`, `render()`, `handle()`, и `createComponent()`. -Вот пример использования этого метода для ограничения доступа только к методу HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Вы можете указать эти ограничения: - на методы HTTP: `#[Requires(methods: ['GET', 'POST'])]` - требующих AJAX-запроса: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ class MyPresenter extends Nette\Application\UI\Presenter - доступ только через переадресацию: `#[Requires(forward: true)]` - ограничения на определенные действия: `#[Requires(actions: 'default')]` -Условия можно комбинировать, перечисляя несколько атрибутов или объединяя их в один: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Подробнее см. в разделе [Как использовать Requires атрибут |best-practices:attribute-requires]. Проверка метода HTTP .[#toc-http-method-check] diff --git a/application/ru/routing.texy b/application/ru/routing.texy index 0e90a2aca6..3363e2d1d5 100644 --- a/application/ru/routing.texy +++ b/application/ru/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Или мы можем использовать эту форму, обратите внимание на переписывание регулярного выражения проверки: +Для более детальной спецификации можно использовать еще более расширенную форму, в которой помимо значений по умолчанию можно задать другие свойства параметров, например, регулярное выражение для проверки (см. параметр `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Эти более подробные форматы полезны для добавления дополнительных метаданных. +Важно отметить, что если параметры, определенные в массиве, не включены в маску пути, их значения не могут быть изменены, даже с помощью параметров запроса, указанных после вопросительного знака в URL. Фильтры и переводы .[#toc-filters-and-translations] diff --git a/application/ru/templates.texy b/application/ru/templates.texy index f506d32046..4be9f83e4d 100644 --- a/application/ru/templates.texy +++ b/application/ru/templates.texy @@ -285,7 +285,7 @@ protected function beforeRender(): void ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Транслятор можно использовать, например, в качестве фильтра `|translate`, передав дополнительные параметры в метод `translate()` (см. `foo, bar`): diff --git a/application/sl/bootstrap.texy b/application/sl/bootstrap.texy index 840ebe2ab6..81ef42aa3d 100644 --- a/application/sl/bootstrap.texy +++ b/application/sl/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Orodje za razhroščevanje Tracy .[#toc-debugging-tool-tracy] Za lažje razhroščevanje bomo vklopili odlično orodje [Tracy |tracy:]. V načinu za razvijalce vizualizira napake, v produkcijskem načinu pa napake beleži v določen imenik: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Začasne datoteke .[#toc-temporary-files] Nette uporablja predpomnilnik za vsebnik DI, RobotLoader, predloge itd. Zato je treba nastaviti pot do imenika, v katerem bo shranjen predpomnilnik: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` V operacijskem sistemu Linux ali macOS nastavite [dovoljenja za pisanje za |nette:troubleshooting#Setting directory permissions] imenike `log/` in `temp/`. @@ -143,16 +143,16 @@ V razvojnem načinu se vsebnik samodejno posodobi vsakič, ko spremenite kodo al Konfiguracijske datoteke se naložijo z uporabo `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Metodo `addConfig()` lahko za dodajanje več datotek pokličete večkrat. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ V konfiguracijskih datotekah lahko uporabite naslednje statične parametre: - `%wwwDir%` je absolutna pot do imenika, ki vsebuje vstopno datoteko `index.php` - `%tempDir%` je absolutna pot do imenika za začasne datoteke - `%vendorDir%` je absolutna pot do imenika, v katerega Composer namesti knjižnice +- `%rootDir%` je absolutna pot do korenskega imenika projekta - `%debugMode%` označuje, ali je aplikacija v načinu odpravljanja napak - `%consoleMode%` označuje, ali je bila zahteva poslana prek ukazne vrstice diff --git a/application/sl/configuration.texy b/application/sl/configuration.texy index b12fdcd385..d6500dbcf7 100644 --- a/application/sl/configuration.texy +++ b/application/sl/configuration.texy @@ -104,7 +104,7 @@ latte: ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/sl/presenters.texy b/application/sl/presenters.texy index 8e33a702e0..d966db6fab 100644 --- a/application/sl/presenters.texy +++ b/application/sl/presenters.texy @@ -452,17 +452,6 @@ Omejitev dostopa z uporabo `#[Requires]` .[#toc-access-restriction-using-require . `#[Requires]` atribut zagotavlja napredne možnosti za omejevanje dostopa do predavateljev in njihovih metod. Z njim lahko določite metode HTTP, zahtevate zahteve AJAX, omejite dostop do istega izvora in omejite dostop samo na posredovanje. Atribut je mogoče uporabiti za razrede predstavnikov in posamezne metode, kot so `action()`, `render()`, `handle()`, in `createComponent()`. -Tukaj je primer uporabe za omejitev dostopa samo na metodo HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Določite lahko te omejitve: - za metode HTTP: `#[Requires(methods: ['GET', 'POST'])]` - ki zahteva zahtevo AJAX: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Določite lahko te omejitve: - dostop samo prek posredovanja: `#[Requires(forward: true)]` - omejitve za določena dejanja: `#[Requires(actions: 'default')]` -Pogoje lahko združite tako, da navedete več atributov ali jih združite v enega: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Za podrobnosti glejte [Kako uporabljati Requires atribut | Best-practices:attribute-requires]. Preverjanje metode HTTP .[#toc-http-method-check] diff --git a/application/sl/routing.texy b/application/sl/routing.texy index 6430a8c631..bea1f8c1b6 100644 --- a/application/sl/routing.texy +++ b/application/sl/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Lahko pa uporabimo tudi to obliko, pri čemer opazimo prepisovanje regularnega izraza za preverjanje: +Za podrobnejšo specifikacijo je mogoče uporabiti še bolj razširjeno obliko, v kateri lahko poleg privzetih vrednosti nastavite tudi druge lastnosti parametrov, na primer regularni izraz za preverjanje (glejte parameter `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Te bolj zgovorne oblike so uporabne za dodajanje drugih metapodatkov. +Pomembno je opozoriti, da če parametri, opredeljeni v polju, niso vključeni v masko poti, njihovih vrednosti ni mogoče spremeniti, niti z uporabo parametrov poizvedbe, določenih za vprašalnim znakom v naslovu URL. Filtri in prevodi .[#toc-filters-and-translations] diff --git a/application/sl/templates.texy b/application/sl/templates.texy index 966b1524a2..06c0ddeb10 100644 --- a/application/sl/templates.texy +++ b/application/sl/templates.texy @@ -285,7 +285,7 @@ Prevajalnik lahko nastavimo tudi s [konfiguracijo |configuration#Latte]: ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Prevajalnik lahko nato uporabimo na primer kot filter `|translate`, pri čemer metodi `translate()` posredujemo dodatne parametre (glej `foo, bar`): diff --git a/application/tr/bootstrap.texy b/application/tr/bootstrap.texy index 98cf02a208..89a829e55b 100644 --- a/application/tr/bootstrap.texy +++ b/application/tr/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ Hata Ayıklama Aracı Tracy .[#toc-debugging-tool-tracy] Kolay hata ayıklama için harika araç [Tracy'yi |tracy:] açacağız. Geliştirici modunda hataları görselleştirir ve üretim modunda hataları belirtilen dizine kaydeder: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ Geçici Dosyalar .[#toc-temporary-files] Nette, DI konteyneri, RobotLoader, şablonlar vb. için önbelleği kullanır. Bu nedenle, önbelleğin depolanacağı dizinin yolunu ayarlamak gerekir: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` Linux veya macOS üzerinde, `log/` ve `temp/` dizinleri için [yazma izinlerini |nette:troubleshooting#Setting directory permissions] ayarlayın. @@ -143,16 +143,16 @@ Geliştirme modunda, kodu veya yapılandırma dosyalarını her değiştirdiğin Yapılandırma dosyaları `addConfig()` kullanılarak yüklenir: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Birden fazla dosya eklemek için `addConfig()` yöntemi birden fazla kez çağrılabilir. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ Yapılandırma dosyalarında aşağıdaki statik parametreleri kullanabilirsiniz - `%wwwDir%`, `index.php` giriş dosyasını içeren dizinin mutlak yoludur - `%tempDir%` geçici dosyalar için dizinin mutlak yoludur - `%vendorDir%` Composer'ın kütüphaneleri yüklediği dizinin mutlak yoludur +- `%rootDir%` projenin kök dizinine giden mutlak yoldur - `%debugMode%` uygulamanın hata ayıklama modunda olup olmadığını gösterir - `%consoleMode%` isteğin komut satırı üzerinden gelip gelmediğini gösterir diff --git a/application/tr/configuration.texy b/application/tr/configuration.texy index 2f1ed45c00..1a58f32f7d 100644 --- a/application/tr/configuration.texy +++ b/application/tr/configuration.texy @@ -104,7 +104,7 @@ Latte sürüm 3 kullanıyorsanız, kullanarak yeni [uzantı |latte:creating-exte ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/tr/presenters.texy b/application/tr/presenters.texy index 512b73e142..7c862b57b1 100644 --- a/application/tr/presenters.texy +++ b/application/tr/presenters.texy @@ -452,17 +452,6 @@ Erişim Kısıtlaması Kullanımı `#[Requires]` .[#toc-access-restriction-using Bu `#[Requires]` özniteliği, sunum yapanlara ve yöntemlerine erişimi kısıtlamak için gelişmiş seçenekler sağlar. HTTP yöntemlerini belirtmek, AJAX istekleri gerektirmek, erişimi aynı kaynakla sınırlamak ve erişimi yalnızca yönlendirme ile kısıtlamak için kullanılabilir. Öznitelik, sunum yapan sınıfların yanı sıra aşağıdaki gibi bireysel yöntemlere de uygulanabilir `action()`, `render()`, `handle()`ve `createComponent()`. -İşte sadece HTTP `POST` yöntemine erişimi kısıtlamak için bir kullanım örneği: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Bu kısıtlamaları belirtebilirsiniz: - HTTP yöntemleri üzerinde: `#[Requires(methods: ['GET', 'POST'])]` - AJAX isteği gerektiriyor: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ Bu kısıtlamaları belirtebilirsiniz: - yalnızca yönlendirme yoluyla erişim: `#[Requires(forward: true)]` - belirli eylemlere ilişkin kısıtlamalar: `#[Requires(actions: 'default')]` -Koşullar, birden fazla öznitelik listelenerek veya bir araya getirilerek birleştirilebilir: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +Ayrıntılar için, bkz [Nasıl kullanılır Requires öznitelik |best-practices:attribute-requires]. HTTP Yöntem Kontrolü .[#toc-http-method-check] diff --git a/application/tr/routing.texy b/application/tr/routing.texy index d298997568..3a0b50b5d3 100644 --- a/application/tr/routing.texy +++ b/application/tr/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Ya da bu formu kullanabiliriz, doğrulama düzenli ifadesinin yeniden yazıldığına dikkat edin: +Daha ayrıntılı bir belirtim için, varsayılan değerlere ek olarak, doğrulama düzenli ifadesi gibi diğer parametre özelliklerinin de ayarlanabildiği daha da genişletilmiş bir form kullanılabilir (bkz. `id` parametresi): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Bu daha konuşkan formatlar diğer meta verileri eklemek için kullanışlıdır. +Dizide tanımlanan parametreler yol maskesine dahil edilmemişse, URL'de bir soru işaretinden sonra belirtilen sorgu parametreleri kullanılsa bile değerlerinin değiştirilemeyeceğine dikkat etmek önemlidir. Filtreler ve Çeviriler .[#toc-filters-and-translations] diff --git a/application/tr/templates.texy b/application/tr/templates.texy index ca42448aad..bd2fea6eee 100644 --- a/application/tr/templates.texy +++ b/application/tr/templates.texy @@ -285,7 +285,7 @@ Alternatif olarak, çevirmen [yapılandırma |configuration#Latte] kullanılarak ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Çevirmen daha sonra örneğin `|translate` filtresi olarak kullanılabilir ve ek parametreler `translate()` yöntemine aktarılabilir (bkz. `foo, bar`): diff --git a/application/uk/bootstrap.texy b/application/uk/bootstrap.texy index 0ebf2ae13d..fa1a842ec0 100644 --- a/application/uk/bootstrap.texy +++ b/application/uk/bootstrap.texy @@ -22,15 +22,15 @@ class Bootstrap { public static function boot(): Configurator { - $appDir = dirname(__DIR__); + $rootDir = dirname(__DIR__); $configurator = new Configurator; //$configurator->setDebugMode('secret@23.75.345.200'); - $configurator->enableTracy($appDir . '/log'); - $configurator->setTempDirectory($appDir . '/temp'); + $configurator->enableTracy($rootDir . '/log'); + $configurator->setTempDirectory($rootDir . '/temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); - $configurator->addConfig($appDir . '/config/common.neon'); + $configurator->addConfig($rootDir . '/config/common.neon'); return $configurator; } } @@ -90,7 +90,7 @@ $configurator->setDebugMode(false); Для полегшення налагодження ми увімкнемо чудовий інструмент [Tracy |tracy:]. У режимі розробника він візуалізує помилки, а в режимі виробництва - записує помилки в зазначений каталог: ```php -$configurator->enableTracy($appDir . '/log'); +$configurator->enableTracy($rootDir . '/log'); ``` @@ -100,7 +100,7 @@ $configurator->enableTracy($appDir . '/log'); Nette використовує кеш для DI-контейнера, RobotLoader, шаблонів тощо. Тому необхідно задати шлях до директорії, де зберігатиметься кеш: ```php -$configurator->setTempDirectory($appDir . '/temp'); +$configurator->setTempDirectory($rootDir . '/temp'); ``` У Linux або macOS встановіть [права на запис |nette:troubleshooting#Setting-Directory-Permissions] для каталогів `log/` і `temp/`. @@ -143,16 +143,16 @@ $configurator->setTimeZone('Europe/Prague'); Файли конфігурації завантажуються за допомогою `addConfig()`: ```php -$configurator->addConfig($appDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); ``` Метод `addConfig()` може бути викликаний кілька разів для додавання декількох файлів. ```php -$configurator->addConfig($appDir . '/config/common.neon'); -$configurator->addConfig($appDir . '/config/services.neon'); +$configurator->addConfig($rootDir . '/config/common.neon'); +$configurator->addConfig($rootDir . '/config/services.neon'); if (PHP_SAPI === 'cli') { - $configurator->addConfig($appDir . '/config/cli.php'); + $configurator->addConfig($rootDir . '/config/cli.php'); } ``` @@ -206,6 +206,7 @@ $configurator->addDynamicParameters([ - `%wwwDir%` - абсолютний шлях до каталогу, в якому знаходиться файл запису `index.php` - `%tempDir%` - абсолютний шлях до каталогу для тимчасових файлів - `%vendorDir%` - абсолютний шлях до каталогу, куди Composer встановлює бібліотеки +- `%rootDir%` - абсолютний шлях до кореневого каталогу проекту - `%debugMode%` вказує на те, чи перебуває програма у режимі налагодження - `%consoleMode%` вказує на те, що запит надійшов через командний рядок diff --git a/application/uk/configuration.texy b/application/uk/configuration.texy index 3fe82774a3..3dc226e7ef 100644 --- a/application/uk/configuration.texy +++ b/application/uk/configuration.texy @@ -104,7 +104,7 @@ latte: ```neon latte: расширения: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` /--comment diff --git a/application/uk/presenters.texy b/application/uk/presenters.texy index 9f85a0c5cb..5148623284 100644 --- a/application/uk/presenters.texy +++ b/application/uk/presenters.texy @@ -452,17 +452,6 @@ $this->sendResponse(new Responses\CallbackResponse($callback)); Атрибут `#[Requires]` надає розширені можливості для обмеження доступу до доповідачів та їхніх методів. Його можна використовувати для визначення HTTP-методів, вимагати AJAX-запитів, обмежувати доступ до одного і того ж джерела та обмежувати доступ лише пересиланням. Атрибут можна застосовувати до класів презентера, а також до окремих методів, таких як `action()`, `render()`, `handle()`та `createComponent()`. -Ось приклад його використання для обмеження доступу лише до методу HTTP `POST`: - -```php -use Nette\Application\Attributes\Requires; - -#[Requires(methods: 'POST')] -class MyPresenter extends Nette\Application\UI\Presenter -{ -} -``` - Ви можете вказати такі обмеження: - на HTTP-методи: `#[Requires(methods: ['GET', 'POST'])]` - що вимагають AJAX-запиту: `#[Requires(ajax: true)]` @@ -470,22 +459,7 @@ class MyPresenter extends Nette\Application\UI\Presenter - доступ тільки через переадресацію: `#[Requires(forward: true)]` - обмеження на певні дії: `#[Requires(actions: 'default')]` -Умови можна комбінувати, перераховуючи кілька атрибутів або об'єднуючи їх в один: - -```php -#[Requires(methods: 'POST', ajax: true)] -public function actionDelete(int $id) -{ -} - -// or - -#[Requires(methods: 'POST')] -#[Requires(ajax: true)] -public function actionDelete(int $id) -{ -} -``` +За деталями дивіться [Як використовувати атрибут Requires атрибут |best-practices:атрибут-requires]. Перевірка методу HTTP .[#toc-http-method-check] diff --git a/application/uk/routing.texy b/application/uk/routing.texy index f270ca67fd..6f1fc532a6 100644 --- a/application/uk/routing.texy +++ b/application/uk/routing.texy @@ -216,7 +216,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [ @@ -225,7 +225,7 @@ $router->addRoute('/[/]', [ ]); ``` -Або ми можемо використовувати цю форму, зверніть увагу на переписування регулярного виразу перевірки: +Для більш детальної специфікації можна використовувати ще більш розширену форму, де на додаток до значень за замовчуванням можна задати інші властивості параметрів, наприклад, регулярний вираз перевірки (див. параметр `id` ): ```php use Nette\Routing\Route; @@ -243,7 +243,7 @@ $router->addRoute('/[/]', [ ]); ``` -Ці детальніші формати корисні для додавання додаткових метаданих. +Важливо відзначити, що якщо параметри, визначені в масиві, не включені в маску шляху, їх значення не можуть бути змінені, навіть за допомогою параметрів запиту, зазначених після знака питання в URL-адресі. Фільтри та переклади .[#toc-filters-and-translations] diff --git a/application/uk/templates.texy b/application/uk/templates.texy index 4b2fda15f0..c4ed7aee2b 100644 --- a/application/uk/templates.texy +++ b/application/uk/templates.texy @@ -285,7 +285,7 @@ protected function beforeRender(): void ```neon latte: extensions: - - Latte\Essential\TranslatorExtension + - Latte\Essential\TranslatorExtension(@Nette\Localization\Translator) ``` Тоді перекладач можна використовувати, наприклад, як фільтр `|translate`, з додатковими параметрами, переданими методу `translate()` (див. `foo, bar`): diff --git a/best-practices/bg/@home.texy b/best-practices/bg/@home.texy index 2fc7fff5c7..814ac362f9 100644 --- a/best-practices/bg/@home.texy +++ b/best-practices/bg/@home.texy @@ -17,6 +17,8 @@ - [Как да се върнете към предишна страница |restore-request] - [Страница на резултатите от базата данни |Pagination] - [Динамични фрагменти |dynamic-snippets] +- [Как да използвате атрибута #Requires |attribute-requires] +- [Как да използвате правилно POST връзки |post-links]
diff --git a/best-practices/bg/attribute-requires.texy b/best-practices/bg/attribute-requires.texy new file mode 100644 index 0000000000..3918ac851d --- /dev/null +++ b/best-practices/bg/attribute-requires.texy @@ -0,0 +1,179 @@ +Как да използвате `#[Requires]` Атрибут +*************************************** + +.[perex] +Когато пишете уеб приложение, често се сблъсквате с необходимостта да ограничите достъпа до определени части на приложението. Може би искате някои заявки да могат да изпращат данни само чрез формуляр (като по този начин се използва методът POST) или да са достъпни само за AJAX повиквания. В Nette Framework 3.2 е въведен нов инструмент, който ви позволява да задавате такива ограничения по елегантен и ясен начин: инструментът `#[Requires]` атрибут. + +Атрибутът е специален маркер в PHP, който се добавя преди дефиницията на даден клас или метод. Тъй като по същество това е клас, трябва да включите клаузата use, за да работят следващите примери: + +```php +use Nette\Application\Attributes\Requires; +``` + +Можете да използвате `#[Requires]` атрибут в самия клас на презентатора и в тези методи: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Последните два метода също се отнасят за компоненти, така че можете да използвате атрибута и при тях. + +Ако условията, определени от атрибута, не са изпълнени, се задейства грешка HTTP 4xx. + + +HTTP методи .[#toc-http-methods] +-------------------------------- + +Можете да зададете кои HTTP методи (като GET, POST и т.н.) са разрешени за достъп. Например, ако искате да разрешите достъп само чрез изпращане на формуляр, задайте: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Защо трябва да използвате POST вместо GET за действия за промяна на състоянието и как да го направите? [Прочетете ръководството |post-links]. + +Можете да посочите метод или масив от методи. Специален случай е стойността `'*'`, за да се активират всички методи, което презентаторите не позволяват по подразбиране от [съображения за сигурност |application:presenters#http-method-check]. + + +Извиквания AJAX .[#toc-ajax-calls] +---------------------------------- + +Ако искате даден презентатор или метод да бъде достъпен само за AJAX заявки, използвайте: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Същият произход .[#toc-same-origin] +----------------------------------- + +За да повишите сигурността, можете да изискате заявката да бъде направена от същия домейн. Това предотвратява [уязвимостта към CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +За `handle()` методи, автоматично се изисква достъп от същия домейн. Затова, ако искате да разрешите достъп от всеки домейн, посочете: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Достъп чрез Forward .[#toc-access-via-forward] +---------------------------------------------- + +Понякога е полезно да се ограничи достъпът до даден презентатор, така че той да е достъпен само косвено, например чрез методите `forward()` или `switch()` от друг презентатор. По този начин се защитават презентаторите за грешки, за да се предотврати задействането им от URL адрес: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +В практиката често се налага да се маркират определени изгледи, до които може да се получи достъп само въз основа на логика в презентатора. Отново, за да не могат да бъдат отваряни директно: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Специфични действия .[#toc-specific-actions] +-------------------------------------------- + +Можете също така да ограничите достъпа до определен код, като например създаване на компонент, само за определени действия в презентатора: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +За едно действие не е необходимо да се пише масив: `#[Requires(actions: 'default')]` + + +Потребителски атрибути .[#toc-custom-attributes] +------------------------------------------------ + +Ако искате да използвате `#[Requires]` атрибут с едни и същи настройки, можете да създадете свой собствен атрибут, който ще наследи `#[Requires]` и да го настроите според нуждите си. + +Например, `#[SingleAction]` позволява достъп само чрез действието `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Или `#[RestMethods]` ще позволи достъп чрез всички HTTP методи, използвани за REST API: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Заключение .[#toc-conclusion] +----------------------------- + +На `#[Requires]` ви дава голяма гъвкавост и контрол върху начина, по който се осъществява достъпът до вашите уеб страници. С помощта на прости, но мощни правила можете да повишите сигурността и правилното функциониране на вашето приложение. Както виждате, използването на атрибути в Nette може не само да опрости работата ви, но и да я осигури. + +{{sitename: Best Practices}} diff --git a/best-practices/bg/dynamic-snippets.texy b/best-practices/bg/dynamic-snippets.texy index b927d707e4..7b2db16d21 100644 --- a/best-practices/bg/dynamic-snippets.texy +++ b/best-practices/bg/dynamic-snippets.texy @@ -35,7 +35,7 @@ public function handleUnlike(int $articleId): void Ajaxisation .[#toc-ajaxization] =============================== -Сега нека въведем AJAX в това просто приложение. Промяната на класацията на дадена статия не е достатъчно важна, за да изисква HTTP заявка с пренасочване, така че в идеалния случай това трябва да се прави с AJAX във фонов режим. Ще използваме [скрипта на манипулатора от добавките |https://componette.org/vojtech-dobes/nette.ajax.js/] с обичайната конвенция, че връзките AJAX имат CSS клас `ajax`. +Сега нека въведем AJAX в това просто приложение. Промяната на класацията на дадена статия не е достатъчно важна, за да изисква HTTP заявка с пренасочване, така че в идеалния случай това трябва да се прави с AJAX във фонов режим. Ще използваме [скрипта на манипулатора от добавките |application:ajax#toc-naja] с обичайната конвенция, че връзките AJAX имат CSS клас `ajax`. Как точно да го направим обаче? Nette предлага 2 начина: метода на динамичните фрагменти и метода на компонентите. И двете имат своите плюсове и минуси, затова ще ги покажем последователно. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ class LikeControl extends Nette\Application\UI\Control ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/bg/post-links.texy b/best-practices/bg/post-links.texy new file mode 100644 index 0000000000..f9299c9cbe --- /dev/null +++ b/best-practices/bg/post-links.texy @@ -0,0 +1,59 @@ +Как правилно да използвате POST връзки +************************************** + +В уеб приложенията, особено в административните интерфейси, трябва да е основно правило, че действия, променящи състоянието на сървъра, не трябва да се извършват чрез метода HTTP GET. Както подсказва името на метода, GET трябва да се използва само за извличане на данни, а не за тяхната промяна. +За действия като изтриване на записи е по-подходящо да се използва методът POST. Въпреки че идеалният вариант би бил да се използва методът DELETE, той не може да бъде извикан без JavaScript, поради което исторически се използва POST. + +Как да го направим на практика? Използвайте този прост трик. В началото на вашия шаблон създайте помощна форма с идентификатор `postForm`, която след това ще използвате за бутоните за изтриване: + +```latte .{file:@layout.latte} +
+``` + +С тази форма можете да използвате `
diff --git a/best-practices/cs/attribute-requires.texy b/best-practices/cs/attribute-requires.texy new file mode 100644 index 0000000000..fdde683a91 --- /dev/null +++ b/best-practices/cs/attribute-requires.texy @@ -0,0 +1,179 @@ +Jak používat atribut `#[Requires]` +********************************** + +.[perex] +Když píšete webovou aplikaci, často se setkáte s potřebou omezit přístup k určitým částem vaší aplikace. Možná chcete, aby některé požadavky mohly odesílat data pouze pomocí formuláře (tedy metodou POST), nebo aby byly přístupné pouze pro AJAXové volání. V Nette Frameworku 3.2 se objevil nový nástroj, který vám umožní taková omezení nastavit velmi elegantně a přehledně: atribut `#[Requires]`. + +Atribut je speciální značka v PHP, kterou přidáte před definici třídy nebo metody. Protože jde vlastně o třídu, aby vám následující příklady fungovaly, je nutné uvést klauzuli use: + +```php +use Nette\Application\Attributes\Requires; +``` + +Atribut `#[Requires]` můžete použít u samotné třídy presenteru a také na těchto metodách: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Poslední dvě metody se týkají i komponent, tedy atribut můžete používat i u nich. + +Pokud nejsou splněny podmínky, které atribut uvádí, dojde k vyvolání HTTP chyby 4xx. + + +Metody HTTP +----------- + +Můžete specifikovat, které HTTP metody (jako GET, POST atd.) jsou pro přístup povolené. Například, pokud chcete povolit přístup pouze odesíláním formuláře, nastavíte: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Proč byste měli používat POST místo GET pro akce měnící stav a jak na to? [Přečtěte si návod |post-links]. + +Můžete uvést metodu nebo pole metod. Speciálním případem je hodnota `'*'`, která povolí všechny metody, což standardně presentery z [bezpečnostních důvodů nedovolují |application:presenters#toc-kontrola-http-metody]. + + +AJAXové volání +-------------- + +Pokud chcete, aby byl presenter nebo metoda dostupná pouze pro AJAXové požadavky, použijte: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Stejný původ +------------ + +Pro zvýšení bezpečnosti můžete vyžadovat, aby byl požadavek učiněn ze stejné domény. Tím zabráníte [zranitelnosti CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +U metod `handle()` je přístup ze stejné domény vyžadován automaticky. Takže pokud naopak chcete povolit přístup z jakékoliv domény, uveďte: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Přístup přes forward +-------------------- + +Někdy je užitečné omezit přístup k presenteru tak, aby byl dostupný pouze nepřímo, například použitím metody `forward()` nebo `switch()` z jiného presenteru. Takto se třeba chrání error-presentery, aby je nebylo možné vyvolat z URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +V praxi bývá často potřeba označit určité views, ke kterým se lze dostat až na základě logiky v presenteru. Tedy opět, aby je nebylo možné otevřít přímo: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = $this->facade->getProduct($id); + if (!$product) { + $this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Konkrétní akce +-------------- + +Můžete také omezit, že určitý kód, třeba vytvoření komponenty, bude dostupné pouze pro specifické akce v presenteru: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +V případě jedné akce není potřeba zapisovat pole: `#[Requires(actions: 'default')]` + + +Vlastní atributy +---------------- + +Pokud chcete použít atribut `#[Requires]` opakovaně s týmž nastavením, můžete si vytvořit vlastní atribut, který bude dědit `#[Requires]` a nastaví ho podle potřeb. + +Například `#[SingleAction]` umožní přístup pouze přes akci `default`: + +```php +#[\Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Nebo `#[RestMethods]` umožní přístup přes všechny HTTP metody používané pro REST API: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Závěr +----- + +Atribut `#[Requires]` vám dává velkou flexibilitu a kontrolu nad tím, jak jsou vaše webové stránky přístupné. Pomocí jednoduchých, ale mocných pravidel můžete zvýšit bezpečnost a správné fungování vaší aplikace. Jak vidíte, použití atributů v Nette může vaši práci nejen usnadnit, ale i zabezpečit. + +{{sitename: Best Practices}} diff --git a/best-practices/cs/dynamic-snippets.texy b/best-practices/cs/dynamic-snippets.texy index 600dc4b9bd..daf3b00928 100644 --- a/best-practices/cs/dynamic-snippets.texy +++ b/best-practices/cs/dynamic-snippets.texy @@ -35,7 +35,7 @@ public function handleUnlike(int $articleId): void Ajaxizace ========= -Pojďme nyní tuto jednoduchou aplikaci vybavit AJAXem. Změna hodnocení článku není natolik důležitá, aby muselo dojít k přesměrování, a proto by ideálně měla probíhat AJAXem na pozadí. Využijeme [obslužného skriptu z doplňků |https://componette.org/vojtech-dobes/nette.ajax.js/] s obvyklou konvencí, že AJAXové odkazy mají CSS třídu `ajax`. +Pojďme nyní tuto jednoduchou aplikaci vybavit AJAXem. Změna hodnocení článku není natolik důležitá, aby muselo dojít k přesměrování, a proto by ideálně měla probíhat AJAXem na pozadí. Využijeme [obslužného skriptu z doplňků |application:ajax#toc-naja] s obvyklou konvencí, že AJAXové odkazy mají CSS třídu `ajax`. Nicméně jak na to konkrétně? Nette nabízí 2 cesty: cestu tzv. dynamických snippetů a cestu komponent. Obě dvě mají svá pro a proti, a proto si je ukážeme jednu po druhé. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Samozřejmě se nám změní šablona view a do presenteru budeme muset doplnit ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/cs/post-links.texy b/best-practices/cs/post-links.texy new file mode 100644 index 0000000000..e82bb4798d --- /dev/null +++ b/best-practices/cs/post-links.texy @@ -0,0 +1,59 @@ +Jak správně používat POST odkazy +******************************** + +Ve webových aplikacích, zejména v administrativních rozhraních, by mělo být základním pravidlem, že akce měnící stav serveru by neměly být prováděny prostřednictvím HTTP metody GET. Jak název metody napovídá, GET by měl sloužit pouze k získání dat, nikoli k jejich změně. +Pro akce jako třeba mazání záznamů je vhodnější použít metodu POST. I když ideální by byla metoda DELETE, ale tu nelze bez JavaScriptu vyvolat, proto se historicky používá POST. + +Jak na to v praxi? Využijte tento jednoduchý trik. Na začátku šablony si vytvoříte pomocný formulář s identifikátorem `postForm`, který následně použijete pro mazací tlačítka: + +```latte .{file:@layout.latte} +
+``` + +Díky tomuto formuláři můžete místo klasického odkazu `
` použít tlačítko `
diff --git a/best-practices/de/attribute-requires.texy b/best-practices/de/attribute-requires.texy new file mode 100644 index 0000000000..853a90b4f5 --- /dev/null +++ b/best-practices/de/attribute-requires.texy @@ -0,0 +1,179 @@ +Wie man das `#[Requires]` Attribut +********************************** + +.[perex] +Wenn Sie eine Webanwendung schreiben, stoßen Sie häufig auf die Notwendigkeit, den Zugriff auf bestimmte Teile Ihrer Anwendung zu beschränken. Vielleicht möchten Sie, dass einige Anfragen nur Daten über ein Formular senden können (also die POST-Methode verwenden) oder nur für AJAX-Aufrufe zugänglich sind. In Nette Framework 3.2 wurde ein neues Werkzeug eingeführt, mit dem Sie solche Einschränkungen elegant und klar festlegen können: das `#[Requires]` Attribut. + +Das Attribut ist eine spezielle Markierung in PHP, die Sie vor der Definition einer Klasse oder Methode hinzufügen. Da es sich im Wesentlichen um eine Klasse handelt, müssen Sie die Use-Klausel einfügen, damit die folgenden Beispiele funktionieren: + +```php +use Nette\Application\Attributes\Requires; +``` + +Sie können das `#[Requires]` Attribut mit der Presenter-Klasse selbst und mit diesen Methoden verwenden: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Die letzten beiden Methoden betreffen auch Komponenten, so dass Sie das Attribut auch für diese verwenden können. + +Wenn die durch das Attribut festgelegten Bedingungen nicht erfüllt sind, wird ein HTTP 4xx-Fehler ausgelöst. + + +HTTP-Methoden .[#toc-http-methods] +---------------------------------- + +Sie können angeben, welche HTTP-Methoden (wie GET, POST usw.) für den Zugriff zugelassen sind. Wenn Sie beispielsweise den Zugriff nur durch das Absenden eines Formulars erlauben wollen, legen Sie fest: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Warum sollten Sie POST anstelle von GET für zustandsändernde Aktionen verwenden, und wie geht das? [Lesen Sie den Leitfaden |post-links]. + +Sie können eine Methode oder eine Reihe von Methoden angeben. Ein Sonderfall ist der Wert `'*'`, um alle Methoden zu aktivieren, was Presenter aus [Sicherheitsgründen |application:presenters#http-method-check] standardmäßig nicht zulassen. + + +AJAX-Aufrufe .[#toc-ajax-calls] +------------------------------- + +Wenn Sie möchten, dass ein Presenter oder eine Methode nur für AJAX-Anfragen zugänglich ist, verwenden Sie: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Gleiche Herkunft .[#toc-same-origin] +------------------------------------ + +Um die Sicherheit zu erhöhen, können Sie verlangen, dass die Anfrage von der gleichen Domäne aus gestellt wird. Dies verhindert eine [Anfälligkeit für CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Für `handle()` Methoden ist der Zugriff aus derselben Domäne automatisch erforderlich. Wenn Sie also den Zugriff aus einer beliebigen Domäne zulassen wollen, geben Sie dies an: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Zugang über Forward .[#toc-access-via-forward] +---------------------------------------------- + +Manchmal ist es sinnvoll, den Zugriff auf einen Präsentator so einzuschränken, dass er nur indirekt verfügbar ist, z. B. über die Methoden `forward()` oder `switch()` eines anderen Präsentators. Auf diese Weise werden Fehlerpräsenter geschützt, um zu verhindern, dass sie von einer URL ausgelöst werden: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +In der Praxis ist es oft notwendig, bestimmte Ansichten zu markieren, auf die nur aufgrund der Logik im Präsentator zugegriffen werden kann. Auch hier gilt, dass sie nicht direkt geöffnet werden können: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Spezifische Aktionen .[#toc-specific-actions] +--------------------------------------------- + +Sie können auch einschränken, dass bestimmter Code, wie das Erstellen einer Komponente, nur für bestimmte Aktionen im Präsentator zugänglich ist: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Für eine einzelne Aktion muss kein Array geschrieben werden: `#[Requires(actions: 'default')]` + + +Benutzerdefinierte Attribute .[#toc-custom-attributes] +------------------------------------------------------ + +Wenn Sie das Attribut `#[Requires]` Attribut wiederholt mit denselben Einstellungen verwenden möchten, können Sie ein eigenes Attribut erstellen, das die `#[Requires]` erbt, und es nach Ihren Bedürfnissen einstellen. + +Zum Beispiel, `#[SingleAction]` erlaubt den Zugriff nur über die Aktion `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Oder `#[RestMethods]` ermöglicht den Zugriff über alle für die REST-API verwendeten HTTP-Methoden: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Schlussfolgerung .[#toc-conclusion] +----------------------------------- + +Das `#[Requires]` Attribut gibt Ihnen große Flexibilität und Kontrolle darüber, wie auf Ihre Webseiten zugegriffen wird. Mit einfachen, aber leistungsfähigen Regeln können Sie die Sicherheit und das ordnungsgemäße Funktionieren Ihrer Anwendung verbessern. Wie Sie sehen, kann die Verwendung von Attributen in Nette Ihre Arbeit nicht nur vereinfachen, sondern auch sichern. + +{{sitename: Best Practices}} diff --git a/best-practices/de/dynamic-snippets.texy b/best-practices/de/dynamic-snippets.texy index c75affd1e4..e4ac99a50a 100644 --- a/best-practices/de/dynamic-snippets.texy +++ b/best-practices/de/dynamic-snippets.texy @@ -35,7 +35,7 @@ Vorlage: Ajaxisierung .[#toc-ajaxization] ================================ -Bringen wir nun AJAX in diese einfache Anwendung. Das Ändern der Bewertung eines Artikels ist nicht wichtig genug, um eine HTTP-Anfrage mit Redirect zu erfordern, also sollte es idealerweise mit AJAX im Hintergrund geschehen. Wir werden das [Handler-Skript aus add-ons |https://componette.org/vojtech-dobes/nette.ajax.js/] verwenden, mit der üblichen Konvention, dass AJAX-Links die CSS-Klasse `ajax` haben. +Bringen wir nun AJAX in diese einfache Anwendung. Das Ändern der Bewertung eines Artikels ist nicht wichtig genug, um eine HTTP-Anfrage mit Redirect zu erfordern, also sollte es idealerweise mit AJAX im Hintergrund geschehen. Wir werden das [Handler-Skript aus add-ons |application:ajax#toc-naja] verwenden, mit der üblichen Konvention, dass AJAX-Links die CSS-Klasse `ajax` haben. Aber wie macht man das konkret? Nette bietet 2 Wege an: den dynamischen Snippet-Weg und den Komponenten-Weg. Beide haben ihre Vor- und Nachteile, daher werden wir sie nacheinander vorstellen. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Natürlich werden wir die Ansichtsvorlage ändern und dem Präsentator eine Fabr ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/de/post-links.texy b/best-practices/de/post-links.texy new file mode 100644 index 0000000000..13c38839bb --- /dev/null +++ b/best-practices/de/post-links.texy @@ -0,0 +1,59 @@ +Wie man POST-Links richtig verwendet +************************************ + +In Webanwendungen, insbesondere in Verwaltungsschnittstellen, sollte es eine Grundregel sein, dass Aktionen, die den Zustand des Servers verändern, nicht über die HTTP-GET-Methode durchgeführt werden sollten. Wie der Name der Methode schon sagt, sollte GET nur zum Abrufen von Daten verwendet werden, nicht zum Ändern. +Für Aktionen wie das Löschen von Datensätzen ist es angemessener, die POST-Methode zu verwenden. Ideal wäre die Verwendung der DELETE-Methode, die jedoch ohne JavaScript nicht aufgerufen werden kann, weshalb in der Regel POST verwendet wird. + +Wie macht man das in der Praxis? Verwenden Sie diesen einfachen Trick. Erstellen Sie am Anfang Ihrer Vorlage ein Hilfsformular mit dem Bezeichner `postForm`, das Sie dann für die Schaltflächen zum Löschen verwenden werden: + +```latte .{file:@layout.latte} +
+``` + +Mit diesem Formular können Sie ein `
diff --git a/best-practices/el/attribute-requires.texy b/best-practices/el/attribute-requires.texy new file mode 100644 index 0000000000..95d1417ac9 --- /dev/null +++ b/best-practices/el/attribute-requires.texy @@ -0,0 +1,179 @@ +Πώς να χρησιμοποιήσετε το `#[Requires]` Attribute +************************************************* + +.[perex] +Κατά τη συγγραφή μιας εφαρμογής ιστού, συναντάτε συχνά την ανάγκη να περιορίσετε την πρόσβαση σε ορισμένα τμήματα της εφαρμογής σας. Ίσως θέλετε κάποια αιτήματα να μπορούν να στέλνουν δεδομένα μόνο μέσω μιας φόρμας (χρησιμοποιώντας έτσι τη μέθοδο POST) ή να είναι προσβάσιμα μόνο σε κλήσεις AJAX. Στο Nette Framework 3.2, έχει εισαχθεί ένα νέο εργαλείο που σας επιτρέπει να ορίσετε τέτοιους περιορισμούς με κομψότητα και σαφήνεια: το `#[Requires]` χαρακτηριστικό. + +Το χαρακτηριστικό είναι ένας ειδικός δείκτης στην PHP, τον οποίο προσθέτετε πριν από τον ορισμό μιας κλάσης ή μεθόδου. Εφόσον πρόκειται ουσιαστικά για μια κλάση, πρέπει να συμπεριλάβετε τη ρήτρα use για να λειτουργήσουν τα παρακάτω παραδείγματα: + +```php +use Nette\Application\Attributes\Requires; +``` + +Μπορείτε να χρησιμοποιήσετε το `#[Requires]` με την ίδια την κλάση presenter και σε αυτές τις μεθόδους: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Οι δύο τελευταίες μέθοδοι αφορούν επίσης συστατικά, οπότε μπορείτε να χρησιμοποιήσετε το χαρακτηριστικό και με αυτά. + +Εάν δεν πληρούνται οι συνθήκες που καθορίζονται από το χαρακτηριστικό, ενεργοποιείται ένα σφάλμα HTTP 4xx. + + +Μέθοδοι HTTP .[#toc-http-methods] +--------------------------------- + +Μπορείτε να καθορίσετε ποιες μέθοδοι HTTP (όπως GET, POST κ.λπ.) επιτρέπονται για πρόσβαση. Για παράδειγμα, αν θέλετε να επιτρέψετε την πρόσβαση μόνο με την υποβολή μιας φόρμας, ορίστε: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Γιατί πρέπει να χρησιμοποιείτε POST αντί για GET για ενέργειες αλλαγής κατάστασης και πώς να το κάνετε; [Διαβάστε τον οδηγό |post-links]. + +Μπορείτε να καθορίσετε μια μέθοδο ή έναν πίνακα μεθόδων. Μια ειδική περίπτωση είναι η τιμή `'*'` για την ενεργοποίηση όλων των μεθόδων, την οποία οι παρουσιαστές δεν επιτρέπουν από προεπιλογή για [λόγους ασφαλείας |application:presenters#http-method-check]. + + +Κλήσεις AJAX .[#toc-ajax-calls] +------------------------------- + +Αν θέλετε ένας παρουσιαστής ή μια μέθοδος να είναι προσβάσιμη μόνο για αιτήσεις AJAX, χρησιμοποιήστε: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Ίδια προέλευση .[#toc-same-origin] +---------------------------------- + +Για να ενισχύσετε την ασφάλεια, μπορείτε να απαιτήσετε η αίτηση να γίνεται από τον ίδιο τομέα. Αυτό αποτρέπει την [ευπάθεια σε CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Για το `handle()` μεθόδους, απαιτείται αυτόματα πρόσβαση από τον ίδιο τομέα. Έτσι, αν θέλετε να επιτρέψετε την πρόσβαση από οποιονδήποτε τομέα, καθορίστε: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Πρόσβαση μέσω Forward .[#toc-access-via-forward] +------------------------------------------------ + +Μερικές φορές είναι χρήσιμο να περιορίσετε την πρόσβαση σε έναν παρουσιαστή, ώστε να είναι διαθέσιμος μόνο έμμεσα, για παράδειγμα, χρησιμοποιώντας τις μεθόδους `forward()` ή `switch()` από έναν άλλο παρουσιαστή. Με αυτόν τον τρόπο προστατεύονται οι παρουσιαστές σφαλμάτων, ώστε να μην μπορούν να ενεργοποιηθούν από μια διεύθυνση URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Στην πράξη, είναι συχνά απαραίτητο να επισημαίνονται ορισμένες προβολές στις οποίες μπορεί να γίνει πρόσβαση μόνο με βάση τη λογική του παρουσιαστή. Και πάλι, έτσι ώστε να μην μπορούν να ανοιχτούν απευθείας: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Ειδικές δράσεις .[#toc-specific-actions] +---------------------------------------- + +Μπορείτε επίσης να περιορίσετε ότι ορισμένος κώδικας, όπως η δημιουργία ενός στοιχείου, θα είναι προσβάσιμος μόνο για συγκεκριμένες ενέργειες στον παρουσιαστή: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Για μια μεμονωμένη ενέργεια, δεν χρειάζεται να γράψετε έναν πίνακα: `#[Requires(actions: 'default')]` + + +Προσαρμοσμένα χαρακτηριστικά .[#toc-custom-attributes] +------------------------------------------------------ + +Αν θέλετε να χρησιμοποιήσετε το `#[Requires]` χαρακτηριστικό επανειλημμένα με τις ίδιες ρυθμίσεις, μπορείτε να δημιουργήσετε το δικό σας χαρακτηριστικό που θα κληρονομεί `#[Requires]` και να το ορίσετε σύμφωνα με τις ανάγκες σας. + +Για παράδειγμα, `#[SingleAction]` επιτρέπει την πρόσβαση μόνο μέσω της ενέργειας `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Ή `#[RestMethods]` θα επιτρέψει την πρόσβαση μέσω όλων των μεθόδων HTTP που χρησιμοποιούνται για το REST API: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Συμπέρασμα .[#toc-conclusion] +----------------------------- + +Το `#[Requires]` σας δίνει μεγάλη ευελιξία και έλεγχο στον τρόπο πρόσβασης στις ιστοσελίδες σας. Χρησιμοποιώντας απλούς, αλλά ισχυρούς κανόνες, μπορείτε να ενισχύσετε την ασφάλεια και την ορθή λειτουργία της εφαρμογής σας. Όπως μπορείτε να δείτε, η χρήση χαρακτηριστικών στη Nette μπορεί όχι μόνο να απλοποιήσει την εργασία σας αλλά και να την ασφαλίσει. + +{{sitename: Best Practices}} diff --git a/best-practices/el/dynamic-snippets.texy b/best-practices/el/dynamic-snippets.texy index 59031461f0..c75bfa12dd 100644 --- a/best-practices/el/dynamic-snippets.texy +++ b/best-practices/el/dynamic-snippets.texy @@ -35,7 +35,7 @@ Template: Ajaxization .[#toc-ajaxization] =============================== -Ας φέρουμε τώρα το AJAX σε αυτή την απλή εφαρμογή. Η αλλαγή της βαθμολογίας ενός άρθρου δεν είναι αρκετά σημαντική ώστε να απαιτεί ένα αίτημα HTTP με ανακατεύθυνση, οπότε ιδανικά θα πρέπει να γίνεται με AJAX στο παρασκήνιο. Θα χρησιμοποιήσουμε το [σενάριο χειρισμού από τα πρόσθετα |https://componette.org/vojtech-dobes/nette.ajax.js/] με τη συνήθη σύμβαση ότι οι σύνδεσμοι AJAX έχουν την κλάση CSS `ajax`. +Ας φέρουμε τώρα το AJAX σε αυτή την απλή εφαρμογή. Η αλλαγή της βαθμολογίας ενός άρθρου δεν είναι αρκετά σημαντική ώστε να απαιτεί ένα αίτημα HTTP με ανακατεύθυνση, οπότε ιδανικά θα πρέπει να γίνεται με AJAX στο παρασκήνιο. Θα χρησιμοποιήσουμε το [σενάριο χειρισμού από τα πρόσθετα |application:ajax#toc-naja] με τη συνήθη σύμβαση ότι οι σύνδεσμοι AJAX έχουν την κλάση CSS `ajax`. Ωστόσο, πώς να το κάνουμε συγκεκριμένα; Η Nette προσφέρει 2 τρόπους: τον τρόπο με τα δυναμικά αποσπάσματα και τον τρόπο με τα συστατικά. Και οι δύο έχουν τα πλεονεκτήματα και τα μειονεκτήματά τους, γι' αυτό θα τους παρουσιάσουμε έναν προς έναν. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ class LikeControl extends Nette\Application\UI\Control ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/el/post-links.texy b/best-practices/el/post-links.texy new file mode 100644 index 0000000000..634091cf38 --- /dev/null +++ b/best-practices/el/post-links.texy @@ -0,0 +1,59 @@ +Πώς να χρησιμοποιείτε σωστά τους συνδέσμους POST +************************************************ + +Στις εφαρμογές ιστού, ειδικά στις διαχειριστικές διεπαφές, θα πρέπει να αποτελεί βασικό κανόνα ότι οι ενέργειες που αλλάζουν την κατάσταση του διακομιστή δεν θα πρέπει να εκτελούνται μέσω της μεθόδου HTTP GET. Όπως υποδηλώνει το όνομα της μεθόδου, η GET θα πρέπει να χρησιμοποιείται μόνο για την ανάκτηση δεδομένων και όχι για την αλλαγή τους. +Για ενέργειες όπως η διαγραφή εγγραφών, είναι καταλληλότερο να χρησιμοποιείται η μέθοδος POST. Αν και το ιδανικό θα ήταν να χρησιμοποιείται η μέθοδος DELETE, αυτή δεν μπορεί να κληθεί χωρίς JavaScript, γι' αυτό και χρησιμοποιείται ιστορικά η μέθοδος POST. + +Πώς να το κάνετε στην πράξη; Χρησιμοποιήστε αυτό το απλό τέχνασμα. Στην αρχή του προτύπου σας, δημιουργήστε μια βοηθητική φόρμα με το αναγνωριστικό `postForm`, την οποία στη συνέχεια θα χρησιμοποιήσετε για τα κουμπιά διαγραφής: + +```latte .{file:@layout.latte} +
+``` + +Με αυτή τη φόρμα, μπορείτε να χρησιμοποιήσετε ένα `
diff --git a/best-practices/en/attribute-requires.texy b/best-practices/en/attribute-requires.texy new file mode 100644 index 0000000000..514355ad79 --- /dev/null +++ b/best-practices/en/attribute-requires.texy @@ -0,0 +1,179 @@ +How to Use the `#[Requires]` Attribute +************************************** + +.[perex] +When writing a web application, you often encounter the need to restrict access to certain parts of your application. Perhaps you want some requests to only be able to send data via a form (thus using the POST method) or to be accessible only to AJAX calls. In Nette Framework 3.2, a new tool has been introduced that allows you to set such restrictions elegantly and clearly: the `#[Requires]` attribute. + +The attribute is a special marker in PHP, which you add before the definition of a class or method. Since it is essentially a class, you need to include the use clause to make the following examples work: + +```php +use Nette\Application\Attributes\Requires; +``` + +You can use the `#[Requires]` attribute with the presenter class itself and on these methods: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +The last two methods also concern components, so you can use the attribute with them as well. + +If the conditions specified by the attribute are not met, an HTTP 4xx error is triggered. + + +HTTP Methods +------------ + +You can specify which HTTP methods (such as GET, POST, etc.) are allowed for access. For example, if you want to allow access only by submitting a form, set: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Why should you use POST instead of GET for state changing actions and how to do it? [Read the guide |post-links]. + +You can specify a method or an array of methods. A special case is the value `'*'` to enable all methods, which presenters do not allow by default for [security reasons |application:presenters#http-method-check]. + + +AJAX Calls +---------- + +If you want a presenter or method to be accessible only for AJAX requests, use: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Same Origin +----------- + +To enhance security, you can require that the request be made from the same domain. This prevents [vulnerability to CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +For `handle()` methods, access from the same domain is automatically required. So, if you want to allow access from any domain, specify: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Access via Forward +------------------ + +Sometimes it is useful to restrict access to a presenter so that it is only available indirectly, for example, using the `forward()` or `switch()` methods from another presenter. This is how error-presenters are protected to prevent them from being triggered from a URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +In practice, it is often necessary to mark certain views that can only be accessed based on logic in the presenter. Again, so that they cannot be opened directly: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Specific Actions +---------------- + +You can also restrict that certain code, like creating a component, will be accessible only for specific actions in the presenter: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +For a single action, there's no need to write an array: `#[Requires(actions: 'default')]` + + +Custom Attributes +----------------- + +If you want to use the `#[Requires]` attribute repeatedly with the same settings, you can create your own attribute that will inherit `#[Requires]` and set it according to your needs. + +For example, `#[SingleAction]` allows access only through the `default` action: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Or `#[RestMethods]` will allow access via all HTTP methods used for the REST API: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Conclusion +---------- + +The `#[Requires]` attribute gives you great flexibility and control over how your web pages are accessed. Using simple, yet powerful rules, you can enhance the security and proper functioning of your application. As you can see, using attributes in Nette can not only simplify your work but also secure it. + +{{sitename: Best Practices}} diff --git a/best-practices/en/dynamic-snippets.texy b/best-practices/en/dynamic-snippets.texy index a0e8e09cae..9ec54ca401 100644 --- a/best-practices/en/dynamic-snippets.texy +++ b/best-practices/en/dynamic-snippets.texy @@ -35,7 +35,7 @@ Template: Ajaxization =========== -Let's now bring AJAX to this simple application. Changing the rating of an article is not important enough to require a HTTP request with redirect, so ideally it should be done with AJAX in the background. We'll use the [handler script from add-ons |https://componette.org/vojtech-dobes/nette.ajax.js/] with the usual convention that AJAX links have the CSS class `ajax`. +Let's now bring AJAX to this simple application. Changing the rating of an article is not important enough to require a HTTP request with redirect, so ideally it should be done with AJAX in the background. We'll use the [handler script from add-ons |application:ajax#toc-naja] with the usual convention that AJAX links have the CSS class `ajax`. However, how to do it specifically? Nette offers 2 ways: the dynamic snippet way and the component way. Both of them have their pros and cons, so we will show them one by one. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Of course we will change the view template and we will have to add a factory to ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/en/post-links.texy b/best-practices/en/post-links.texy new file mode 100644 index 0000000000..45af7ea028 --- /dev/null +++ b/best-practices/en/post-links.texy @@ -0,0 +1,59 @@ +How to Properly Use POST Links +****************************** + +In web applications, especially in administrative interfaces, it should be a basic rule that actions changing the state of the server should not be performed via the HTTP GET method. As the method name suggests, GET should be used only to retrieve data, not to change it. +For actions such as deleting records, it is more appropriate to use the POST method. Although the ideal would be to use the DELETE method, this cannot be invoked without JavaScript, hence POST is historically used. + +How to do it in practice? Use this simple trick. At the beginning of your template, create a helper form with the identifier `postForm`, which you will then use for the delete buttons: + +```latte .{file:@layout.latte} +
+``` + +With this form, you can use a `
diff --git a/best-practices/es/attribute-requires.texy b/best-practices/es/attribute-requires.texy new file mode 100644 index 0000000000..0c51ef716b --- /dev/null +++ b/best-practices/es/attribute-requires.texy @@ -0,0 +1,179 @@ +Cómo utilizar el atributo `#[Requires]` Atributo +************************************************ + +.[perex] +Cuando escribes una aplicación web, a menudo te encuentras con la necesidad de restringir el acceso a ciertas partes de tu aplicación. Tal vez desee que algunas peticiones sólo puedan enviar datos a través de un formulario (utilizando así el método POST) o que sólo sean accesibles para llamadas AJAX. En Nette Framework 3.2, se ha introducido una nueva herramienta que permite establecer estas restricciones de forma elegante y clara: el atributo `#[Requires]` atributo. + +El atributo es un marcador especial en PHP, que se añade antes de la definición de una clase o método. Dado que se trata esencialmente de una clase, es necesario incluir la cláusula use para que los siguientes ejemplos funcionen: + +```php +use Nette\Application\Attributes\Requires; +``` + +Puede utilizar el atributo `#[Requires]` con la propia clase presentadora y en estos métodos: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Los dos últimos métodos también afectan a los componentes, por lo que también puede utilizar el atributo con ellos. + +Si no se cumplen las condiciones especificadas por el atributo, se produce un error HTTP 4xx. + + +Métodos HTTP .[#toc-http-methods] +--------------------------------- + +Puede especificar qué métodos HTTP (como GET, POST, etc.) están permitidos para el acceso. Por ejemplo, si desea permitir el acceso sólo mediante el envío de un formulario, establezca: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +¿Por qué debería utilizar POST en lugar de GET para las acciones de cambio de estado y cómo hacerlo? [Lea la guía |post-links]. + +Puede especificar un método o un conjunto de métodos. Un caso especial es el valor `'*'` para habilitar todos los métodos, que los presentadores no permiten por defecto por [motivos de seguridad |application:presenters#http-method-check]. + + +Llamadas AJAX .[#toc-ajax-calls] +-------------------------------- + +Si desea que un presentador o método sea accesible sólo para peticiones AJAX, utilice: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Mismo origen .[#toc-same-origin] +-------------------------------- + +Para mejorar la seguridad, puede exigir que la solicitud se realice desde el mismo dominio. Esto evita la [vulnerabilidad a CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Para los métodos `handle()` se requiere automáticamente el acceso desde el mismo dominio. Por lo tanto, si desea permitir el acceso desde cualquier dominio, especifique: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Acceso a través de Forward .[#toc-access-via-forward] +----------------------------------------------------- + +A veces es útil restringir el acceso a un presentador para que sólo esté disponible indirectamente, por ejemplo, utilizando los métodos `forward()` o `switch()` desde otro presentador. Así es como se protegen los presentadores de errores para evitar que se activen desde una URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +En la práctica, a menudo es necesario marcar determinadas vistas a las que sólo se puede acceder basándose en la lógica del presentador. De nuevo, para que no puedan abrirse directamente: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Acciones específicas .[#toc-specific-actions] +--------------------------------------------- + +También puede restringir que cierto código, como la creación de un componente, sea accesible sólo para acciones específicas en el presentador: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Para una sola acción, no es necesario escribir una matriz: `#[Requires(actions: 'default')]` + + +Atributos personalizados .[#toc-custom-attributes] +-------------------------------------------------- + +Si desea utilizar el atributo `#[Requires]` atributo repetidamente con la misma configuración, puede crear su propio atributo que heredará `#[Requires]` y configurarlo según tus necesidades. + +Por ejemplo `#[SingleAction]` sólo permite el acceso a través de la acción `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +O `#[RestMethods]` permitirá el acceso a través de todos los métodos HTTP utilizados para la API REST: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Conclusión .[#toc-conclusion] +----------------------------- + +El atributo `#[Requires]` te ofrece una gran flexibilidad y control sobre cómo se accede a tus páginas web. Usando reglas simples, pero potentes, puedes mejorar la seguridad y el buen funcionamiento de tu aplicación. Como puede ver, el uso de atributos en Nette no sólo puede simplificar su trabajo, sino también asegurarlo. + +{{sitename: Best Practices}} diff --git a/best-practices/es/dynamic-snippets.texy b/best-practices/es/dynamic-snippets.texy index 2133b4a573..d59e1eaefe 100644 --- a/best-practices/es/dynamic-snippets.texy +++ b/best-practices/es/dynamic-snippets.texy @@ -35,7 +35,7 @@ Plantilla: Ajaxización .[#toc-ajaxization] =============================== -Llevemos ahora AJAX a esta sencilla aplicación. Cambiar la calificación de un artículo no es lo suficientemente importante como para requerir una petición HTTP con redirección, así que lo ideal sería hacerlo con AJAX en segundo plano. Usaremos el [script handler de add-ons |https://componette.org/vojtech-dobes/nette.ajax.js/] con la convención habitual de que los enlaces AJAX tienen la clase CSS `ajax`. +Llevemos ahora AJAX a esta sencilla aplicación. Cambiar la calificación de un artículo no es lo suficientemente importante como para requerir una petición HTTP con redirección, así que lo ideal sería hacerlo con AJAX en segundo plano. Usaremos el [script handler de add-ons |application:ajax#toc-naja] con la convención habitual de que los enlaces AJAX tienen la clase CSS `ajax`. Sin embargo, ¿cómo hacerlo específicamente? Nette ofrece 2 maneras: la del fragmento dinámico y la del componente. Ambas tienen sus pros y sus contras, así que las mostraremos una a una. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Por supuesto cambiaremos la plantilla de la vista y tendremos que añadir una f ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/es/post-links.texy b/best-practices/es/post-links.texy new file mode 100644 index 0000000000..4b13b68b11 --- /dev/null +++ b/best-practices/es/post-links.texy @@ -0,0 +1,59 @@ +Cómo utilizar correctamente los enlaces POST +******************************************** + +En aplicaciones web, especialmente en interfaces administrativas, debería ser una regla básica que las acciones que cambian el estado del servidor no deberían realizarse a través del método HTTP GET. Como el nombre del método sugiere, GET debería usarse sólo para recuperar datos, no para cambiarlos. +Para acciones como borrar registros, es más apropiado utilizar el método POST. Aunque lo ideal sería utilizar el método DELETE, éste no puede invocarse sin JavaScript, de ahí que históricamente se utilice POST. + +¿Cómo hacerlo en la práctica? Utilice este sencillo truco. Al principio de su plantilla, cree un formulario de ayuda con el identificador `postForm`, que luego utilizará para los botones de eliminación: + +```latte .{file:@layout.latte} +
+``` + +Con este formulario, puedes utilizar un `
diff --git a/best-practices/fr/attribute-requires.texy b/best-practices/fr/attribute-requires.texy new file mode 100644 index 0000000000..03e5be9f2e --- /dev/null +++ b/best-practices/fr/attribute-requires.texy @@ -0,0 +1,179 @@ +Comment utiliser l'attribut `#[Requires]` Attribut +************************************************** + +.[perex] +Lorsque vous écrivez une application web, vous rencontrez souvent le besoin de restreindre l'accès à certaines parties de votre application. Vous souhaitez peut-être que certaines requêtes ne puissent envoyer des données que par l'intermédiaire d'un formulaire (en utilisant donc la méthode POST) ou qu'elles ne soient accessibles qu'aux appels AJAX. Dans le Nette Framework 3.2, un nouvel outil a été introduit qui vous permet de définir de telles restrictions de manière élégante et claire : l'attribut `#[Requires]` attribut. + +L'attribut est un marqueur spécial en PHP, que vous ajoutez avant la définition d'une classe ou d'une méthode. Comme il s'agit essentiellement d'une classe, vous devez inclure la clause use pour que les exemples suivants fonctionnent : + +```php +use Nette\Application\Attributes\Requires; +``` + +Vous pouvez utiliser l'attribut `#[Requires]` avec la classe du présentateur elle-même et avec ces méthodes : + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Les deux dernières méthodes concernent également les composants, de sorte que vous pouvez également utiliser l'attribut avec eux. + +Si les conditions spécifiées par l'attribut ne sont pas remplies, une erreur HTTP 4xx est déclenchée. + + +Méthodes HTTP .[#toc-http-methods] +---------------------------------- + +Vous pouvez spécifier les méthodes HTTP (telles que GET, POST, etc.) autorisées pour l'accès. Par exemple, si vous souhaitez n'autoriser l'accès qu'en soumettant un formulaire, définissez : + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Pourquoi utiliser POST au lieu de GET pour les actions de changement d'état et comment le faire ? [Lire le guide |post-links]. + +Vous pouvez spécifier une méthode ou un tableau de méthodes. Un cas particulier est la valeur `'*'` qui permet d'activer toutes les méthodes, ce que les présentateurs n'autorisent pas par défaut pour des [raisons de sécurité |application:presenters#http-method-check]. + + +Appels AJAX .[#toc-ajax-calls] +------------------------------ + +Si vous souhaitez qu'un présentateur ou une méthode ne soit accessible que pour les requêtes AJAX, utilisez : + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Même origine .[#toc-same-origin] +-------------------------------- + +Pour renforcer la sécurité, vous pouvez exiger que la demande soit faite à partir du même domaine. Cela permet d'éviter la [vulnérabilité au CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Pour les méthodes `handle()` l'accès à partir du même domaine est automatiquement requis. Par conséquent, si vous souhaitez autoriser l'accès à partir de n'importe quel domaine, indiquez : + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Accès via Forward .[#toc-access-via-forward] +-------------------------------------------- + +Il est parfois utile de restreindre l'accès à un présentateur pour qu'il ne soit accessible qu'indirectement, par exemple en utilisant les méthodes `forward()` ou `switch()` d'un autre présentateur. C'est ainsi que les présentateurs d'erreurs sont protégés pour éviter qu'ils ne soient déclenchés à partir d'une URL : + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Dans la pratique, il est souvent nécessaire de marquer certaines vues auxquelles on ne peut accéder qu'en fonction de la logique du présentateur. Là encore, elles ne peuvent pas être ouvertes directement : + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Actions spécifiques .[#toc-specific-actions] +-------------------------------------------- + +Vous pouvez également limiter l'accès à certains codes, comme la création d'un composant, à des actions spécifiques dans le présentateur : + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Pour une action unique, il n'est pas nécessaire d'écrire un tableau : `#[Requires(actions: 'default')]` + + +Attributs personnalisés .[#toc-custom-attributes] +------------------------------------------------- + +Si vous souhaitez utiliser l'attribut `#[Requires]` à plusieurs reprises avec les mêmes paramètres, vous pouvez créer votre propre attribut qui héritera de l'attribut `#[Requires]` et le paramétrer en fonction de vos besoins. + +Par exemple, l'attribut `#[SingleAction]` n'autorise l'accès que par l'action `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +ou `#[RestMethods]` permet l'accès via toutes les méthodes HTTP utilisées pour l'API REST : + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Conclusion .[#toc-conclusion] +----------------------------- + +L'attribut `#[Requires]` vous offre une grande flexibilité et un contrôle sur la manière dont vos pages web sont accessibles. En utilisant des règles simples mais puissantes, vous pouvez améliorer la sécurité et le bon fonctionnement de votre application. Comme vous pouvez le constater, l'utilisation des attributs dans Nette peut non seulement simplifier votre travail, mais aussi le sécuriser. + +{{sitename: Best Practices}} diff --git a/best-practices/fr/dynamic-snippets.texy b/best-practices/fr/dynamic-snippets.texy index 5bc4743f67..053c6e6607 100644 --- a/best-practices/fr/dynamic-snippets.texy +++ b/best-practices/fr/dynamic-snippets.texy @@ -35,7 +35,7 @@ Template : Ajaxisation .[#toc-ajaxization] =============================== -Introduisons maintenant AJAX dans cette application simple. La modification de l'évaluation d'un article n'est pas assez importante pour nécessiter une requête HTTP avec redirection, donc l'idéal serait de le faire avec AJAX en arrière-plan. Nous utiliserons le [script de gestion des modules complémentaires |https://componette.org/vojtech-dobes/nette.ajax.js/] avec la convention habituelle selon laquelle les liens AJAX ont la classe CSS `ajax`. +Introduisons maintenant AJAX dans cette application simple. La modification de l'évaluation d'un article n'est pas assez importante pour nécessiter une requête HTTP avec redirection, donc l'idéal serait de le faire avec AJAX en arrière-plan. Nous utiliserons le [script de gestion des modules complémentaires |application:ajax#toc-naja] avec la convention habituelle selon laquelle les liens AJAX ont la classe CSS `ajax`. Cependant, comment le faire spécifiquement ? Nette propose deux méthodes : le snippet dynamique et le composant. Ces deux méthodes ont leurs avantages et leurs inconvénients, nous allons donc les présenter une par une. @@ -151,7 +151,7 @@ Bien sûr, nous allons modifier le modèle de vue et nous devrons ajouter une fa ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/fr/post-links.texy b/best-practices/fr/post-links.texy new file mode 100644 index 0000000000..70211882bc --- /dev/null +++ b/best-practices/fr/post-links.texy @@ -0,0 +1,59 @@ +Comment utiliser correctement les liens POST +******************************************** + +Dans les applications web, en particulier dans les interfaces administratives, la règle de base devrait être que les actions modifiant l'état du serveur ne doivent pas être effectuées via la méthode HTTP GET. Comme le nom de la méthode le suggère, GET ne doit être utilisé que pour récupérer des données, et non pour les modifier. +Pour des actions telles que la suppression d'enregistrements, il est plus approprié d'utiliser la méthode POST. L'idéal serait d'utiliser la méthode DELETE, mais celle-ci ne peut être invoquée sans JavaScript, d'où l'utilisation historique de POST. + +Comment faire en pratique ? Utilisez cette astuce simple. Au début de votre modèle, créez un formulaire d'aide avec l'identifiant `postForm`, que vous utiliserez ensuite pour les boutons de suppression : + +```latte .{file:@layout.latte} +
+``` + +Avec ce formulaire, vous pouvez utiliser un `
diff --git a/best-practices/hu/attribute-requires.texy b/best-practices/hu/attribute-requires.texy new file mode 100644 index 0000000000..22cea565bb --- /dev/null +++ b/best-practices/hu/attribute-requires.texy @@ -0,0 +1,179 @@ +Hogyan használjuk a `#[Requires]` Attribútum +******************************************** + +.[perex] +Webalkalmazások írása során gyakran találkozunk azzal az igénnyel, hogy korlátozni kell az alkalmazás bizonyos részeihez való hozzáférést. Talán azt szeretné, hogy egyes kérések csak űrlapon keresztül küldhessenek adatokat (tehát a POST módszerrel), vagy csak AJAX-hívások számára legyenek elérhetők. A Nette Framework 3.2-ben egy új eszköz került bevezetésre, amely lehetővé teszi az ilyen korlátozások elegáns és egyértelmű beállítását: a `#[Requires]` attribútum. + +Az attribútum egy speciális jelölő a PHP-ban, amelyet egy osztály vagy metódus definíciója előtt adunk meg. Mivel lényegében egy osztályról van szó, a következő példák működéséhez a use záradékot is be kell illesztenie: + +```php +use Nette\Application\Attributes\Requires; +``` + +Használhatja a `#[Requires]` attribútumot magával a prezentáló osztállyal és ezekkel a metódusokkal: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Az utolsó két módszer szintén komponensekre vonatkozik, így ezekkel is használhatja az attribútumot. + +Ha az attribútum által meghatározott feltételek nem teljesülnek, a rendszer egy HTTP 4xx hibaüzenetet küld. + + +HTTP-módszerek .[#toc-http-methods] +----------------------------------- + +Megadhatja, hogy mely HTTP-módszerek (például GET, POST stb.) engedélyezettek a hozzáféréshez. Ha például csak egy űrlap elküldésével akarja engedélyezni a hozzáférést, állítsa be a következőket: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Miért érdemes POST-ot használni GET helyett állapotváltoztató műveletekhez, és hogyan kell ezt megtenni? [Olvassa el az útmutatót |post-links]. + +Megadhat egy módszert vagy módszerek tömbjét. Speciális eset a `'*'` érték, amely minden módszert engedélyez, amit a prezenterek [biztonsági okokból |application:presenters#http-method-check] alapértelmezés szerint nem engedélyeznek. + + +AJAX hívások .[#toc-ajax-calls] +------------------------------- + +Ha azt szeretné, hogy egy bemutató vagy metódus csak AJAX-kérések számára legyen elérhető, használja a következőt: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Ugyanaz az eredet .[#toc-same-origin] +------------------------------------- + +A biztonság növelése érdekében megkövetelheti, hogy a kérés ugyanarról a tartományról érkezzen. Ez megakadályozza [a CSRF sebezhetőséget |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +A oldalon. `handle()` módszerek esetében automatikusan ugyanabból a tartományból való hozzáférés szükséges. Ha tehát bármilyen tartományból engedélyezni szeretné a hozzáférést, adja meg: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Hozzáférés a Forwardon keresztül .[#toc-access-via-forward] +----------------------------------------------------------- + +Néha célszerű úgy korlátozni a hozzáférést egy prezentálóhoz, hogy az csak közvetve legyen elérhető, például egy másik prezentáló `forward()` vagy `switch()` módszereivel. A hiba-bemutatókat így védik, hogy megakadályozzák, hogy egy URL-ből indítsák őket: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +A gyakorlatban gyakran szükség van bizonyos nézetek megjelölésére, amelyek csak a prezenter logikája alapján érhetők el. Megint csak azért, hogy ne lehessen őket közvetlenül megnyitni: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Konkrét intézkedések .[#toc-specific-actions] +--------------------------------------------- + +Azt is korlátozhatja, hogy bizonyos kódok, például egy komponens létrehozása, csak bizonyos műveletek esetén legyenek elérhetők a prezenterben: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Egyetlen művelethez nem szükséges tömböt írni: `#[Requires(actions: 'default')]` + + +Egyéni attribútumok .[#toc-custom-attributes] +--------------------------------------------- + +Ha a `#[Requires]` attribútumot ismételten ugyanazokkal a beállításokkal használni, létrehozhat saját attribútumot, amely örökli a `#[Requires]` és az igényeinek megfelelően állíthatja be. + +Például, `#[SingleAction]` csak a `default` műveleten keresztül engedélyezi a hozzáférést: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Vagy `#[RestMethods]` lehetővé teszi a hozzáférést a REST API-hoz használt összes HTTP-módszeren keresztül: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Következtetés .[#toc-conclusion] +-------------------------------- + +A `#[Requires]` attribútum nagyfokú rugalmasságot és ellenőrzést biztosít a weboldalak elérésének módját illetően. Egyszerű, de hatékony szabályok használatával fokozhatja az alkalmazás biztonságát és megfelelő működését. Amint láthatja, az attribútumok használata a Nette-ben nemcsak egyszerűsítheti, hanem biztosíthatja is a munkáját. + +{{sitename: Best Practices}} diff --git a/best-practices/hu/dynamic-snippets.texy b/best-practices/hu/dynamic-snippets.texy index 508065649e..9234d5b6ce 100644 --- a/best-practices/hu/dynamic-snippets.texy +++ b/best-practices/hu/dynamic-snippets.texy @@ -35,7 +35,7 @@ Template: Ajaxization .[#toc-ajaxization] =============================== -Vigyük most az AJAX-ot ebbe az egyszerű alkalmazásba. Egy cikk értékelésének megváltoztatása nem elég fontos ahhoz, hogy HTTP-kérést igényeljen átirányítással, így ideális esetben ezt AJAX-szel kell elvégezni a háttérben. Használni fogjuk a [kezelőszkriptet a kiegészítésekből |https://componette.org/vojtech-dobes/nette.ajax.js/] a szokásos konvencióval, hogy az AJAX linkek CSS osztálya a `ajax`. +Vigyük most az AJAX-ot ebbe az egyszerű alkalmazásba. Egy cikk értékelésének megváltoztatása nem elég fontos ahhoz, hogy HTTP-kérést igényeljen átirányítással, így ideális esetben ezt AJAX-szel kell elvégezni a háttérben. Használni fogjuk a [kezelőszkriptet a kiegészítésekből |application:ajax#toc-naja] a szokásos konvencióval, hogy az AJAX linkek CSS osztálya a `ajax`. Azonban hogyan kell ezt konkrétan megtenni? A Nette 2 módszert kínál: a dinamikus snippet módot és a komponens módot. Mindkettőnek megvannak az előnyei és hátrányai, ezért egyenként mutatjuk be őket. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Természetesen meg fogjuk változtatni a nézetsablont, és hozzá kell adnunk e ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/hu/post-links.texy b/best-practices/hu/post-links.texy new file mode 100644 index 0000000000..7fa8a2a16e --- /dev/null +++ b/best-practices/hu/post-links.texy @@ -0,0 +1,59 @@ +Hogyan kell helyesen használni a POST linkeket +********************************************** + +A webes alkalmazásokban, különösen az adminisztrációs felületeken alapvető szabály kell, hogy legyen, hogy a kiszolgáló állapotát megváltoztató műveleteket nem szabad a HTTP GET módszerrel végrehajtani. Ahogy a módszer neve is sugallja, a GET csak adatok lekérdezésére használható, azok megváltoztatására nem. +Az olyan műveletekhez, mint például a rekordok törlése, célszerűbb a POST módszert használni. Bár az ideális a DELETE módszer használata lenne, ez nem hívható elő JavaScript nélkül, ezért a POST módszert használják. + +Hogyan kell ezt a gyakorlatban csinálni? Használja ezt az egyszerű trükköt. A sablon elején hozzon létre egy segédűrlapot a `postForm` azonosítóval, amelyet aztán a törlés gombokhoz fog használni: + +```latte .{file:@layout.latte} +
+``` + +Ezzel az űrlappal használhat egy `
diff --git a/best-practices/it/attribute-requires.texy b/best-practices/it/attribute-requires.texy new file mode 100644 index 0000000000..f6a54bf381 --- /dev/null +++ b/best-practices/it/attribute-requires.texy @@ -0,0 +1,179 @@ +Come utilizzare l'attributo `#[Requires]` Attributo +*************************************************** + +.[perex] +Quando si scrive un'applicazione web, spesso si incontra la necessità di limitare l'accesso a certe parti dell'applicazione. Forse si desidera che alcune richieste possano essere inviate solo tramite un modulo (utilizzando quindi il metodo POST) o che siano accessibili solo alle chiamate AJAX. In Nette Framework 3.2 è stato introdotto un nuovo strumento che consente di impostare tali restrizioni in modo elegante e chiaro: l'attributo `#[Requires]` attributo. + +L'attributo è un marcatore speciale in PHP, che si aggiunge prima della definizione di una classe o di un metodo. Poiché si tratta essenzialmente di una classe, è necessario includere la clausola use per far funzionare gli esempi seguenti: + +```php +use Nette\Application\Attributes\Requires; +``` + +È possibile utilizzare l'attributo `#[Requires]` con la classe del presentatore e con questi metodi: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Anche gli ultimi due metodi riguardano i componenti, quindi è possibile utilizzare l'attributo anche con essi. + +Se le condizioni specificate dall'attributo non sono soddisfatte, viene generato un errore HTTP 4xx. + + +Metodi HTTP .[#toc-http-methods] +-------------------------------- + +È possibile specificare quali metodi HTTP (come GET, POST, ecc.) sono consentiti per l'accesso. Ad esempio, se si desidera consentire l'accesso solo tramite l'invio di un modulo, impostare: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Perché usare POST invece di GET per le azioni di modifica dello stato e come farlo? [Leggete la guida |post-links]. + +È possibile specificare un metodo o una serie di metodi. Un caso particolare è il valore `'*'` per abilitare tutti i metodi, che i presentatori non consentono di default per [motivi di sicurezza |application:presenters#http-method-check]. + + +Chiamate AJAX .[#toc-ajax-calls] +-------------------------------- + +Se si desidera che un presentatore o un metodo sia accessibile solo per le richieste AJAX, utilizzare: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Stessa origine .[#toc-same-origin] +---------------------------------- + +Per migliorare la sicurezza, è possibile richiedere che la richiesta venga effettuata dallo stesso dominio. In questo modo si evita la [vulnerabilità al CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Per i metodi `handle()` l'accesso dallo stesso dominio è automaticamente richiesto. Pertanto, se si desidera consentire l'accesso da qualsiasi dominio, specificare: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Accesso tramite Forward .[#toc-access-via-forward] +-------------------------------------------------- + +A volte è utile limitare l'accesso a un presentatore in modo che sia disponibile solo indirettamente, ad esempio utilizzando i metodi `forward()` o `switch()` di un altro presentatore. In questo modo si proteggono i presentatori di errori, per evitare che vengano attivati da un URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +In pratica, spesso è necessario contrassegnare alcune viste a cui si può accedere solo in base alla logica del presentatore. Anche in questo caso, in modo che non possano essere aperte direttamente: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Azioni specifiche .[#toc-specific-actions] +------------------------------------------ + +È anche possibile limitare l'accesso a determinati codici, come la creazione di un componente, solo per azioni specifiche nel presentatore: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Per una singola azione, non è necessario scrivere un array: `#[Requires(actions: 'default')]` + + +Attributi personalizzati .[#toc-custom-attributes] +-------------------------------------------------- + +Se si desidera utilizzare l'attributo `#[Requires]` con le stesse impostazioni, è possibile creare un attributo personalizzato che erediterà `#[Requires]` e impostarlo secondo le proprie esigenze. + +Ad esempio, `#[SingleAction]` consente l'accesso solo attraverso l'azione `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Oppure `#[RestMethods]` consentirà l'accesso tramite tutti i metodi HTTP utilizzati per l'API REST: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Conclusione .[#toc-conclusion] +------------------------------ + +L'attributo `#[Requires]` offre grande flessibilità e controllo sulle modalità di accesso alle pagine web. Utilizzando regole semplici ma potenti, è possibile migliorare la sicurezza e il corretto funzionamento dell'applicazione. Come si può vedere, l'uso degli attributi in Nette non solo semplifica il lavoro, ma lo rende anche sicuro. + +{{sitename: Best Practices}} diff --git a/best-practices/it/dynamic-snippets.texy b/best-practices/it/dynamic-snippets.texy index 870ac5ebdc..c195b97853 100644 --- a/best-practices/it/dynamic-snippets.texy +++ b/best-practices/it/dynamic-snippets.texy @@ -35,7 +35,7 @@ Template: Ajaxization .[#toc-ajaxization] =============================== -Ora aggiungiamo AJAX a questa semplice applicazione. La modifica della valutazione di un articolo non è abbastanza importante da richiedere una richiesta HTTP con redirect, quindi idealmente dovrebbe essere fatta con AJAX in background. Utilizzeremo lo [script handler di add-on |https://componette.org/vojtech-dobes/nette.ajax.js/] con la solita convenzione che i link AJAX abbiano la classe CSS `ajax`. +Ora aggiungiamo AJAX a questa semplice applicazione. La modifica della valutazione di un articolo non è abbastanza importante da richiedere una richiesta HTTP con redirect, quindi idealmente dovrebbe essere fatta con AJAX in background. Utilizzeremo lo [script handler di add-on |application:ajax#toc-naja] con la solita convenzione che i link AJAX abbiano la classe CSS `ajax`. Tuttavia, come farlo in modo specifico? Nette offre due modi: quello degli snippet dinamici e quello dei componenti. Entrambi hanno pro e contro, quindi li mostreremo uno per uno. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Naturalmente cambieremo il modello della vista e dovremo aggiungere un factory a ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/it/post-links.texy b/best-practices/it/post-links.texy new file mode 100644 index 0000000000..8fbca0e2c4 --- /dev/null +++ b/best-practices/it/post-links.texy @@ -0,0 +1,59 @@ +Come utilizzare correttamente i link POST +***************************************** + +Nelle applicazioni web, soprattutto nelle interfacce amministrative, dovrebbe essere una regola di base che le azioni che modificano lo stato del server non dovrebbero essere eseguite tramite il metodo HTTP GET. Come suggerisce il nome del metodo, GET deve essere usato solo per recuperare dati, non per modificarli. +Per azioni come la cancellazione di record, è più appropriato usare il metodo POST. Anche se l'ideale sarebbe usare il metodo DELETE, questo non può essere invocato senza JavaScript, quindi storicamente si usa POST. + +Come fare nella pratica? Utilizzando questo semplice trucco. All'inizio del modello, creare un modulo di aiuto con l'identificatore `postForm`, che verrà poi utilizzato per i pulsanti di cancellazione: + +```latte .{file:@layout.latte} +
+``` + +Con questo modulo, è possibile utilizzare un elemento `
diff --git a/best-practices/pl/attribute-requires.texy b/best-practices/pl/attribute-requires.texy new file mode 100644 index 0000000000..2c79b3fc87 --- /dev/null +++ b/best-practices/pl/attribute-requires.texy @@ -0,0 +1,179 @@ +Jak używać atrybutu `#[Requires]` Atrybut +***************************************** + +.[perex] +Podczas pisania aplikacji internetowej często pojawia się potrzeba ograniczenia dostępu do niektórych jej części. Być może chcesz, aby niektóre żądania mogły wysyłać dane tylko za pośrednictwem formularza (a więc przy użyciu metody POST) lub aby były dostępne tylko dla wywołań AJAX. W Nette Framework 3.2 wprowadzono nowe narzędzie, które pozwala ustawić takie ograniczenia w elegancki i przejrzysty sposób: atrybut `#[Requires]` atrybut. + +Atrybut jest specjalnym znacznikiem w PHP, który dodaje się przed definicją klasy lub metody. Ponieważ jest to zasadniczo klasa, musisz dołączyć klauzulę use, aby poniższe przykłady działały: + +```php +use Nette\Application\Attributes\Requires; +``` + +Atrybutu `#[Requires]` z samą klasą prezentera i tymi metodami: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Dwie ostatnie metody również dotyczą komponentów, więc można użyć atrybutu również z nimi. + +Jeśli warunki określone przez atrybut nie są spełnione, wywoływany jest błąd HTTP 4xx. + + +Metody HTTP .[#toc-http-methods] +-------------------------------- + +Można określić, które metody HTTP (takie jak GET, POST itp.) są dozwolone dla dostępu. Na przykład, jeśli chcesz zezwolić na dostęp tylko poprzez przesłanie formularza, ustaw: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Dlaczego należy używać POST zamiast GET do akcji zmieniających stan i jak to zrobić? [Przeczytaj przewodnik |post-links]. + +Można określić metodę lub tablicę metod. Szczególnym przypadkiem jest wartość `'*'`, która włącza wszystkie metody, na które prezentery nie pozwalają domyślnie ze [względów |application:presenters#http-method-check] bezpieczeństwa. + + +Wywołania AJAX .[#toc-ajax-calls] +--------------------------------- + +Jeśli chcesz, aby prezenter lub metoda były dostępne tylko dla żądań AJAX, użyj: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +To samo pochodzenie .[#toc-same-origin] +--------------------------------------- + +Aby zwiększyć bezpieczeństwo, można wymagać, aby żądanie zostało wykonane z tej samej domeny. Zapobiega to [podatności na CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Dla `handle()` automatycznie wymagany jest dostęp z tej samej domeny. Jeśli więc chcesz zezwolić na dostęp z dowolnej domeny, określ: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Dostęp przez Forward .[#toc-access-via-forward] +----------------------------------------------- + +Czasami przydatne jest ograniczenie dostępu do prezentera, tak aby był on dostępny tylko pośrednio, na przykład przy użyciu metod `forward()` lub `switch()` z innego prezentera. W ten sposób chronione są prezentery błędów, aby uniemożliwić ich wywołanie z adresu URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +W praktyce często konieczne jest oznaczenie pewnych widoków, do których można uzyskać dostęp tylko w oparciu o logikę w prezenterze. Ponownie, aby nie można było ich otworzyć bezpośrednio: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Konkretne działania .[#toc-specific-actions] +-------------------------------------------- + +Można również ograniczyć dostęp do określonego kodu, takiego jak tworzenie komponentu, tylko dla określonych akcji w prezenterze: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Dla pojedynczej akcji nie ma potrzeby pisania tablicy: `#[Requires(actions: 'default')]` + + +Atrybuty niestandardowe .[#toc-custom-attributes] +------------------------------------------------- + +Jeśli chcesz używać atrybutu `#[Requires]` z tymi samymi ustawieniami, można utworzyć własny atrybut, który będzie dziedziczył `#[Requires]` i ustawić go zgodnie z własnymi potrzebami. + +Na przykład, `#[SingleAction]` zezwala na dostęp tylko poprzez akcję `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +lub `#[RestMethods]` umożliwi dostęp za pośrednictwem wszystkich metod HTTP używanych w interfejsie API REST: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Wnioski .[#toc-conclusion] +-------------------------- + +Atrybut `#[Requires]` zapewnia dużą elastyczność i kontrolę nad sposobem dostępu do stron internetowych. Korzystając z prostych, ale potężnych reguł, można zwiększyć bezpieczeństwo i prawidłowe funkcjonowanie aplikacji. Jak widać, korzystanie z atrybutów w Nette może nie tylko uprościć pracę, ale także ją zabezpieczyć. + +{{sitename: Best Practices}} diff --git a/best-practices/pl/dynamic-snippets.texy b/best-practices/pl/dynamic-snippets.texy index c1ad93724d..74c1c17c1f 100644 --- a/best-practices/pl/dynamic-snippets.texy +++ b/best-practices/pl/dynamic-snippets.texy @@ -35,7 +35,7 @@ Szablon: Ajaxizacja .[#toc-ajaxization] ============================== -Wyposażmy teraz tę prostą aplikację w AJAX. Zmiana oceny artykułu nie jest na tyle ważna, aby wymagała przekierowania, więc idealnie powinna być wykonana z AJAX w tle. Wykorzystamy [skrypt handler z dodatków ze |https://componette.org/vojtech-dobes/nette.ajax.js/] zwykłą konwencją, że linki AJAX mają klasę CSS `ajax`. +Wyposażmy teraz tę prostą aplikację w AJAX. Zmiana oceny artykułu nie jest na tyle ważna, aby wymagała przekierowania, więc idealnie powinna być wykonana z AJAX w tle. Wykorzystamy [skrypt handler z dodatków ze |application:ajax#toc-naja] zwykłą konwencją, że linki AJAX mają klasę CSS `ajax`. Jednak jak to konkretnie zrobić? Nette oferuje 2 ścieżki: tzw. ścieżkę dynamicznych snippetów oraz ścieżkę komponentów. Oba mają swoje plusy i minusy, więc pokażemy je po kolei. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Oczywiście zmienimy szablon widoku i będziemy musieli dodać fabrykę do preze ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/pl/post-links.texy b/best-practices/pl/post-links.texy new file mode 100644 index 0000000000..9db658ec70 --- /dev/null +++ b/best-practices/pl/post-links.texy @@ -0,0 +1,59 @@ +Jak prawidłowo używać linków POST +********************************* + +W aplikacjach internetowych, zwłaszcza w interfejsach administracyjnych, podstawową zasadą powinno być to, że działania zmieniające stan serwera nie powinny być wykonywane za pomocą metody HTTP GET. Jak sugeruje nazwa metody, GET powinien być używany tylko do pobierania danych, a nie do ich zmiany. +W przypadku działań takich jak usuwanie rekordów, bardziej odpowiednie jest użycie metody POST. Chociaż idealnym rozwiązaniem byłoby użycie metody DELETE, nie można jej wywołać bez JavaScript, dlatego POST jest historycznie używany. + +Jak to zrobić w praktyce? Użyj tej prostej sztuczki. Na początku szablonu utwórz formularz pomocniczy o identyfikatorze `postForm`, który następnie użyjesz dla przycisków usuwania: + +```latte .{file:@layout.latte} +
+``` + +W tym formularzu możesz użyć `
diff --git a/best-practices/pt/attribute-requires.texy b/best-practices/pt/attribute-requires.texy new file mode 100644 index 0000000000..af9f1f4ec0 --- /dev/null +++ b/best-practices/pt/attribute-requires.texy @@ -0,0 +1,179 @@ +Como usar o `#[Requires]` Atributo +********************************** + +.[perex] +Ao escrever um aplicativo da Web, você frequentemente se depara com a necessidade de restringir o acesso a determinadas partes do aplicativo. Talvez você queira que algumas solicitações só possam enviar dados por meio de um formulário (usando, portanto, o método POST) ou que sejam acessíveis somente a chamadas AJAX. No Nette Framework 3.2, foi introduzida uma nova ferramenta que permite que você defina essas restrições de forma elegante e clara: o atributo `#[Requires]` atributo. + +O atributo é um marcador especial no PHP, que você adiciona antes da definição de uma classe ou método. Como ele é essencialmente uma classe, você precisa incluir a cláusula use para que os exemplos a seguir funcionem: + +```php +use Nette\Application\Attributes\Requires; +``` + +Você pode usar o atributo `#[Requires]` com a própria classe do apresentador e nesses métodos: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Os dois últimos métodos também se referem a componentes, portanto, você também pode usar o atributo com eles. + +Se as condições especificadas pelo atributo não forem atendidas, será acionado um erro HTTP 4xx. + + +Métodos HTTP .[#toc-http-methods] +--------------------------------- + +Você pode especificar quais métodos HTTP (como GET, POST, etc.) são permitidos para acesso. Por exemplo, se você quiser permitir o acesso somente por meio do envio de um formulário, defina: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Por que você deve usar POST em vez de GET para ações de alteração de estado e como fazer isso? [Leia o guia |post-links]. + +Você pode especificar um método ou uma matriz de métodos. Um caso especial é o valor `'*'` para ativar todos os métodos, que os apresentadores não permitem por padrão por [motivos de segurança |application:presenters#http-method-check]. + + +Chamadas AJAX .[#toc-ajax-calls] +-------------------------------- + +Se você quiser que um apresentador ou método seja acessível somente para solicitações AJAX, use: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Mesma origem .[#toc-same-origin] +-------------------------------- + +Para aumentar a segurança, você pode exigir que a solicitação seja feita a partir do mesmo domínio. Isso evita a [vulnerabilidade ao CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Para os métodos `handle()` o acesso do mesmo domínio é automaticamente necessário. Portanto, se você quiser permitir o acesso de qualquer domínio, especifique: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Acesso via Forward .[#toc-access-via-forward] +--------------------------------------------- + +Às vezes, é útil restringir o acesso a um apresentador para que ele esteja disponível apenas indiretamente, por exemplo, usando os métodos `forward()` ou `switch()` de outro apresentador. É assim que os apresentadores de erros são protegidos para evitar que sejam acionados a partir de um URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Na prática, muitas vezes é necessário marcar determinadas exibições que só podem ser acessadas com base na lógica do apresentador. Novamente, para que elas não possam ser abertas diretamente: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Ações específicas .[#toc-specific-actions] +------------------------------------------ + +Você também pode restringir o acesso a determinados códigos, como a criação de um componente, apenas para ações específicas no apresentador: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Para uma única ação, não há necessidade de escrever uma matriz: `#[Requires(actions: 'default')]` + + +Atributos personalizados .[#toc-custom-attributes] +-------------------------------------------------- + +Se você quiser usar o atributo `#[Requires]` repetidamente com as mesmas configurações, você pode criar seu próprio atributo que herdará o atributo `#[Requires]` e defini-lo de acordo com suas necessidades. + +Por exemplo, `#[SingleAction]` permite o acesso somente por meio da ação `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Ou `#[RestMethods]` permitirá o acesso por meio de todos os métodos HTTP usados para a API REST: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Conclusão .[#toc-conclusion] +---------------------------- + +O atributo `#[Requires]` oferece grande flexibilidade e controle sobre como as páginas da Web são acessadas. Usando regras simples, porém poderosas, você pode aumentar a segurança e o funcionamento adequado do seu aplicativo. Como você pode ver, o uso de atributos no Nette pode não apenas simplificar seu trabalho, mas também torná-lo seguro. + +{{sitename: Best Practices}} diff --git a/best-practices/pt/dynamic-snippets.texy b/best-practices/pt/dynamic-snippets.texy index 660329a182..65434b41c0 100644 --- a/best-practices/pt/dynamic-snippets.texy +++ b/best-practices/pt/dynamic-snippets.texy @@ -35,7 +35,7 @@ Modelo: Ajaxização .[#toc-ajaxization] ============================== -Vamos agora trazer o AJAX para esta simples aplicação. Mudar a classificação de um artigo não é suficientemente importante para exigir um pedido HTTP com redirecionamento, então o ideal é que isso seja feito com AJAX em segundo plano. Usaremos o [script do handler dos add-ons |https://componette.org/vojtech-dobes/nette.ajax.js/] com a convenção usual de que os links AJAX têm a classe CSS `ajax`. +Vamos agora trazer o AJAX para esta simples aplicação. Mudar a classificação de um artigo não é suficientemente importante para exigir um pedido HTTP com redirecionamento, então o ideal é que isso seja feito com AJAX em segundo plano. Usaremos o [script do handler dos add-ons |application:ajax#toc-naja] com a convenção usual de que os links AJAX têm a classe CSS `ajax`. No entanto, como fazer isso especificamente? A Nette oferece 2 maneiras: a maneira dinâmica do snippet e a maneira dos componentes. Ambas têm seus prós e contras, por isso vamos mostrar-lhes uma a uma. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Modelo de componente: ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/pt/post-links.texy b/best-practices/pt/post-links.texy new file mode 100644 index 0000000000..453fc217e1 --- /dev/null +++ b/best-practices/pt/post-links.texy @@ -0,0 +1,59 @@ +Como usar corretamente os links POST +************************************ + +Em aplicativos da Web, especialmente em interfaces administrativas, deve ser uma regra básica que as ações que alteram o estado do servidor não sejam executadas por meio do método HTTP GET. Como o nome do método sugere, o GET deve ser usado somente para recuperar dados, não para alterá-los. +Para ações como a exclusão de registros, é mais apropriado usar o método POST. Embora o ideal fosse usar o método DELETE, ele não pode ser invocado sem JavaScript, por isso o POST é historicamente usado. + +Como fazer isso na prática? Use este truque simples. No início do seu modelo, crie um formulário auxiliar com o identificador `postForm`, que você usará para os botões de exclusão: + +```latte .{file:@layout.latte} +
+``` + +Com esse formulário, você pode usar um `
diff --git a/best-practices/ro/attribute-requires.texy b/best-practices/ro/attribute-requires.texy new file mode 100644 index 0000000000..7d541aaa50 --- /dev/null +++ b/best-practices/ro/attribute-requires.texy @@ -0,0 +1,179 @@ +Cum se utilizează `#[Requires]` Atributul +***************************************** + +.[perex] +Atunci când scrieți o aplicație web, vă confruntați adesea cu necesitatea de a restricționa accesul la anumite părți ale aplicației. Poate doriți ca unele cereri să poată trimite date doar prin intermediul unui formular (utilizând astfel metoda POST) sau să fie accesibile doar apelurilor AJAX. În Nette Framework 3.2, a fost introdus un nou instrument care vă permite să stabiliți astfel de restricții în mod elegant și clar: instrumentul `#[Requires]` atribut. + +Atributul este un marker special în PHP, pe care îl adăugați înainte de definiția unei clase sau metode. Deoarece este în esență o clasă, trebuie să includeți clauza use pentru ca următoarele exemple să funcționeze: + +```php +use Nette\Application\Attributes\Requires; +``` + +Puteți utiliza funcția `#[Requires]` cu clasa presenter în sine și cu aceste metode: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Ultimele două metode se referă, de asemenea, la componente, astfel încât puteți utiliza atributul și cu acestea. + +În cazul în care condițiile specificate de atribut nu sunt îndeplinite, se declanșează o eroare HTTP 4xx. + + +Metode HTTP .[#toc-http-methods] +-------------------------------- + +Puteți specifica ce metode HTTP (cum ar fi GET, POST etc.) sunt permise pentru acces. De exemplu, dacă doriți să permiteți accesul numai prin trimiterea unui formular, setați: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +De ce ar trebui să folosiți POST în loc de GET pentru acțiunile de schimbare a stării și cum să faceți acest lucru? [Citiți ghidul |post-links]. + +Puteți specifica o metodă sau o serie de metode. Un caz special este valoarea `'*'` pentru a activa toate metodele, pe care prezentatorii nu o permit în mod implicit din [motive de securitate |application:presenters#http-method-check]. + + +Apeluri AJAX .[#toc-ajax-calls] +------------------------------- + +Dacă doriți ca un prezentator sau o metodă să fie accesibilă numai pentru cererile AJAX, utilizați: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Aceeași origine .[#toc-same-origin] +----------------------------------- + +Pentru a spori securitatea, puteți solicita ca solicitarea să fie făcută din același domeniu. Acest lucru previne [vulnerabilitatea la CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Pentru `handle()` este necesar în mod automat accesul din același domeniu. Prin urmare, dacă doriți să permiteți accesul din orice domeniu, specificați: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Acces prin Forward .[#toc-access-via-forward] +--------------------------------------------- + +Uneori este util să se restricționeze accesul la un prezentator astfel încât acesta să fie disponibil doar indirect, de exemplu, prin utilizarea metodelor `forward()` sau `switch()` de la un alt prezentator. Acesta este modul în care sunt protejați prezentatorii de erori pentru a împiedica declanșarea lor de la un URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +În practică, este adesea necesar să se marcheze anumite vizualizări care pot fi accesate numai pe baza logicii din prezentator. Din nou, pentru ca acestea să nu poată fi deschise direct: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Acțiuni specifice .[#toc-specific-actions] +------------------------------------------ + +Puteți, de asemenea, să restricționați accesul la anumite coduri, cum ar fi crearea unei componente, numai pentru anumite acțiuni din prezentator: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Pentru o singură acțiune, nu este nevoie să scrieți o matrice: `#[Requires(actions: 'default')]` + + +Atribute personalizate .[#toc-custom-attributes] +------------------------------------------------ + +Dacă doriți să utilizați `#[Requires]` în mod repetat cu aceleași setări, puteți crea propriul atribut care va moșteni atributul `#[Requires]` și să îl setați în funcție de nevoile dumneavoastră. + +De exemplu, `#[SingleAction]` permite accesul numai prin intermediul acțiunii `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Sau `#[RestMethods]` va permite accesul prin toate metodele HTTP utilizate pentru API REST: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Concluzie .[#toc-conclusion] +---------------------------- + +The `#[Requires]` vă oferă o mare flexibilitate și control asupra modului în care sunt accesate paginile dvs. web. Utilizând reguli simple, dar puternice, puteți spori securitatea și buna funcționare a aplicației dumneavoastră. După cum puteți vedea, utilizarea atributelor în Nette nu numai că vă poate simplifica munca, dar o poate și securiza. + +{{sitename: Best Practices}} diff --git a/best-practices/ro/dynamic-snippets.texy b/best-practices/ro/dynamic-snippets.texy index c5201295d5..3635169fd9 100644 --- a/best-practices/ro/dynamic-snippets.texy +++ b/best-practices/ro/dynamic-snippets.texy @@ -35,7 +35,7 @@ public function handleUnlike(int $articleId): void Ajaxizare .[#toc-ajaxization] ============================= -Să aducem acum AJAX în această aplicație simplă. Modificarea ratingului unui articol nu este suficient de importantă pentru a necesita o cerere HTTP cu redirecționare, așa că, în mod ideal, ar trebui să se facă cu AJAX în fundal. Vom folosi [scriptul handler din add-ons |https://componette.org/vojtech-dobes/nette.ajax.js/] cu convenția obișnuită ca legăturile AJAX să aibă clasa CSS `ajax`. +Să aducem acum AJAX în această aplicație simplă. Modificarea ratingului unui articol nu este suficient de importantă pentru a necesita o cerere HTTP cu redirecționare, așa că, în mod ideal, ar trebui să se facă cu AJAX în fundal. Vom folosi [scriptul handler din add-ons |application:ajax#toc-naja] cu convenția obișnuită ca legăturile AJAX să aibă clasa CSS `ajax`. Totuși, cum să o facem în mod specific? Nette oferă 2 modalități: modalitatea cu fragmente dinamice și modalitatea cu componente. Ambele au avantajele și dezavantajele lor, așa că le vom prezenta pe rând. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Bineînțeles că vom schimba șablonul de vizualizare și va trebui să adăug ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/ro/post-links.texy b/best-practices/ro/post-links.texy new file mode 100644 index 0000000000..d81e2aa8bb --- /dev/null +++ b/best-practices/ro/post-links.texy @@ -0,0 +1,59 @@ +Cum să folosiți corect legăturile POST +************************************** + +În aplicațiile web, în special în interfețele administrative, ar trebui să fie o regulă de bază ca acțiunile care modifică starea serverului să nu fie efectuate prin metoda HTTP GET. După cum sugerează și numele metodei, GET ar trebui să fie utilizată numai pentru a prelua date, nu pentru a le modifica. +Pentru acțiuni precum ștergerea înregistrărilor, este mai indicat să se utilizeze metoda POST. Deși ideal ar fi să se folosească metoda DELETE, aceasta nu poate fi invocată fără JavaScript, de aceea se folosește în mod obișnuit metoda POST. + +Cum se procedează în practică? Folosiți acest truc simplu. La începutul șablonului dumneavoastră, creați un formular ajutător cu identificatorul `postForm`, pe care îl veți folosi apoi pentru butoanele de ștergere: + +```latte .{file:@layout.latte} +
+``` + +Cu acest formular, puteți utiliza un `
diff --git a/best-practices/ru/attribute-requires.texy b/best-practices/ru/attribute-requires.texy new file mode 100644 index 0000000000..f91273fa06 --- /dev/null +++ b/best-practices/ru/attribute-requires.texy @@ -0,0 +1,179 @@ +Как использовать `#[Requires]` Атрибут +************************************** + +.[perex] +При написании веб-приложений вы часто сталкиваетесь с необходимостью ограничить доступ к определенным частям вашего приложения. Возможно, вы хотите, чтобы некоторые запросы могли отправлять данные только через форму (таким образом, используя метод POST) или были доступны только для вызовов AJAX. В Nette Framework 3.2 появился новый инструмент, позволяющий элегантно и четко задать такие ограничения: атрибут `#[Requires]` атрибут. + +Атрибут - это специальный маркер в PHP, который добавляется перед определением класса или метода. Так как по сути это класс, вам необходимо включить условие use, чтобы следующие примеры работали: + +```php +use Nette\Application\Attributes\Requires; +``` + +Вы можете использовать атрибут `#[Requires]` атрибут в самом классе ведущего и в этих методах: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Последние два метода также относятся к компонентам, поэтому вы можете использовать атрибут и с ними. + +Если условия, указанные в атрибуте, не выполняются, возникает ошибка HTTP 4xx. + + +Методы HTTP .[#toc-http-methods] +-------------------------------- + +Вы можете указать, какие методы HTTP (такие как GET, POST и т. д.) разрешены для доступа. Например, если вы хотите разрешить доступ только при отправке формы, установите: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Почему для действий, изменяющих состояние, следует использовать POST, а не GET, и как это сделать? [Читайте руководство |post-links]. + +Вы можете указать метод или массив методов. Особым случаем является значение `'*'` для включения всех методов, что по умолчанию не разрешается презентаторами из [соображений безопасности |application:presenters#http-method-check]. + + +Вызовы AJAX .[#toc-ajax-calls] +------------------------------ + +Если вы хотите, чтобы ведущий или метод был доступен только для AJAX-запросов, используйте: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +То же происхождение .[#toc-same-origin] +--------------------------------------- + +Для повышения безопасности можно потребовать, чтобы запрос выполнялся из одного и того же домена. Это предотвратит [уязвимость к CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Для `handle()` методов автоматически требуется доступ из того же домена. Поэтому, если вы хотите разрешить доступ из любого домена, укажите: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Доступ через Forward .[#toc-access-via-forward] +----------------------------------------------- + +Иногда полезно ограничить доступ к презентатору так, чтобы он был доступен только косвенно, например, с помощью методов `forward()` или `switch()` из другого презентатора. Так защищаются презентаторы ошибок, чтобы их нельзя было вызвать с URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +На практике часто возникает необходимость пометить определенные представления, доступ к которым возможен только на основе логики в презентере. Опять же, чтобы их нельзя было открыть напрямую: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Конкретные действия .[#toc-specific-actions] +-------------------------------------------- + +Вы также можете ограничить доступ к определенному коду, например к созданию компонента, только для определенных действий в презентере: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Для одного действия нет необходимости писать массив: `#[Requires(actions: 'default')]` + + +Пользовательские атрибуты .[#toc-custom-attributes] +--------------------------------------------------- + +Если вы хотите использовать атрибут `#[Requires]` атрибут многократно с одними и теми же настройками, вы можете создать собственный атрибут, который будет наследоваться `#[Requires]` и настроить его в соответствии с вашими потребностями. + +Например, `#[SingleAction]` разрешает доступ только через действие `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Или `#[RestMethods]` позволит получить доступ через все методы HTTP, используемые для REST API: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Заключение .[#toc-conclusion] +----------------------------- + +Атрибут `#[Requires]` предоставляет вам большую гибкость и контроль над тем, как осуществляется доступ к вашим веб-страницам. Используя простые, но мощные правила, вы можете повысить безопасность и правильное функционирование вашего приложения. Как видите, использование атрибутов в Nette может не только упростить вашу работу, но и обезопасить ее. + +{{sitename: Best Practices}} diff --git a/best-practices/ru/dynamic-snippets.texy b/best-practices/ru/dynamic-snippets.texy index 744b905458..2d90f071b4 100644 --- a/best-practices/ru/dynamic-snippets.texy +++ b/best-practices/ru/dynamic-snippets.texy @@ -35,7 +35,7 @@ Template: Аяксизация .[#toc-ajaxization] ============================== -Теперь давайте привнесем AJAX в это простое приложение. Изменение рейтинга статьи не настолько важно, чтобы требовать HTTP-запрос с перенаправлением, поэтому в идеале это должно быть сделано с помощью AJAX в фоновом режиме. Мы будем использовать [скрипт обработчика из дополнений |https://componette.org/vojtech-dobes/nette.ajax.js/] с обычным соглашением, что AJAX ссылки имеют CSS класс `ajax`. +Теперь давайте привнесем AJAX в это простое приложение. Изменение рейтинга статьи не настолько важно, чтобы требовать HTTP-запрос с перенаправлением, поэтому в идеале это должно быть сделано с помощью AJAX в фоновом режиме. Мы будем использовать [скрипт обработчика из дополнений |application:ajax#toc-naja] с обычным соглашением, что AJAX ссылки имеют CSS класс `ajax`. Однако как это сделать конкретно? Nette предлагает 2 способа: способ динамических фрагментов и способ компонентов. У обоих есть свои плюсы и минусы, поэтому мы покажем их по очереди. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ class LikeControl extends Nette\Application\UI\Control ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/ru/post-links.texy b/best-practices/ru/post-links.texy new file mode 100644 index 0000000000..ac941e667a --- /dev/null +++ b/best-practices/ru/post-links.texy @@ -0,0 +1,59 @@ +Как правильно использовать POST-ссылки +************************************** + +В веб-приложениях, особенно в административных интерфейсах, должно быть основным правилом, что действия, изменяющие состояние сервера, не должны выполняться с помощью метода HTTP GET. Как следует из названия метода, GET должен использоваться только для получения данных, а не для их изменения. +Для таких действий, как удаление записей, целесообразнее использовать метод POST. Хотя идеальным вариантом было бы использование метода DELETE, его невозможно вызвать без JavaScript, поэтому исторически используется POST. + +Как сделать это на практике? Используйте этот простой прием. В начале вашего шаблона создайте вспомогательную форму с идентификатором `postForm`, которую вы затем будете использовать для кнопок удаления: + +```latte .{file:@layout.latte} +
+``` + +В этой форме вы можете использовать `
diff --git a/best-practices/sl/attribute-requires.texy b/best-practices/sl/attribute-requires.texy new file mode 100644 index 0000000000..9c1494eb09 --- /dev/null +++ b/best-practices/sl/attribute-requires.texy @@ -0,0 +1,179 @@ +Kako uporabljati `#[Requires]` Atribut +************************************** + +.[perex] +Pri pisanju spletne aplikacije se pogosto srečate s potrebo po omejitvi dostopa do določenih delov aplikacije. Morda želite, da lahko nekatere zahteve pošljejo podatke samo prek obrazca (torej z uporabo metode POST) ali da so dostopne samo za klice AJAX. V okolju Nette Framework 3.2 je bilo uvedeno novo orodje, ki vam omogoča elegantno in jasno določanje takšnih omejitev: orodje `#[Requires]` atribut. + +Atribut je posebna oznaka v jeziku PHP, ki jo dodate pred definicijo razreda ali metode. Ker gre v bistvu za razred, morate za delovanje naslednjih primerov vključiti klavzulo use: + +```php +use Nette\Application\Attributes\Requires; +``` + +Uporabite lahko `#[Requires]` atribut v samem razredu presenter in v teh metodah: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Tudi zadnji dve metodi se nanašata na komponente, zato lahko atribut uporabite tudi z njima. + +Če pogoji, določeni z atributom, niso izpolnjeni, se sproži napaka HTTP 4xx. + + +Metode HTTP .[#toc-http-methods] +-------------------------------- + +Določite lahko, katere metode HTTP (kot so GET, POST itd.) so dovoljene za dostop. Če želite na primer dovoliti dostop samo z oddajo obrazca, nastavite: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Zakaj za spreminjanje stanja uporabiti POST namesto GET in kako to storiti? [Preberite vodnik |post-links]. + +Določite lahko metodo ali niz metod. Poseben primer je vrednost `'*'` za omogočanje vseh metod, ki jih predstavniki zaradi [varnostnih razlogov |application:presenters#http-method-check] privzeto ne omogočajo. + + +Klici AJAX .[#toc-ajax-calls] +----------------------------- + +Če želite, da je predstavnik ali metoda dostopna samo za zahteve AJAX, uporabite: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Enako poreklo .[#toc-same-origin] +--------------------------------- + +Če želite povečati varnost, lahko zahtevate, da je zahteva poslana iz iste domene. S tem preprečite [ranljivost CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Za `handle()` je samodejno potreben dostop iz iste domene. Če torej želite dovoliti dostop iz katere koli domene, določite: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Dostop prek spletne strani Forward .[#toc-access-via-forward] +------------------------------------------------------------- + +Včasih je koristno omejiti dostop do predstavnika, tako da je na voljo le posredno, na primer z uporabo metod `forward()` ali `switch()` iz drugega predstavnika. Tako so predstavniki napak zaščiteni, da jih ni mogoče sprožiti z naslova URL: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +V praksi je pogosto treba označiti določene poglede, do katerih je mogoče dostopati le na podlagi logike v predstavitvenem programu. Spet tako, da jih ni mogoče odpreti neposredno: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Posebni ukrepi .[#toc-specific-actions] +--------------------------------------- + +Prav tako lahko omejite, da bo določena koda, na primer ustvarjanje komponente, dostopna samo za določena dejanja v predstavitvenem programu: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Za posamezno dejanje ni treba pisati polja: `#[Requires(actions: 'default')]` + + +Atributi po meri .[#toc-custom-attributes] +------------------------------------------ + +Če želite uporabiti `#[Requires]` atribut večkrat uporabiti z enakimi nastavitvami, lahko ustvarite svoj atribut, ki bo podedoval `#[Requires]` in ga nastavite v skladu s svojimi potrebami. + +Na primer, `#[SingleAction]` omogoča dostop samo prek dejanja `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Ali `#[RestMethods]` omogoči dostop prek vseh metod HTTP, ki se uporabljajo za API REST: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Zaključek .[#toc-conclusion] +---------------------------- + +Na spletni strani `#[Requires]` vam omogoča veliko prilagodljivost in nadzor nad načinom dostopa do spletnih strani. Z uporabo preprostih, a zmogljivih pravil lahko izboljšate varnost in pravilno delovanje svoje aplikacije. Kot lahko vidite, lahko z uporabo atributov v Nette ne le poenostavite svoje delo, temveč ga tudi zavarujete. + +{{sitename: Best Practices}} diff --git a/best-practices/sl/dynamic-snippets.texy b/best-practices/sl/dynamic-snippets.texy index dcd25eb0c7..0554bab175 100644 --- a/best-practices/sl/dynamic-snippets.texy +++ b/best-practices/sl/dynamic-snippets.texy @@ -35,7 +35,7 @@ Predloga: Ajaksizacija .[#toc-ajaxization] ================================ -V to preprosto aplikacijo zdaj vnesimo AJAX. Spreminjanje ocene članka ni dovolj pomembno, da bi zahtevalo zahtevo HTTP s preusmeritvijo, zato bi bilo idealno, če bi to opravili z AJAXom v ozadju. Uporabili bomo [skript za obdelavo iz dodatkov |https://componette.org/vojtech-dobes/nette.ajax.js/] z običajno konvencijo, da imajo povezave AJAX razred CSS `ajax`. +V to preprosto aplikacijo zdaj vnesimo AJAX. Spreminjanje ocene članka ni dovolj pomembno, da bi zahtevalo zahtevo HTTP s preusmeritvijo, zato bi bilo idealno, če bi to opravili z AJAXom v ozadju. Uporabili bomo [skript za obdelavo iz dodatkov |application:ajax#toc-naja] z običajno konvencijo, da imajo povezave AJAX razred CSS `ajax`. Vendar pa, kako to storiti konkretno? Nette ponuja dva načina: način z dinamičnimi utrinki in način s komponentami. Oba načina imata svoje prednosti in slabosti, zato ju bomo prikazali enega za drugim. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Seveda bomo spremenili predlogo pogleda in morali bomo dodati tovarno za predsta ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/sl/post-links.texy b/best-practices/sl/post-links.texy new file mode 100644 index 0000000000..8c588b5864 --- /dev/null +++ b/best-practices/sl/post-links.texy @@ -0,0 +1,59 @@ +Kako pravilno uporabljati povezave POST +*************************************** + +V spletnih aplikacijah, zlasti v upravnih vmesnikih, bi moralo veljati osnovno pravilo, da se dejanja, ki spreminjajo stanje strežnika, ne smejo izvajati z metodo HTTP GET. Kot pove že ime metode, naj se GET uporablja samo za pridobivanje podatkov in ne za njihovo spreminjanje. +Za dejanja, kot je brisanje zapisov, je primerneje uporabiti metodo POST. Čeprav bi bilo idealno uporabiti metodo DELETE, je brez JavaScripta ni mogoče izvesti, zato se v preteklosti uporablja metoda POST. + +Kako to storiti v praksi? Uporabite ta preprost trik. Na začetku predloge ustvarite pomožni obrazec z identifikatorjem `postForm`, ki ga boste nato uporabili za gumbe za brisanje: + +```latte .{file:@layout.latte} +
+``` + +S tem obrazcem lahko uporabite `
diff --git a/best-practices/tr/attribute-requires.texy b/best-practices/tr/attribute-requires.texy new file mode 100644 index 0000000000..41ce8c21e6 --- /dev/null +++ b/best-practices/tr/attribute-requires.texy @@ -0,0 +1,179 @@ +Nasıl Kullanılır `#[Requires]` Öznitelik +**************************************** + +.[perex] +Bir web uygulaması yazarken, uygulamanızın belirli bölümlerine erişimi kısıtlama ihtiyacıyla sık sık karşılaşırsınız. Belki de bazı isteklerin yalnızca bir form aracılığıyla veri gönderebilmesini (dolayısıyla POST yöntemini kullanarak) veya yalnızca AJAX çağrıları tarafından erişilebilir olmasını istiyorsunuzdur. Nette Framework 3.2'de, bu tür kısıtlamaları zarif ve açık bir şekilde ayarlamanıza olanak tanıyan yeni bir araç sunulmuştur: `#[Requires]` nitelik. + +Nitelik, PHP'de bir sınıf veya yöntemin tanımından önce eklediğiniz özel bir işarettir. Esasen bir sınıf olduğu için, aşağıdaki örneklerin çalışması için use cümlesini eklemeniz gerekir: + +```php +use Nette\Application\Attributes\Requires; +``` + +Kullanabilirsiniz `#[Requires]` özniteliğinin sunum yapan sınıfın kendisiyle ve bu yöntemlerle olan ilişkisi: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Son iki yöntem de bileşenlerle ilgilidir, bu nedenle özniteliği onlarla da kullanabilirsiniz. + +Öznitelik tarafından belirtilen koşullar karşılanmazsa, bir HTTP 4xx hatası tetiklenir. + + +HTTP Yöntemleri .[#toc-http-methods] +------------------------------------ + +Erişim için hangi HTTP yöntemlerine (GET, POST, vb.) izin verileceğini belirtebilirsiniz. Örneğin, yalnızca bir form göndererek erişime izin vermek istiyorsanız, şunu ayarlayın: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Durum değiştirme eylemleri için neden GET yerine POST kullanmalısınız ve bunu nasıl yapmalısınız? [Kılavuzu okuyun |post-links]. + +Bir yöntem veya bir dizi yöntem belirtebilirsiniz. Özel bir durum, sunum yapanların [güvenlik nedeniyle |application:presenters#http-method-check] varsayılan olarak izin vermediği tüm yöntemleri etkinleştirmek için `'*'` değeridir. + + +AJAX Çağrıları .[#toc-ajax-calls] +--------------------------------- + +Bir sunucunun veya yöntemin yalnızca AJAX istekleri için erişilebilir olmasını istiyorsanız, şunu kullanın: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Aynı Köken .[#toc-same-origin] +------------------------------ + +Güvenliği artırmak için, isteğin aynı etki alanından yapılmasını zorunlu tutabilirsiniz. Bu, [CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]'ye karşı güvenlik açığını önler: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +İçin `handle()` yöntemlerinde, aynı etki alanından erişim otomatik olarak gereklidir. Bu nedenle, herhangi bir etki alanından erişime izin vermek istiyorsanız, şunu belirtin: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Forward üzerinden erişim .[#toc-access-via-forward] +--------------------------------------------------- + +Bazen bir sunucuya erişimi kısıtlamak yararlı olabilir, böylece yalnızca dolaylı olarak, örneğin başka bir sunucudan `forward()` veya `switch()` yöntemleri kullanılarak kullanılabilir. Hata sunucuları, bir URL'den tetiklenmelerini önlemek için bu şekilde korunur: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Pratikte, yalnızca sunum yapan kişideki mantığa dayalı olarak erişilebilen belirli görünümleri işaretlemek genellikle gereklidir. Yine, böylece doğrudan açılamazlar: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Spesifik Eylemler .[#toc-specific-actions] +------------------------------------------ + +Ayrıca, bir bileşen oluşturmak gibi belirli kodların yalnızca sunum aracındaki belirli eylemler için erişilebilir olmasını da kısıtlayabilirsiniz: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Tek bir eylem için bir dizi yazmaya gerek yoktur: `#[Requires(actions: 'default')]` + + +Özel Nitelikler .[#toc-custom-attributes] +----------------------------------------- + +Eğer kullanmak istiyorsanız `#[Requires]` özniteliğini aynı ayarlarla tekrar tekrar kullanmak istemiyorsanız, kendi özniteliğinizi oluşturabilirsiniz. `#[Requires]` ve ihtiyaçlarınıza göre ayarlayın. + +Örneğin, `#[SingleAction]` yalnızca `default` eylemi aracılığıyla erişime izin verir: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Ya da `#[RestMethods]` REST API için kullanılan tüm HTTP yöntemleri aracılığıyla erişime izin verecektir: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Sonuç .[#toc-conclusion] +------------------------ + +Bu `#[Requires]` özelliği, web sayfalarınıza nasıl erişileceği konusunda size büyük esneklik ve kontrol sağlar. Basit ama güçlü kurallar kullanarak uygulamanızın güvenliğini ve düzgün çalışmasını artırabilirsiniz. Gördüğünüz gibi, Nette öznitelikleri kullanmak sadece işinizi basitleştirmekle kalmaz, aynı zamanda güvenli hale de getirir. + +{{sitename: Best Practices}} diff --git a/best-practices/tr/dynamic-snippets.texy b/best-practices/tr/dynamic-snippets.texy index bae43f06d3..30980e895e 100644 --- a/best-practices/tr/dynamic-snippets.texy +++ b/best-practices/tr/dynamic-snippets.texy @@ -35,7 +35,7 @@ public function handleUnlike(int $articleId): void Ajaxlaştırma .[#toc-ajaxization] ================================ -Şimdi bu basit uygulamaya AJAX'ı getirelim. Bir makalenin derecelendirmesini değiştirmek, yönlendirmeli bir HTTP isteği gerektirecek kadar önemli değildir, bu nedenle ideal olarak arka planda AJAX ile yapılmalıdır. AJAX bağlantılarının `ajax` CSS sınıfına sahip olduğu olağan kuralıyla [eklentilerdeki işleyici |https://componette.org/vojtech-dobes/nette.ajax.js/] komut dosyasını kullanacağız. +Şimdi bu basit uygulamaya AJAX'ı getirelim. Bir makalenin derecelendirmesini değiştirmek, yönlendirmeli bir HTTP isteği gerektirecek kadar önemli değildir, bu nedenle ideal olarak arka planda AJAX ile yapılmalıdır. AJAX bağlantılarının `ajax` CSS sınıfına sahip olduğu olağan kuralıyla [eklentilerdeki işleyici |application:ajax#toc-naja] komut dosyasını kullanacağız. Ancak, bunu özellikle nasıl yapmalı? Nette 2 yol sunuyor: dinamik snippet yolu ve bileşen yolu. Her ikisinin de artıları ve eksileri var, bu yüzden bunları tek tek göstereceğiz. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ Elbette görünüm şablonunu değiştireceğiz ve sunucuya bir fabrika eklememi ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/tr/post-links.texy b/best-practices/tr/post-links.texy new file mode 100644 index 0000000000..94bef4ceec --- /dev/null +++ b/best-practices/tr/post-links.texy @@ -0,0 +1,59 @@ +POST Bağlantıları Nasıl Doğru Kullanılır? +***************************************** + +Web uygulamalarında, özellikle de yönetim arayüzlerinde, sunucunun durumunu değiştiren eylemlerin HTTP GET yöntemi ile gerçekleştirilmemesi temel bir kural olmalıdır. Metot adından da anlaşılacağı üzere GET sadece veri almak için kullanılmalıdır, değiştirmek için değil. +Kayıt silme gibi eylemler için POST yönteminin kullanılması daha uygundur. İdeal olan DELETE yöntemini kullanmak olsa da, bu JavaScript olmadan çağrılamaz, bu nedenle POST tarihsel olarak kullanılır. + +Pratikte nasıl yapılır? Bu basit numarayı kullanın. Şablonunuzun başında, daha sonra silme düğmeleri için kullanacağınız `postForm` tanımlayıcısına sahip bir yardımcı form oluşturun: + +```latte .{file:@layout.latte} +
+``` + +Bu form ile, bir `
diff --git a/best-practices/uk/attribute-requires.texy b/best-practices/uk/attribute-requires.texy new file mode 100644 index 0000000000..543ae066c2 --- /dev/null +++ b/best-practices/uk/attribute-requires.texy @@ -0,0 +1,179 @@ +Як використовувати атрибут `#[Requires]` Атрибут +************************************************ + +.[perex] +При написанні веб-додатків часто виникає потреба обмежити доступ до певних частин вашого додатку. Можливо, ви хочете, щоб деякі запити могли надсилати дані лише через форму (використовуючи метод POST) або щоб вони були доступні лише для AJAX-викликів. У Nette Framework 3.2 з'явився новий інструмент, який дозволяє елегантно і зрозуміло встановлювати такі обмеження: атрибут `#[Requires]` атрибут + +Атрибут - це спеціальний маркер в PHP, який ви додаєте перед визначенням класу або методу. Оскільки це, по суті, клас, вам потрібно включити речення use, щоб наведені нижче приклади працювали: + +```php +use Nette\Application\Attributes\Requires; +``` + +Ви можете використовувати атрибут `#[Requires]` з самим класом доповідача та з цими методами: + +- `action()` +- `render()` +- `handle()` +- `createComponent()` + +Останні два методи також стосуються компонентів, тому ви можете використовувати атрибут і з ними. + +Якщо умови, визначені атрибутом, не виконуються, генерується помилка HTTP 4xx. + + +Методи HTTP .[#toc-http-methods] +-------------------------------- + +Ви можете вказати, які HTTP-методи (наприклад, GET, POST тощо) дозволені для доступу. Наприклад, якщо ви хочете дозволити доступ тільки за допомогою відправки форми, встановіть: + +```php +class AdminPresenter extends Nette\Application\UI\Presenter +{ + #[Requires(methods: 'POST')] + public function actionDelete(int $id): void + { + } +} +``` + +Чому для зміни стану слід використовувати POST, а не GET, і як це зробити? [Читайте гайд |post-links]. + +Ви можете вказати метод або масив методів. Особливим випадком є значення `'*'`, щоб увімкнути всі методи, що не дозволяється за замовчуванням з [міркувань безпеки |application:presenters#http-method-check]. + + +AJAX-дзвінки .[#toc-ajax-calls] +------------------------------- + +Якщо ви хочете, щоб доповідач або метод був доступний лише для AJAX-запитів, використовуйте цей параметр: + +```php +#[Requires(ajax: true)] +class AjaxPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Одного походження .[#toc-same-origin] +------------------------------------- + +Щоб підвищити безпеку, ви можете вимагати, щоб запит був зроблений з того ж домену. Це запобігає [вразливості до CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]: + +```php +#[Requires(sameOrigin: true)] +class SecurePresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Для методів `handle()` автоматично вимагається доступ з того ж домену. Тому, якщо ви хочете дозволити доступ з будь-якого домену, вкажіть це: + +```php +#[Requires(sameOrigin: false)] +public function handleList(): void +{ +} +``` + + +Доступ через Форвард .[#toc-access-via-forward] +----------------------------------------------- + +Іноді корисно обмежити доступ до презентера так, щоб він був доступний лише опосередковано, наприклад, за допомогою методів `forward()` або `switch()` з іншого презентера. Так захищаються презентери, що спричиняють помилки, щоб запобігти їхньому запуску з URL-адреси: + +```php +#[Requires(forward: true)] +class ForwardedPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +На практиці часто виникає потреба позначити певні подання, доступ до яких можна отримати лише на основі логіки в презентері. Знову ж таки, щоб їх не можна було відкрити безпосередньо: + +```php +class ProductPresenter extends Nette\Application\UI\Presenter +{ + + public function actionDefault(int $id): void + { + $product = this->facade->getProduct($id); + if (!product) { + this->setView('notfound'); + } + } + + #[Requires(forward: true)] + public function renderNotFound(): void + { + } +} +``` + + +Конкретні дії .[#toc-specific-actions] +-------------------------------------- + +Ви також можете обмежити доступ до певного коду, наприклад, створення компонента, лише для певних дій у презентері: + +```php +class EditDeletePresenter extends Nette\Application\UI\Presenter +{ + #[Requires(actions: ['add', 'edit'])] + public function createComponentPostForm() + { + } +} +``` + +Для однієї дії не потрібно писати масив: `#[Requires(actions: 'default')]` + + +Користувацькі атрибути .[#toc-custom-attributes] +------------------------------------------------ + +Якщо ви хочете використовувати атрибут `#[Requires]` з тими самими налаштуваннями, ви можете створити власний атрибут, який успадкує `#[Requires]` і налаштувати його відповідно до ваших потреб. + +Наприклад `#[SingleAction]` дозволяє доступ тільки через дію `default`: + +```php +#[Attribute] +class SingleAction extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(actions: 'default'); + } +} + +#[SingleAction] +class SingleActionPresenter extends Nette\Application\UI\Presenter +{ +} +``` + +Або `#[RestMethods]` дозволить доступ за допомогою всіх HTTP-методів, що використовуються для REST API: + +```php +#[\Attribute] +class RestMethods extends Nette\Application\Attributes\Requires +{ + public function __construct() + { + parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + } +} + +#[RestMethods] +class ApiPresenter extends Nette\Application\UI\Presenter +{ +} +``` + + +Висновок .[#toc-conclusion] +--------------------------- + +Атрибут `#[Requires]` надає вам велику гнучкість і контроль над тим, як здійснюється доступ до ваших веб-сторінок. Використовуючи прості, але потужні правила, ви можете підвищити безпеку та належне функціонування вашого додатку. Як бачите, використання атрибутів у Nette може не тільки спростити вашу роботу, але й убезпечити її. + +{{sitename: Best Practices}} diff --git a/best-practices/uk/dynamic-snippets.texy b/best-practices/uk/dynamic-snippets.texy index 40867a88cf..33872a3b0e 100644 --- a/best-practices/uk/dynamic-snippets.texy +++ b/best-practices/uk/dynamic-snippets.texy @@ -35,7 +35,7 @@ Template: Аяксизація .[#toc-ajaxization] ============================== -Тепер давайте привнесемо AJAX у цей простий додаток. Зміна рейтингу статті не настільки важлива, щоб вимагати HTTP-запит із переспрямуванням, тому в ідеалі це має бути зроблено за допомогою AJAX у фоновому режимі. Ми будемо використовувати [скрипт обробника з додат |https://componette.org/vojtech-dobes/nette.ajax.js/] ків зі звичайною угодою, що AJAX-посилання мають CSS клас `ajax`. +Тепер давайте привнесемо AJAX у цей простий додаток. Зміна рейтингу статті не настільки важлива, щоб вимагати HTTP-запит із переспрямуванням, тому в ідеалі це має бути зроблено за допомогою AJAX у фоновому режимі. Ми будемо використовувати [скрипт обробника з додат |application:ajax#toc-naja] ків зі звичайною угодою, що AJAX-посилання мають CSS клас `ajax`. Однак як це зробити конкретно? Nette пропонує 2 способи: спосіб динамічних фрагментів і спосіб компонентів. Обидва мають свої плюси та мінуси, тому ми покажемо їх по черзі. @@ -92,7 +92,7 @@ public function handleLike(int $articleId): void if ($this->isAjax()) { // ... $this->template->articles = [ - $this->connection->table('articles')->get($articleId), + $this->db->table('articles')->get($articleId), ]; } else { // ... @@ -101,7 +101,7 @@ public function handleLike(int $articleId): void public function renderDefault(): void { if (!isset($this->template->articles)) { - $this->template->articles = $this->connection->table('articles'); + $this->template->articles = $this->db->table('articles'); } } ``` @@ -151,7 +151,7 @@ class LikeControl extends Nette\Application\UI\Control ```php protected function createComponentLikeControl() { - $articles = $this->connection->table('articles'); + $articles = $this->db->table('articles'); return new Nette\Application\UI\Multiplier(function (int $articleId) use ($articles) { return new LikeControl($articles[$articleId]); }); diff --git a/best-practices/uk/post-links.texy b/best-practices/uk/post-links.texy new file mode 100644 index 0000000000..b0e7213fc5 --- /dev/null +++ b/best-practices/uk/post-links.texy @@ -0,0 +1,59 @@ +Як правильно використовувати POST-посилання +******************************************* + +У веб-додатках, особливо в адміністративних інтерфейсах, основним правилом має бути те, що дії, які змінюють стан сервера, не повинні виконуватися за допомогою методу HTTP GET. Як випливає з назви методу, GET слід використовувати тільки для отримання даних, а не для їх зміни. +Для таких дій, як видалення записів, доцільніше використовувати метод POST. Хоча ідеальним варіантом було б використання методу DELETE, але його неможливо викликати без JavaScript, тому історично використовується POST. + +Як це зробити на практиці? Використовуйте цей простий трюк. На початку вашого шаблону створіть допоміжну форму з ідентифікатором `postForm`, яку ви потім будете використовувати для кнопок видалення: + +```latte .{file:@layout.latte} +
+``` + +У цій формі ви можете використовувати `