diff --git a/014-docs.md b/014-docs.md index be7c5634..53bfd775 100644 --- a/014-docs.md +++ b/014-docs.md @@ -25,26 +25,37 @@ The guide should follow [Micosoft style guide](https://learn.microsoft.com/en-us ## Blocks -Blocks use the Markdown `> Type: `. There are four block types: +Blocks are in the [GitHub Alerts format](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts): -* `Warning`, for bad security things and other problems -* `Note`, to emphasize key concepts, things to avoid -* `Info`, general information (an aside); not as strong as a "Note" -* `Tip`, pro tips, extras. It can be useful but may not be needed by everyone all the time +``` +> [!NOTE] +> Useful information that users should know, even when skimming content. + +> [!TIP] +> Helpful advice for doing things better or more easily. + +> [!IMPORTANT] +> Key information users need to know to achieve their goal. -The sentence after the colon should begin with a capital letter. +> [!WARNING] +> Urgent info that needs immediate user attention to avoid problems. + +> [!CAUTION] +> Advises about risks or negative outcomes of certain actions. +``` When translating documentation, these Block indicators should not be translated. Keeps them intact as they are and only translate the block content. -For translating the `Type` word, each guide translation should have a `blocktypes.json` file +For translating the label for the block, each guide translation should have a `blocktypes.json` file containing the translations. The following shows an example for German: ```json { - "Warning:": "Achtung:", - "Note:": "Hinweis:", - "Info:": "Info:", - "Tip:": "Tipp:" + "Note": "Hinweis", + "Tip": "Tipp", + "Important": "Wichtig", + "Warning": "Achtung", + "Caution": "Vorsicht" } ``` diff --git a/015-phpstorm.md b/015-phpstorm.md index 11b63c36..02ed582c 100644 --- a/015-phpstorm.md +++ b/015-phpstorm.md @@ -12,7 +12,8 @@ We use the following set of coding styles for metadata. - Metadata should be placed in `/.phpstorm.meta.php` directory. - Configuration should be split into files. Each file should be named after a class it configures. -> Note: There is no support for subdirectories in PhpStorm yet. +> [!NOTE] +> There is no support for subdirectories in PhpStorm yet. ### Constants diff --git a/cookbook/en/README.md b/cookbook/en/README.md index 6e50ac36..ad1d539c 100644 --- a/cookbook/en/README.md +++ b/cookbook/en/README.md @@ -15,3 +15,4 @@ This book conforms to the [Terms of Yii Documentation](https://www.yiiframework. - [Preface](preface.md) - [Structuring code by use-case with vertical slices](organizing-code/structuring-by-use-case-with-vertical-slices.md) - [Sentry integration](sentry-integration.md) +- [Configuring webservers](configuring-webservers/general.md) diff --git a/cookbook/en/configuring-webservers/apache.md b/cookbook/en/configuring-webservers/apache.md new file mode 100644 index 00000000..dc74d110 --- /dev/null +++ b/cookbook/en/configuring-webservers/apache.md @@ -0,0 +1,46 @@ +# Configuring web servers: Apache + +Use the following configuration in Apache's `httpd.conf` file or within a virtual host configuration. Note that you +should replace `path/to/app/public` with the actual path for `app/public`. + +```apacheconfig +# Set document root to be "app/public" +DocumentRoot "path/to/app/public" + + + # use mod_rewrite for pretty URL support + RewriteEngine on + + # if $showScriptName is false in UrlManager, do not allow accessing URLs with script name + RewriteRule ^index.php/ - [L,R=404] + + # If a directory or a file exists, use the request directly + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + + # Otherwise forward the request to index.php + RewriteRule . index.php + + # ...other settings... + +``` + +In case you have `AllowOverride All` you can add `.htaccess` file with the following configuration instead of +using `httpd.conf`: + +```apacheconfig +# use mod_rewrite for pretty URL support +RewriteEngine on + +# if $showScriptName is false in UrlManager, do not allow accessing URLs with script name +RewriteRule ^index.php/ - [L,R=404] + +# If a directory or a file exists, use the request directly +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d + +# Otherwise forward the request to index.php +RewriteRule . index.php + +# ...other settings... +``` diff --git a/cookbook/en/configuring-webservers/general.md b/cookbook/en/configuring-webservers/general.md new file mode 100644 index 00000000..f139b5de --- /dev/null +++ b/cookbook/en/configuring-webservers/general.md @@ -0,0 +1,16 @@ +# Configuring web servers: General + +On a production server, if you don't use Docker, configure your web server to serve only the application's public files. +Point the document root of your web server to the `app/public` folder. + +> [!IMPORTANT] +> If you're running your Yii application behind a reverse proxy, you might need to configure +> [Trusted proxies and headers](../../../guide/en/security/trusted-request.md). + +## Specific server configurations + +- [Nginx](nginx.md) +- [Apache](apache.md) +- [Lighttpd](lighttpd.md) +- [Nginx Unit](nginx-unit.md) +- [IIS](iis.md) diff --git a/cookbook/en/configuring-webservers/iis.md b/cookbook/en/configuring-webservers/iis.md new file mode 100644 index 00000000..63943389 --- /dev/null +++ b/cookbook/en/configuring-webservers/iis.md @@ -0,0 +1,34 @@ +# Configuring web servers: IIS + +When you use [IIS](https://www.iis.net/), host the application in a virtual host (Website) where the document +root points to the `path/to/app/public` folder and configure the website to run PHP. +In that `public` folder, place a file named `web.config` at `path/to/app/public/web.config`. +Use the following content: + +```xml + + + + + + + + + + + + + + + + + + +``` + +Also, the following list of Microsoft's official resources could be useful to configure PHP on IIS: + +1. [How to set up your first IIS website](https://support.microsoft.com/en-us/help/323972/how-to-set-up-your-first-iis-web-site) +2. [Configure a PHP Website on IIS](https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configure-a-php-website-on-iis) diff --git a/cookbook/en/configuring-webservers/lighttpd.md b/cookbook/en/configuring-webservers/lighttpd.md new file mode 100644 index 00000000..551300c6 --- /dev/null +++ b/cookbook/en/configuring-webservers/lighttpd.md @@ -0,0 +1,7 @@ +# Configuring web servers: lighttpd + +To use [lighttpd](https://www.lighttpd.net/) >= 1.4.24, put `index.php` in the web root and add the following to the configuration: + +``` +url.rewrite-if-not-file = ("(.*)" => "/index.php/$0") +``` diff --git a/cookbook/en/configuring-webservers/nginx-unit.md b/cookbook/en/configuring-webservers/nginx-unit.md new file mode 100644 index 00000000..11b7af8d --- /dev/null +++ b/cookbook/en/configuring-webservers/nginx-unit.md @@ -0,0 +1,60 @@ +# Configuring web servers: NGINX Unit + +Run Yii-based apps using [NGINX Unit](https://unit.nginx.org/) with a PHP language module. +Here is a sample configuration. + +```json +{ + "listeners": { + "*:80": { + "pass": "routes/yii" + } + }, + + "routes": { + "yii": [ + { + "match": { + "uri": [ + "!/assets/*", + "*.php", + "*.php/*" + ] + }, + + "action": { + "pass": "applications/yii/direct" + } + }, + { + "action": { + "share": "/path/to/app/public/", + "fallback": { + "pass": "applications/yii/index" + } + } + } + ] + }, + + "applications": { + "yii": { + "type": "php", + "user": "www-data", + "targets": { + "direct": { + "root": "/path/to/app/public/" + }, + + "index": { + "root": "/path/to/app/public/", + "script": "index.php" + } + } + } + } +} +``` + +You can also [set up](https://unit.nginx.org/configuration/#php) your PHP environment or supply a custom `php.ini` +in the same configuration. diff --git a/cookbook/en/configuring-webservers/nginx.md b/cookbook/en/configuring-webservers/nginx.md new file mode 100644 index 00000000..fea28339 --- /dev/null +++ b/cookbook/en/configuring-webservers/nginx.md @@ -0,0 +1,56 @@ +# Configuring web servers: Nginx + +To use [Nginx](https://wiki.nginx.org/), install PHP as an [FPM SAPI](https://secure.php.net/install.fpm). +Use the following Nginx configuration, replacing `path/to/app/public` with the actual path for +`app/public` and `mysite.test` with the actual hostname to serve. + +```nginx +server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name mysite.test; + root /path/to/app/public; + index index.php; + + access_log /path/to/basic/log/access.log; + error_log /path/to/basic/log/error.log; + + location / { + # Redirect everything that isn't a real file to index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # uncomment to avoid processing of calls to non-existing static files by Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + # deny accessing php files for the /assets directory + location ~ ^/assets/.*\.php$ { + deny all; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php8-fpm.sock; + try_files $uri =404; + } + + location ~* /\. { + deny all; + } +} +``` + +When you use this configuration, also set `cgi.fix_pathinfo=0` in the `php.ini` file +to avoid many unnecessary system `stat()` calls. + +Also, note that when running an HTTPS server, you need to add `fastcgi_param HTTPS on;` so that Yii +can detect if a connection is secure. diff --git a/cookbook/en/preface.md b/cookbook/en/preface.md index bf62ceb8..7aeff135 100644 --- a/cookbook/en/preface.md +++ b/cookbook/en/preface.md @@ -10,8 +10,7 @@ Because of its architecture and sophisticated caching support, it's especially suitable for developing large-scale applications such as portals, content management systems, e-commerce, REST APIs, etc. -Together with a comprehensive set of documentation and an enthusiastic user community, Yii can reduce your development -time in a long run significantly. +With comprehensive documentation and an enthusiastic user community, Yii can significantly reduce your development time in the long run. ## What's the book about diff --git a/guide/en/README.md b/guide/en/README.md index eef368ba..a97f3216 100644 --- a/guide/en/README.md +++ b/guide/en/README.md @@ -1,6 +1,6 @@ # The definitive guide to Yii 3.0 -This guide is released under the [Terms of Yii Documentation](https://www.yiiframework.com/license#docs). +We release this guide under the [Terms of Yii Documentation](https://www.yiiframework.com/license#docs). Introduction + ------------ diff --git a/guide/en/caching/data.md b/guide/en/caching/data.md index 77cf3788..dcd396c7 100644 --- a/guide/en/caching/data.md +++ b/guide/en/caching/data.md @@ -59,7 +59,8 @@ Yii provides the following handlers: [You could find more handlers at packagist.org](https://packagist.org/providers/psr/simple-cache-implementation). -> Tip: You may use different cache storage in the same application. A common strategy is: +> [!TIP] +> You may use different cache storage in the same application. A common strategy is: > - To use memory-based cache storage to store small but constantly used data (e.g., statistics) > - To use file-based or database-based cache storage to store big and less often used data (e.g., page content) diff --git a/guide/en/concept/aliases.md b/guide/en/concept/aliases.md index 8294b01e..7ae9e8d2 100644 --- a/guide/en/concept/aliases.md +++ b/guide/en/concept/aliases.md @@ -32,7 +32,8 @@ return [ ]; ``` -> Note: The file path or URL being aliased may *not* necessarily refer to an existing file or resource. +> [!NOTE] +> The file path or URL being aliased may *not* necessarily refer to an existing file or resource. Given a defined alias, you may derive a new alias by appending a slash `/` followed with one or more path segments. For example, `@foo` is a root alias, while `@foo/bar/file.php` is a derived alias. @@ -94,7 +95,8 @@ public function actionIndex(Aliases $aliases) The path/URL represented by a derived alias is determined by replacing the root alias part with its corresponding path/URL in the derived alias. -> Note: The `get()` method doesn't check whether the resulting path/URL refers to an existing file or resource. +> [!NOTE] +> The `get()` method doesn't check whether the resulting path/URL refers to an existing file or resource. A root alias may also contain slash `/` characters. The `get()` method diff --git a/guide/en/concept/configuration.md b/guide/en/concept/configuration.md index 1a6c1e35..b5307feb 100644 --- a/guide/en/concept/configuration.md +++ b/guide/en/concept/configuration.md @@ -266,7 +266,8 @@ Read more about it in ["Events"](events.md). Parameters, `config/params.php` store configuration values that are used in other config files to configuring services and service providers. -> Tip: Don't use parameters, constants or environment variables directly in your application, configure +> [!TIP] +> Don't use parameters, constants or environment variables directly in your application, configure > services instead. Default application `params.php` looks like the following: diff --git a/guide/en/runtime/logging.md b/guide/en/runtime/logging.md index 8c915588..90b60b9a 100644 --- a/guide/en/runtime/logging.md +++ b/guide/en/runtime/logging.md @@ -81,7 +81,8 @@ the constant appears. For example, it's equal to the string `'App\\Service\\MyService::serve'` if the above line of code is called within this method. -> Info: The logging methods described above are actually shortcuts to the [[\Psr\Log\LoggerInterface::log()]]. +> [!IMPORTANT] +> The logging methods described above are actually shortcuts to the [[\Psr\Log\LoggerInterface::log()]]. Note that PSR-3 package provides `\Psr\Log\NullLogger` class that provides the same set of methods but doesn't log anything. That means that you don't have to check if logger is configured with `if ($logger !== null)` and, instead, @@ -267,7 +268,8 @@ $logger = new \Yiisoft\Log\Logger($targets); $logger->setExcludedTracePaths(['/path/to/file', '/path/to/folder']); ``` -> Info: Getting call stack information isn't trivial. Therefore, you should only use this feature during development +> [!IMPORTANT] +> Getting call stack information isn't trivial. Therefore, you should only use this feature during development or when debugging an application. @@ -284,7 +286,8 @@ $logger = new \Yiisoft\Log\Logger($targets); $logger->setFlushInterval(100); // default is 1000 ``` -> Info: Message flushing also occurs when the application ends, +> [!IMPORTANT] +> Message flushing also occurs when the application ends, which ensures log targets can receive complete log messages. When the [[\Yiisoft\Log\Logger|logger object]] flushes log messages to [log targets](#log-targets), @@ -311,7 +314,8 @@ $logger = new \Yiisoft\Log\Logger([$fileTarget]); $logger->setFlushInterval(1); ``` -> Note: Frequent message flushing and exporting will degrade the performance of your application. +> [!NOTE] +> Frequent message flushing and exporting will degrade the performance of your application. ### Toggling log targets @@ -350,7 +354,8 @@ The following protected methods will also be available for child targets: For more details, you may refer to any of the log target classes included in the package. -> Tip: Instead of creating your own loggers, you may try any PSR-3 compatible logger such +> [!TIP] +> Instead of creating your own loggers, you may try any PSR-3 compatible logger such as [Monolog](https://github.com/Seldaek/monolog) by using [[\Yii\Log\PsrTarget]]. ```php diff --git a/guide/en/runtime/routing.md b/guide/en/runtime/routing.md index 47bf8ba3..34dffb47 100644 --- a/guide/en/runtime/routing.md +++ b/guide/en/runtime/routing.md @@ -261,7 +261,8 @@ of `{ParamName:RegExp}`, where `ParamName` specifies the parameter name and `Reg expression used to match parameter values. If `RegExp` isn't specified, it means the parameter value should be a string without any slash. -> Note: You can only use regular expressions inside parameters. The rest of the pattern is considered plain text. +> [!NOTE] +> You can only use regular expressions inside parameters. The rest of the pattern is considered plain text. You can't use capturing groups. For example `{lang:(en|de)}` isn't a valid placeholder, because `()` is a capturing group. Instead, you can use either `{lang:en|de}` or `{lang:(?:en|de)}`. diff --git a/guide/en/runtime/sessions.md b/guide/en/runtime/sessions.md index 7b83c03b..351ef0c1 100644 --- a/guide/en/runtime/sessions.md +++ b/guide/en/runtime/sessions.md @@ -72,7 +72,8 @@ public function actionProfile(\Yiisoft\Session\SessionInterface $session) } ``` -> Note: Closing session as early as possible is a good practice since many session implementations are blocking other +> [!NOTE] +> Closing session as early as possible is a good practice since many session implementations are blocking other > requests while the session is open. There are two more ways to close a session: diff --git a/guide/en/start/creating-project.md b/guide/en/start/creating-project.md index 41f12df2..5d2cc31f 100644 --- a/guide/en/start/creating-project.md +++ b/guide/en/start/creating-project.md @@ -1,319 +1,50 @@ # Creating a project -You can create a Yii project using the [Composer](https://getcomposer.org) package manager. +In this guide we'll provide commands for both [Docker](https://docs.docker.com/get-started/get-docker/) and +the built-in dev server with everything installed locally. -We recommend starting with a project template that's a minimal working Yii project implementing some basic features. -Its code is organized in a recommended way. Therefore, it can serve as a good starting point for your projects. - -## Installing composer - -If you don't already have a Composer installed, you may do so by following the instructions at -[getcomposer.org](https://getcomposer.org/download/). On Linux and Mac OS X, you'll run the following commands: - -```bash -curl -sS https://getcomposer.org/installer | php -sudo mv composer.phar /usr/local/bin/composer -``` - -On Windows, you'll download and run [Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe). - -Please refer to the [Troubleshooting section of the Composer's Documentation](https://getcomposer.org/doc/articles/troubleshooting.md) -if you meet any problems. -If you're new to Composer, we also recommend reading at least the [Basic usage section](https://getcomposer.org/doc/01-basic-usage.md) -of the Composer's documentation. - -In this guide, all composer commands assume you've installed composer [globally](https://getcomposer.org/doc/00-intro.md#globally) -so that it's available as the `composer` command. If you're using the `composer.phar` in the local directory instead, -you have to adjust the example commands accordingly. - -If you had Composer already installed before, make sure you use an up-to-date version. You can update Composer -by running `composer self-update`. +> [!NOTE] +> If you want to use another web server, +> see ["Configuring web servers"](../../../cookbook/en/configuring-webservers/general.md). -## Creating a project +We recommend starting with a project template that's a minimal working Yii project implementing some basic features. +It can serve as a good starting point for your projects. -With Composer installed, you can create a Yii project from a template by running the following command -under a Web-accessible folder: +You can create a new project from a template using the [Composer](https://getcomposer.org) package manager: -```bash -composer create-project yiisoft/app --stability=dev your_project ``` - -This will install the latest version of Yii project template in a directory named `your_project`. -You can choose a different directory name if you want. - - - -## Using individual packages - -You could use many Yii packages separately from the framework via Composer. -Framework-specific ones have `yii-` prefix in their name. - -## Verifying the Installation - -After you finish installation, either configure your web server (see the next section) or use the -[built-in PHP web server](https://secure.php.net/manual/en/features.commandline.webserver.php) by running the following -console command while in the project root directory: - -```bash -./yii serve +composer create-project yiisoft/app your_project ``` -> Note: By default, the HTTP server will listen to port 8080. However, if that port is already in use, or you wish to -serve many applications this way, you might want to specify what port to use via the --port argument: +Docker users can run the following command: -```bash -./yii serve --port=8888 +```sh +docker run --rm -it -v "$(pwd):/app" composer/composer create-project yiisoft/app your_project ``` -You can use your browser to access the installed Yii application with the following URL: - -``` -http://localhost:8080/ -``` - -![Successful Installation of Yii](img/app-installed.png) - -You should see the page in your browser. If not, please check if your PHP installation satisfies -Yii's requirements by using [yiisoft/requirements package](https://github.com/yiisoft/requirements). - - -## Configuring web servers - -> Info: You may skip this subsection for now if you're just test-driving Yii with no intention - of deploying it to a production server. - -The application installed according to the instructions should work out of the box with either -an [Apache HTTP server](https://httpd.apache.org/) or a [Nginx HTTP server](https://nginx.org/), on -Windows, Mac OS X, or Linux running PHP 8.1 or higher. - -On a production server, we recommend configuring your Web server so that a user can access the application -via the URL `http://www.example.com/index.php` instead of `http://www.example.com/app/public/index.php`. -Such a configuration requires pointing the document root of your Web server to the `app/public` folder. -In this subsection, you'll learn how to configure your webserver to achieve it. - -> Info: By setting `app/public` as the document root, you also prevent end users from accessing -> your private application code and sensitive data files that are stored in the sibling directories -> of `app/public`. Denying access to those other folders is a security improvement. - -> Info: If your application runs in a shared hosting environment where you don't have permission -> to change its Web server configuration, you may still adjust the structure of your application for better security. -> Please refer to the [Shared Hosting Environment](tutorial-shared-hosting.md) section for more details. - -> Info: If you're running your Yii application behind a reverse proxy, you might need to configure -> [Trusted proxies and headers](../security/trusted-request.md). - -### Apache - -Use the following configuration in Apache's `httpd.conf` file or within a virtual host configuration. Note that you -should replace `path/to/app/public` with the actual path for `app/public`. - -```apacheconfig -# Set document root to be "app/public" -DocumentRoot "path/to/app/public" - - - # use mod_rewrite for pretty URL support - RewriteEngine on - - # if $showScriptName is false in UrlManager, do not allow accessing URLs with script name - RewriteRule ^index.php/ - [L,R=404] - - # If a directory or a file exists, use the request directly - RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d - - # Otherwise forward the request to index.php - RewriteRule . index.php - - # ...other settings... - -``` - -In case you have `AllowOverride All` you can add `.htaccess` file with the following configuration instead of -using `httpd.conf`: - -```apacheconfig -# use mod_rewrite for pretty URL support -RewriteEngine on - -# if $showScriptName is false in UrlManager, do not allow accessing URLs with script name -RewriteRule ^index.php/ - [L,R=404] - -# If a directory or a file exists, use the request directly -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d - -# Otherwise forward the request to index.php -RewriteRule . index.php - -# ...other settings... -``` - -### Nginx - -To use [Nginx](https://wiki.nginx.org/), you should install PHP as an [FPM SAPI](https://secure.php.net/install.fpm). -You may use the following Nginx configuration, replacing `path/to/app/public` with the actual path for -`app/public` and `mysite.test` with the actual hostname to serve. - -```nginx -server { - charset utf-8; - client_max_body_size 128M; - - listen 80; ## listen for ipv4 - #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 - - server_name mysite.test; - root /path/to/app/public; - index index.php; - - access_log /path/to/basic/log/access.log; - error_log /path/to/basic/log/error.log; - - location / { - # Redirect everything that isn't a real file to index.php - try_files $uri $uri/ /index.php$is_args$args; - } - - # uncomment to avoid processing of calls to non-existing static files by Yii - #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { - # try_files $uri =404; - #} - #error_page 404 /404.html; +This installs the latest stable version of the Yii project template in a directory named `your_project`. +You can choose a different directory name if you want. - # deny accessing php files for the /assets directory - location ~ ^/assets/.*\.php$ { - deny all; - } +> [!TIP] +> If you want to install the latest development version of Yii, you may add `--stability=dev` to the command. +> Don't use the development version of Yii for production because it may break your running code. - location ~ \.php$ { - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_pass 127.0.0.1:9000; - #fastcgi_pass unix:/var/run/php5-fpm.sock; - try_files $uri =404; - } +Go into the newly created directory and run: - location ~* /\. { - deny all; - } -} +```sh +APP_ENV=dev ./yii serve --port=80 ``` -When using this configuration, you should also set `cgi.fix_pathinfo=0` in the `php.ini` file -to avoid many unnecessary system `stat()` calls. - -Also, note that when running an HTTPS server, you need to add `fastcgi_param HTTPS on;` so that Yii -can detect if a connection is secure. - -### NGINX Unit - -You can run Yii-based apps using [NGINX Unit](https://unit.nginx.org/) with a PHP language module. -Here is a sample configuration. - -```json -{ - "listeners": { - "*:80": { - "pass": "routes/yii" - } - }, +For Docker users, run: - "routes": { - "yii": [ - { - "match": { - "uri": [ - "!/assets/*", - "*.php", - "*.php/*" - ] - }, - - "action": { - "pass": "applications/yii/direct" - } - }, - { - "action": { - "share": "/path/to/app/public/", - "fallback": { - "pass": "applications/yii/index" - } - } - } - ] - }, - - "applications": { - "yii": { - "type": "php", - "user": "www-data", - "targets": { - "direct": { - "root": "/path/to/app/public/" - }, - - "index": { - "root": "/path/to/app/public/", - "script": "index.php" - } - } - } - } -} ``` - -You can also [set up](https://unit.nginx.org/configuration/#php) your PHP environment or supply a custom `php.ini` -in the same configuration. - -### IIS - -When using [IIS](https://www.iis.net/), we recommend hosting the application in a virtual host (Website) where document -root points to `path/to/app/web` folder and that website is configured to run PHP. In that `web` folder you have to -place a file named `web.config` that's `path/to/app/web/web.config`. The Content of the file should be the following: - -```xml - - - - - - - - - - - - - - - - - - +make up ``` -Also, the following list of Microsoft's official resources could be useful to configure PHP on IIS: - - 1. [How to set up your first IIS website](https://support.microsoft.com/en-us/help/323972/how-to-set-up-your-first-iis-web-site) - 2. [Configure a PHP Website on IIS](https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configure-a-php-website-on-iis) +Open your browser to the URL `http://localhost/`. -### lighttpd +> [!NOTE] +> The HTTP server listens on port 80. If that port is already in use, specify the port via `--port` or, in case of Docker, +> `DEV_PORT` in the `docker/.env` file. -To use [lighttpd](https://www.lighttpd.net/) >= 1.4.24 put `index.php` to webroot and add the following to configuration: - -``` -url.rewrite-if-not-file = ("(.*)" => "/index.php/$0") -``` +![Successful Installation of Yii](img/app-installed.png) diff --git a/guide/en/start/databases.md b/guide/en/start/databases.md index c6a573fe..f0b84bbd 100644 --- a/guide/en/start/databases.md +++ b/guide/en/start/databases.md @@ -3,9 +3,10 @@ Yii doesn't dictate using a particular database or storage for your application. There are many ways you can work with relational databases: -- [Yii Database](https://github.com/yiisoft/db) -- [Doctrine](https://www.doctrine-project.org/) via [Yii Doctrine package](https://github.com/stargazer-team/yii-doctrine) +- [Yii DB](https://github.com/yiisoft/db) +- [Yii Active Record](https://github.com/yiisoft/active-record) - [Cycle](https://github.com/cycle) via [Yii Cycle package](https://github.com/yiisoft/yii-cycle) +- [Doctrine](https://www.doctrine-project.org/) via [Yii Doctrine package](https://github.com/stargazer-team/yii-doctrine) - [PDO](https://www.php.net/manual/en/book.pdo.php) For non-relational ones, there are usually official libraries available: @@ -13,3 +14,17 @@ For non-relational ones, there are usually official libraries available: - [ElasticSearch](https://github.com/elastic/elasticsearch-php) - [Redis](https://redis.io/docs/clients/#php) - ... + +In this guide, we will focus on working with relational databases using Yii DB. + +## Configuring connection + +## Creating and applying migration + +## Inserting + +## Selecting + +## Using data package + +### Pagination diff --git a/guide/en/start/forms.md b/guide/en/start/forms.md index 99863c24..56363787 100644 --- a/guide/en/start/forms.md +++ b/guide/en/start/forms.md @@ -13,342 +13,180 @@ Through this tutorial, you will learn how to: To install form package, issue the following command in your application directory: ``` -composer require yiisoft/form +composer require yiisoft/form-model +``` + +For Docker that would be: + +``` +make composer require yiisoft/form-model ``` ## Creating a form -The data to be requested from the user will be represented by an `EchoForm` class as shown below and -saved in the file `/src/Form/EchoForm.php`: +The data to be requested from the user will be represented by a `Form` class as shown below and +saved in the file `/src/App/Controller/Echo/Form.php`: ```php message; - } + #[Label('The message to be echoed')] + #[Length(min: 2)] + public string $message = ''; } ``` -To inherit from `FormModel` you need to install `form-model` by following commands: - -``` -composer require yiisoft/form-model -``` - -The `EchoForm` class has `$message` property and related getter. +In the above example, the `Form` has a single string property `$message` which length should be at least +of two characters. There's also a custom label for the property. ## Using the form Now that you have a form, use it in your action from "[Saying Hello](hello.md)". -You also need to install a hydrator package - -``` -composer require yiisoft/hydrator -``` - -Here's what you end up with in `/src/Controller/EchoController.php`: +Here's what you end up with in `/src/Controller/Echo/Action.php`: ```php viewRenderer = $viewRenderer->withControllerName('echo'); - } + private ViewRenderer $viewRenderer, + private FormHydrator $formHydrator, + ) {} - public function say(ServerRequestInterface $request): ResponseInterface + public function __invoke(ServerRequestInterface $request): ResponseInterface { - $form = new EchoForm(); - $hydrator = new Hydrator(); - - if ($request->getMethod() === Method::POST) { - $hydrator->hydrate($form, $request->getParsedBody()['EchoForm']); - } - - return $this->viewRenderer->render('say', [ + $form = new Form(); + + $this->formHydrator->populateFromPostAndValidate($form, $request); + + return $this->viewRenderer->render(__DIR__ . '/template', [ 'form' => $form, ]); } } ``` -Instead of reading from request directly, you fill your form with the help of `Yiisoft\Hydrator\Hydrator::hydrate()` method if the request -method is POST and then pass it to your view. +Instead of reading from route, you fill your form from request's POST data and validate it with +the help of `FormHydrator`. Next you pass the form to the view. -Now, to allow POST, you need to adjust your route in `config/routes.php`: +For the form to function we need to allow both GET to render the form and POST to send the data. +Adjust your route in `config/common/routes.php`: ```php action([SiteController::class, 'index'])->name('home'), - Route::methods([Method::GET, Method::POST], '/say[/{message}]')->action([EchoController::class, 'say'])->name('echo/say'), + Group::create() + ->routes( + Route::get('/') + ->action(\App\Controller\HomePage\Action::class) + ->name('home'), + Route::methods([Method::GET, Method::POST], '/say') + ->action(\App\Controller\Echo\Action::class) + ->name('echo/say'), + ), ]; ``` ## Adjusting view -To render a form, you need to change your view, `resources/views/echo/say.php`: +To render a form, you need to change your view, `src/Controller/Echo/template.php`: ```php - +/** + * @var Form $form + * @var string[] $errors + * @var UrlGeneratorInterface $urlGenerator + * @var Csrf $csrf + */ -getMessage())): ?> -
- The message is: getMessage()) ?> -
- - -post($urlGenerator->generate('echo/say')) - ->csrf($csrf) - ->open() ?> - -name('EchoForm[message]') - ->value($form->getMessage()) - ->label('Message') - ->placeholder('Type your message') - ->inputId('echoform-message'); ?> + ->csrf($csrf); +?> - +open() ?> + required() ?> + +close() ?> -close() ?> +isValid()): ?> + Echo said: message) ?> + ``` -If a form has a message set, you're displaying a box with the message. The rest is about rendering the form. +If the form is valid, you display a message. The rest initializes and renders the form. -You get the action URL from the URL manager service. -You access it as `$urlGenerator` that's a default parameter available in all views. -This variable and similar ones such as `$csrf` are provided by view injections listed in `config/common/params.php`: +First, you initialize `$htmlForm` with the POST type and the action URL generated with the help from the URL generator. +You can access it as `$urlGenerator` in all views. You also need to pass the CSRF token to the form, which is also +available in every view as `$csrf` thanks to the view injections listed in `config/common/params.php`: ```php 'yiisoft/yii-view-renderer' => [ 'injections' => [ - Reference::to(CommonViewInjection::class), Reference::to(CsrfViewInjection::class), - Reference::to(LayoutViewInjection::class), - Reference::to(TranslatorViewInjection::class), ], ], ``` -You set the value of a CSRF token, and it is rendered as a hidden input to ensure that the request originates from +The template renders the CSRF token value as a hidden input to ensure that the request originates from the form page and not from another website. It will be submitted along with POST form data. Omitting it would result in [HTTP response code 422](https://tools.ietf.org/html/rfc4918#section-11.2). -CSRF protection is enabled by default. To turn off the CSRF protection, -you need to remove using `CsrfMiddleware` or `CsrfTokenMiddleware` to `config/common/di/router.php`: - -```php - static function (RouteCollectorInterface $collector) use ($config) { - $collector - ->middleware(CsrfMiddleware::class) // <-- here - ->middleware(FormatDataResponse::class) - ->addGroup( - Group::create() - ->routes(...$config->get('routes')) - ); - - return new RouteCollection($collector); - }, -]; - - // ... -``` - -You use `Text::widget()` to output "message" field, so it takes care about filling the value, escaping it, -rendering field label and validation errors you're going to take care of next. - -## Adding validation - -Right now it's possible to submit an empty value. Make it required. Modify `/src/Controller/EchoController.php`: - -```php -viewRenderer = $viewRenderer->withControllerName('echo'); - } - - public function say(ServerRequestInterface $request, Validator $validator): ResponseInterface - { - $form = new EchoForm(); - $hydrator = new Hydrator(); - $errors = null; - - if ($request->getMethod() === Method::POST) { - $hydrator->hydrate($form, $request->getParsedBody()[$form->getFormName()]); - $result = $validator->validate($form); - if (!$result->isValid()) { - $errors = $result->getErrors(); - } - } - - return $this->viewRenderer->render('say', [ - 'form' => $form, - 'errors' => $errors, - ]); - } -} -``` - -You've got a validator instance through type-hinting and used it to validate the form. -Now you need to add validation rules to `/src/Form/EchoForm.php`: - -```php -message; - } -} -``` - -Now, in case you submit an empty message, you will get a validation error: "Message cannot be blank." -Also, you can add required attribute to text field in `views/echo/say.php`. - -```php - - - -getMessage())): ?> -
- The message is: getMessage()) ?> -
- - - -
- getMessage()) ?> -
- - - -post($urlGenerator->generate('echo/say')) - ->csrf($csrf) - ->open() ?> - -name('EchoForm[message]') - ->value($form->getMessage()) - ->label('Message') - ->placeholder('Type your message') - ->required(true) // <-- here - ->inputId('echoform-message'); ?> - - - -close() ?> -``` +Now, in case you submit an empty message, you will get a validation error: "The message to be echoed must contain +at least 2 characters." ## Trying it Out - To see how it works, use your browser to access the following URL: ``` http://localhost:8080/say ``` -You will see a page displaying a form input field that has a label that indicates what data are to be entered. -Also, there is a "submit" button labeled "Say". If you click the "submit" button without entering anything, you will see -an error message displayed next to a problematic input field. +You will see a page with a form input field and a label that indicates what data to enter. +Also, the form has a "submit" button labeled "Say". If you click the "submit" button without entering anything, you will see +that the field is required. If you enter a single character, the form displays an error message next to +the problematic input field. ![Form with a validation error](img/form-error.png) -After entering a message and clicking the "submit" button, you will see a new page -displaying the data that you just entered. +After you enter a valid message and click the "submit" button, the page echoes the data that you entered. ![Form with a success message](img/form-success.png) diff --git a/guide/en/start/hello.md b/guide/en/start/hello.md index 16ea667b..cdb32256 100644 --- a/guide/en/start/hello.md +++ b/guide/en/start/hello.md @@ -1,7 +1,5 @@ # Saying hello -> Note: This document reflects the current configuration. The Yii team is going to simplify it before release. - This section describes how to create a new "Hello" page in your application. It's a simple page that will echo back whatever you pass to it or, if nothing passed, will just say "Hello!". @@ -15,38 +13,35 @@ Through this tutorial, you will learn three things: 2. How to map URL to the handler. 3. How to create a [view](../structure/view.md) to compose the response's content. -## Creating a Handler +## Creating a handler -For the "Hello" task, you will create a `EchoController` class with `say` method that reads +For the "Hello" task, you will create a handler class that reads a `message` parameter from the request and displays that message back to the user. If the request doesn't provide a `message` parameter, the action will display the default "Hello" message. -Create `src/Controller/EchoController.php`: +Create `src/Controller/Echo/Action.php`: ```php getArgument('message', 'Hello!'); - $response = $this->responseFactory->createResponse(); $response->getBody()->write('The message is: ' . Html::encode($message)); return $response; @@ -54,12 +49,12 @@ final readonly class EchoController } ``` -The `say` method in your example is given `$currentRoute` parameter that you can use to get -a message, whose value defaults to `"Hello"`. If the request is made to `/say/Goodbye`, -the `$message` variable within the action will be assigned that value. +In your example, the `__invoke` method receives the `$message` parameter that with the help of `RouteArgument` attribute +gets the message from URL. The value defaults to `"Hello!"`. If the request is made to `/say/Goodbye`, +the action assigns the value "Goodbye" to the `$message` variable. -The response returned goes through [middleware stack](../structure/middleware.md) into emitter that outputs response -to the end user. +The application passes the response through the [middleware stack](../structure/middleware.md) to the emitter that +outputs the response to the end user. ## Configuring router @@ -70,41 +65,43 @@ Now, to map your handler to URL, you need to add a route in `config/common/route declare(strict_types=1); -use App\Controller\EchoController; -use App\Controller\SiteController; +use Yiisoft\Router\Group; use Yiisoft\Router\Route; return [ - Route::get('/')->action([SiteController::class, 'index'])->name('home'), - Route::get('/say[/{message}]')->action([EchoController::class, 'say'])->name('echo/say'), + Group::create() + ->routes( + Route::get('/') + ->action(\App\Controller\HomePage\Action::class) + ->name('home'), + Route::get('/say[/{message}]') + ->action(\App\Controller\Echo\Action::class) + ->name('echo/say'), + ), ]; ``` -In the above you're mapping `/say[/{message}]` pattern to `EchoController::say()`. For a request its instance will -be created and `say()` method will be called. The pattern `{message}` part means that anything specified in this place -will be written to `message` request attribute. `[]` means that this part of the pattern is optional. +In the above, you map the `/say[/{message}]` pattern to `\App\Controller\Echo\Action`. +For a request, the router creates an instance and calls the `__invoke()` method. +The `{message}` part of the pattern writes anything specified in this place to the `message` request attribute. +`[]` marks this part of the pattern as optional. You also give a `echo/say` name to this route to be able to generate URLs pointing to it. ## Trying it out -After creating the action and the view, start a web server with `./yii serve` and follow the following URL: - -``` -http://localhost:8080/say/Hello+World -``` +After creating the action and the view open `http://localhost/say/Hello+World` in your browser. -This URL will result in a page displaying "The message is: Hello World". +This URL displays a page with "The message is: Hello World". -If you omit the `message` parameter in the URL, you would see the page display "The message is: Hello!". +If you omit the `message` parameter in the URL, the page displays "The message is: Hello!". ## Creating a View Template Usually, the task is more complicated than printing out "hello world" and involves rendering some complex -HTML. For this task, it's handy to use [views templates](../structure/view.md). They're scripts you -write to generate a response's body. +HTML. For this task, it's handy to use view templates. They're scripts you write to generate a response's body. -For the "Hello" task, create a `/resources/views/echo/say.php` view that prints the `message` parameter received +For the "Hello" task, create a `src/Controller/Echo/template.php` template that prints the `message` parameter received from the action method: ```php @@ -116,55 +113,50 @@ use Yiisoft\Html\Html;

The message is:

``` -Note that in the above code, the `message` parameter is HTML-encoded -before being printed. This is necessary as the parameter comes from an end user, making it vulnerable to +In the above code, the `message` parameter uses HTML encoding before you print it. You need that because the parameter comes from an end user and is vulnerable to [cross-site scripting (XSS) attacks](https://en.wikipedia.org/wiki/Cross-site_scripting) by embedding malicious JavaScript in the parameter. Naturally, you may put more content in the `say` view. The content can consist of HTML tags, plain text, and even -PHP statements. In fact, the `say` view is a PHP script executed by the view service. +PHP statements. In fact, the view service executes the `say` view as a PHP script. -To use the view, you need to change `src/Controller/EchoController.php`: +To use the view, you need to change `src/Controller/Echo/Action.php`: ```php viewRenderer = $viewRenderer->withControllerName('echo'); - } + private ViewRenderer $viewRenderer, + ) {} - public function say(CurrentRoute $route): ResponseInterface + #[RouteArgument('message')] + public function __invoke(string $message = 'Hello!'): ResponseInterface { - $message = $route->getArgument('message', 'Hello!'); - - return $this->viewRenderer->render('say', [ + return $this->viewRenderer->render(__DIR__ . '/template', [ 'message' => $message, ]); } } ``` -Now open your browser and check it again. It should give you a similar text but with a layout applied. +Now open your browser and check it again. You should see the similar text but with a layout applied. Also, you've separated the part about how it works and part of how it's presented. In the larger applications, it helps a lot to deal with complexity. ## Summary -In this section, you've touched the handler and view parts of the typical web application. +In this section, you've touched the handler and template parts of the typical web application. You created a handler as part of a class to handle a specific request. You also created a view to compose the response's content. In this simple example, no data source was involved as the only data used was the `message` parameter. diff --git a/guide/en/start/img/form-error.png b/guide/en/start/img/form-error.png index c1a05bc8..b2a9c333 100644 Binary files a/guide/en/start/img/form-error.png and b/guide/en/start/img/form-error.png differ diff --git a/guide/en/start/img/form-success.png b/guide/en/start/img/form-success.png index c6c09ce4..5c13dbb5 100644 Binary files a/guide/en/start/img/form-success.png and b/guide/en/start/img/form-success.png differ diff --git a/guide/en/start/looking-ahead.md b/guide/en/start/looking-ahead.md index 253cf8f2..941f32e1 100644 --- a/guide/en/start/looking-ahead.md +++ b/guide/en/start/looking-ahead.md @@ -4,36 +4,4 @@ If you've read through the entire "Getting Started" chapter, you have now create In the process, you've learned how to implement some commonly necessary features, such as getting data from users via an HTML form, fetching data from a database, and displaying data in a paginated fashion. You've also learned how to use [Gii](gii.md) to generate code automatically. Using Gii for code generation turns the bulk of your Web development -process into a task as simple as just filling out some forms. - -This section will summarize the Yii resources available to help you be more productive when using the framework. - -* Documentation - - [The Definitive Guide](../README.md): - As the name indicates, the guide precisely defines how Yii should work and provides general guidance - about using Yii. It's the single most important Yii tutorial, and one you should read - before writing any Yii code. - - The Class Reference (to be available later): - This specifies the usage of every class provided by Yii. It should be mainly used when you're writing - code and want to understand the usage of a particular class, method, property. Usage of the class reference - is the best only after a contextual understanding of the entire framework. - - [The Wiki Articles](https://www.yiiframework.com/wiki?version=all&tag=yii3): - The wiki articles are written by Yii users based on their own experiences. Most of them are written - like cookbook recipes, and show how to solve particular problems using Yii. While the quality of these - articles mayn't be as good as the Definitive Guide, they're useful in that they cover broader topics - and can often provide ready-to-use solutions. - - [Books](https://www.yiiframework.com/doc/) -* [Extensions](https://www.yiiframework.com/extensions/): - Yii boasts a library of thousands of user-contributed extensions that can be easily plugged into your applications, - thereby making your application development even faster and easier. -* Community - - Forum: - - IRC chat: The #yii channel on the freenode network () - - Slack channel: - - Gitter chat: - - GitHub: - - Facebook: - - Twitter: - - LinkedIn: - - Stackoverflow: - - Telegram: +process into a task as simple as just filling out some forms. diff --git a/guide/en/start/prerequisites.md b/guide/en/start/prerequisites.md index c8275646..0718b09f 100644 --- a/guide/en/start/prerequisites.md +++ b/guide/en/start/prerequisites.md @@ -9,10 +9,10 @@ Yii is a PHP framework, so make sure you [read and understand language reference ## Object-oriented programming -A basic understanding of object-oriented programming is required. If you're not familiar with it, check one of the many +You need a basic understanding of object-oriented programming. If you're not familiar with it, check one of the many tutorials available such as [the one from tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762). -When developing with Yii, you will be writing code in an object-oriented fashion, so make sure you're familiar with +When you develop with Yii, you write code in an object-oriented fashion, so make sure you're familiar with [PHP OOP support](https://www.php.net/manual/en/language.oop5.php). Note that the more complicated your application is, the more advanced OOP concepts you should learn to successfully @@ -26,5 +26,12 @@ the command line, it's time to start trying. Once you learn the basics, you'll n ## HTTP -Since Yii is a web framework and a major part of the web is using HTTP, it's a good idea to +Since Yii is a web framework and the web largely uses HTTP, it's a good idea to [learn more about it](https://developer.mozilla.org/en-US/docs/Web/HTTP). + +## Docker + +The default application template leverages Docker, +so we recommend that you [read and understand the concepts](https://docs.docker.com/get-started/). + +Also, you will benefit from familiarizing yourself with [twelve-factor app](https://12factor.net/) principles. diff --git a/guide/en/start/workflow.md b/guide/en/start/workflow.md index 1026851f..a19fd88b 100644 --- a/guide/en/start/workflow.md +++ b/guide/en/start/workflow.md @@ -1,20 +1,16 @@ # Running applications -After installing Yii, you have a working Yii application that can be launched via `./yii serve` and then -accessed via the URL `http://localhost:8080/`. This section will introduce the application's built-in functionality, +After installing Yii, you have a working Yii application. +This section introduces the application's built-in functionality, how the code is organized, and how the application handles requests in general. -> Info: For simplicity, throughout this "Getting Started" tutorial use the "serve" command. It shouldn't be used -> to serve the project in production. When setting up a real server, use `app/public` as the document root. - -Note that unlike the framework itself, after you install a project template, it's all yours. You're free to add or delete -code and overall change it as you need. - +Note that unlike the framework itself, after you install a project template, it's all yours. +You're free to add or delete code and overall change it as you need. ## Functionality -The application installed has only the homepage, displayed when you access the URL `http://localhost:8080/`. -It shares a common layout that could be reused on further pages. +The installed application has only the homepage, which displays when you access the URL `http://localhost/`. +It shares a common layout that you can reuse on further pages. -Additionally, to the web application, there is a console script accessible via `./yii`. -This script can be used to run background and maintenance tasks for the application, which are described -in the [Console Application Section](../tutorial/console-applications.md). +In addition to the web application, you can access a console script via `APP_ENV=dev ./yii` or, in case of Docker, `make yii`. +Use this script to run background and maintenance tasks for the application, which the +[Console Application Section](../tutorial/console-applications.md) describes. ## Application structure @@ -32,10 +28,13 @@ in the [Console Application Section](../tutorial/console-applications.md). The most important directories and files in your application are (assuming the application's root directory is `app`): ``` -config/ Configuration files. +assets/ Application assets to be published. +config/ Configuration. common/ Configs applied to both console and web. di/ DI container configuration. aliasess.php Aliases. + application.php Application configuration. + bootstrap.php Bootstrap configuration. params.php Various parameters used in DI configs. routes.php Application routes. console/ Configs applied to console. @@ -50,50 +49,58 @@ config/ Configuration files. prod/ Configs applied in prod environment. params.php Various parameters used in DI configs. test/ Configs applied in test environment. - params.php Various parameters used in DI configs. - events.php Event handlers for both console and web. - events-console.php Event handlers for console. - events-web.php Event handlers for web. - params.php Parameters that are passed to configs. - providers.php Service providers for both console and web. - providers-console.php Service providers for console. - providers-web.php Service providers for web. - routes.php Defines how URLs are mapped to their handlers. -docs/ Documentation. + params.php Various parameters used in DI configs. + configuration.php Defines how to read application configs. + .merge-plan.php Merge plan to assemble configs according to. Build using `configuration.php`. +docker/ Docker configuration. + dev/ Dev environment. + .env Environment variables. + compose.yml Services for dev environment. + prod/ Prod environment. + .env Environment variables. + compose.yml Services for prod environment. + test/ Test environment. + .env Environment variables. + compose.yml Services for test environment. + .env Common environment variables. + compose.yml Common services. + Dockerfile Images to use. public/ Files publically accessible from the Internet. assets/ Published assets. - index.php Entry script. -resources/ Application resources. - assets/ Asset bundle resources. - message/ Message translations. - views/ View templates. - layout/ View layouts. + index.php Entry script for web. runtime/ Files generated during runtime. src/ Application source code. - Asset/ Asset bundle definitions. Command/ Console commands. - Controller/ Web controller classes. + Controller/ Controllers. Handler/ Custom handler for 404. - ViewInjection/ Injections that bring additional variables into view templates. - Installer.php Additional actions done on Composer commands. -tests/ A set of Codeception tests for the application. + Layout/ Layouts. + autoload.php Autoloader. + Environment.php Environment helper. +tests/ A set of Codeception tests for the application. vendor/ Installed Composer packages. -configuration.php Defines how to read application configs. +.gitignore Files and directories to be ignored by Git. +.php-cs-fixer.php PHP Coding Standards Fixer configuration. +c3.php Codeception code coverage script. +condeception.yml Codeception configuration. +composer.json Composer configuration. +composer.lock Composer lock file. +Makefile Makefile with shortcut commands. +psalm.xml Psalm configuration. +rector.php Rector configuration. yii Console application entry point. ``` -In general, the files in the application can be divided into two types: those under `app/public` and those -under other directories. The former can be directly accessed via HTTP (i.e., in a browser), while the latter can't -and shouldn't be. +In general, the files in the application fall into two groups: those under `app/public` and those +under other directories. You can access the former directly via HTTP (i.e., in a browser), while you shouldn't expose the latter. -Each application has an entry script `public/index.php` which is the only Web accessible PHP script in the application. -The entry script is using an [application runner](https://github.com/yiisoft/yii-runner) to create an instance of -an incoming request with the help of one of PSR-7 packages and passes it to [an application](../structure/application.md) -instance. An application contains a set of middleware that is executed sequentially processing the request. -The result is passed further to the emitter that takes care of sending a response to the browser. +Each application has an entry script `public/index.php`, the only web-accessible PHP script in the application. +The entry script uses an [application runner](https://github.com/yiisoft/yii-runner) to create an instance of +an incoming request with the help of one of PSR-7 packages and passes it to an [application](../structure/application.md) +instance. The application executes a set of middleware sequentially to process the request. +It then passes the result to the emitter, which sends the response to the browser. -Depending on the middleware used, the application may behave differently. By default, there is a router -that, based on URL requested and configuration, chooses a handler that's executed to produce a response. +Depending on the middleware you use, the application may behave differently. By default, a router +uses the requested URL and configuration to choose a handler and execute it to produce a response. You can learn more about the application template from the [yiisoft/app package documentation](https://github.com/yiisoft/app/blob/master/README.md). diff --git a/guide/en/structure/domain.md b/guide/en/structure/domain.md index 56580b15..a751005d 100644 --- a/guide/en/structure/domain.md +++ b/guide/en/structure/domain.md @@ -5,7 +5,8 @@ in mind (the problem context), you build an abstraction that consists of entitie operates these entities. To focus on the complex part of the problem, domain is, ideally, separated from the infrastructure part of the system (that's how to save data into a database, how to form HTTP response, etc.). -> Note: Such isolation is suitable for complex systems. If your project domain is basically create/read/update/delete +> [!NOTE] +> Such isolation is suitable for complex systems. If your project domain is basically create/read/update/delete > for a set of records with not much complex logic, it makes no sense to apply a complex solution to a simple problem. > The individual concepts of domain design below could be applied separately, so make sure to check these even if your > project isn't that complicated. diff --git a/guide/en/structure/package.md b/guide/en/structure/package.md index 29f889aa..2089c684 100644 --- a/guide/en/structure/package.md +++ b/guide/en/structure/package.md @@ -14,7 +14,8 @@ to use it. This is useful if you're developing private packages that you want to Packages installed by Composer are stored in the `vendor` directory of your project. Because the Composer is a dependency manager, when it installs a package, it will also install all its dependent packages. -> Warning: `vendor` directory of your application should never be modified. +> [!WARNING] +> `vendor` directory of your application should never be modified. A package could be installed with the following command: @@ -130,7 +131,8 @@ Each Composer package should have a package name which uniquely identifies the p The format of package names is `vendorName/projectName`. For example, in the package name `yiisoft/queue`, the vendor name, and the project name are `yiisoft` and `queue`, respectively. -> Warning: Don't use `yiisoft` as your vendor name as it's reserved for use by the Yii itself. +> [!WARNING] +> Don't use `yiisoft` as your vendor name as it's reserved for use by the Yii itself. We recommend you prefix `yii-` to the project name for packages that aren't able to work as general PHP packages and require Yii application. This will allow users to more easily tell whether a package is Yii specific. diff --git a/guide/es/runtime/logging.md b/guide/es/runtime/logging.md index 59e80d75..9b8fdd85 100644 --- a/guide/es/runtime/logging.md +++ b/guide/es/runtime/logging.md @@ -75,7 +75,8 @@ The `__METHOD__` constant evaluates as the name of the method (prefixed with the the constant appears. For example, it is equal to the string `'App\\Service\\MyService::serve'` if the above line of code is called within this method. -> Info: The logging methods described above are actually shortcuts to the [[\Psr\Log\LoggerInterface::log()]]. +> [!IMPORTANT] +> The logging methods described above are actually shortcuts to the [[\Psr\Log\LoggerInterface::log()]]. Note that PSR-3 package provides `\Psr\Log\NullLogger` class that provides the same set of methods but does not log anything. That means that you don't have to check if logger is configured with `if ($logger !== null)` and, instead, @@ -211,7 +212,8 @@ $logger->setTraceLevel(3); The above application configuration sets trace level to be 3 so each log message will be appended with at most 3 levels of the call stack at which the log message is recorded. -> Info: Getting call stack information is not trivial. Therefore, you should only use this feature during development +> [!IMPORTANT] +> Getting call stack information is not trivial. Therefore, you should only use this feature during development or when debugging an application. @@ -228,7 +230,8 @@ $logger = new \Yiisoft\Log\Logger($targets); $logger->setFlushInterval(100); // default is 1000 ``` -> Info: Message flushing also occurs when the application ends, which ensures log targets can receive complete log messages. +> [!IMPORTANT] +> Message flushing also occurs when the application ends, which ensures log targets can receive complete log messages. When the [[\Yiisoft\Log\Logger|logger object]] flushes log messages to [log targets](#log-targets), they do not get exported immediately. Instead, the message exporting only occurs when a log target accumulates certain number of the filtered @@ -253,7 +256,8 @@ $logger = new \Yiisoft\Log\Logger([$fileTarget]); $logger->setFlushInterval(1); ``` -> Note: Frequent message flushing and exporting will degrade the performance of your application. +> [!NOTE] +> Frequent message flushing and exporting will degrade the performance of your application. ### Toggling Log Targets @@ -281,5 +285,6 @@ sending the content of the [[\Yii\Log\Target::messages]] array to a designated m [[\Yii\Log\Target::formatMessage()]] method to format each message. For more details, you may refer to any of the log target classes included in the Yii release. -> Tip: Instead of creating your own loggers you may try any PSR-3 compatible logger such +> [!TIP] +> Instead of creating your own loggers you may try any PSR-3 compatible logger such as [Monolog](https://github.com/Seldaek/monolog) by using [[\Yii\Log\PsrTarget]]. diff --git a/guide/es/runtime/sessions.md b/guide/es/runtime/sessions.md index bb738b78..d5e5f6c4 100644 --- a/guide/es/runtime/sessions.md +++ b/guide/es/runtime/sessions.md @@ -23,8 +23,9 @@ public function actionProfile(\Yiisoft\Yii\Web\Session\SessionInterface $session } ``` -> Note: Closing session as early as possible is a good practice since many session implementations are blocking other -> requests while session is open. +> [!NOTE] +> Closing session as early as possible is a good practice since many session implementations are blocking other +> requests while the session is open. There are two more ways to close session: diff --git a/guide/es/start/hello.md b/guide/es/start/hello.md index 2849abc8..ed15c644 100644 --- a/guide/es/start/hello.md +++ b/guide/es/start/hello.md @@ -1,6 +1,7 @@ # Saying Hello -> Note: This document reflects current configuration. Yii team is going to make it significantly simpler before release. +> [!NOTE] +> This document reflects the current configuration. Yii team is going to make it significantly simpler before release. This section describes how to create a new "Hello" page in your application. To achieve this goal, you will define a route, create [a handler](../structure/handler.md) diff --git a/guide/es/start/installation.md b/guide/es/start/installation.md index 930d64ad..d7c27d05 100644 --- a/guide/es/start/installation.md +++ b/guide/es/start/installation.md @@ -42,7 +42,8 @@ composer create-project yiisoft/yii-demo app This will install the latest stable version of Yii application template in a directory named `app`. You can choose a different directory name if you want. -> Tip: If you want to install the latest development version of Yii, you may use the following command instead, +> [!TIP] +> If you want to install the latest development version of Yii, you may use the following command instead, > which adds a [stability option](https://getcomposer.org/doc/04-schema.md#minimum-stability): > > ```bash @@ -71,7 +72,8 @@ console command while in the project `public` directory: ../vendor/bin/yii serve ``` -> Note: By default, the HTTP-server will listen to port 8080. However, if that port is already in use or you wish to +> [!NOTE] +> By default, the HTTP-server will listen to port 8080. However, if that port is already in use or you wish to serve multiple applications this way, you might want to specify what port to use. Just add the --port argument: ```bash @@ -91,8 +93,9 @@ You should see the above "Congratulations!" page in your browser. ## Configuring Web Servers -> Info: You may skip this subsection for now if you are just test-driving Yii with no intention - of deploying it to a production server. +> [!IMPORTANT] +> You may skip this subsection for now if you are just test-driving Yii with no intention +> of deploying it to a production server. The application installed according to the above instructions should work out of the box with either an [Apache HTTP server](https://httpd.apache.org/) or an [Nginx HTTP server](https://nginx.org/), on @@ -104,15 +107,18 @@ requires pointing the document root of your Web server to the `app/public` folde want to hide `index.php` from the URL, as described in the [Routing and URL Creation](runtime-routing.md) section. In this subsection, you'll learn how to configure your Apache or Nginx server to achieve these goals. -> Info: By setting `app/public` as the document root, you also prevent end users from accessing +> [!IMPORTANT] +> By setting `app/public` as the document root, you also prevent end users from accessing your private application code and sensitive data files that are stored in the sibling directories of `app/public`. Denying access to those other folders is a security improvement. -> Info: If your application will run in a shared hosting environment where you do not have permission +> [!IMPORTANT] +> If your application runs in a shared hosting environment where you do not have permission to modify its Web server configuration, you may still adjust the structure of your application for better security. Please refer to the [Shared Hosting Environment](tutorial-shared-hosting.md) section for more details. -> Info: If you are running your Yii application behind a reverse proxy, you might need to configure +> [!IMPORTANT] +> If you are running your Yii application behind a reverse proxy, you might need to configure > [Trusted proxies and headers](runtime-requests.md#trusted-proxies) in the request component. ### Apache diff --git a/guide/es/start/workflow.md b/guide/es/start/workflow.md index c1c77979..c4fb91df 100644 --- a/guide/es/start/workflow.md +++ b/guide/es/start/workflow.md @@ -4,7 +4,8 @@ After installing Yii, you have a working Yii application that can be accessed vi the URL `http://hostname/`. This section will introduce the application's built-in functionality, how the code is organized, and how the application handles requests in general. -> Info: For simplicity, throughout this "Getting Started" tutorial, it's assumed that you have set `app/public` +> [!IMPORTANT] +> For simplicity, throughout this "Getting Started" tutorial, it's assumed that you have set `app/public` as the document root of your Web server, and configured the URL for accessing your application to be `http://hostname/index.php` or something similar. For your needs, please adjust the URLs in our descriptions accordingly. diff --git a/guide/es/structure/domain.md b/guide/es/structure/domain.md index f1b5f20d..e7703a3b 100644 --- a/guide/es/structure/domain.md +++ b/guide/es/structure/domain.md @@ -5,7 +5,8 @@ in mind (the problem context), we build an abstraction that consists of entities operates these entities. To focus on the complex part of the problem, domain is, ideally, separated from infrastructure part of the system (i.e., how to save data into database, how to form HTTP response etc.). -> Note: Such isolation is suitable for complex systems. If your project domain is basically create/read/update/delete +> [!NOTE] +> Such isolation is suitable for complex systems. If your project domain is basically create/read/update/delete > for a set of records with not much complex logic it makes no sense to apply complex solution to a simple problem. > Individual concepts of domain design below could be applied separately so make sure to check these even if your > project isn't that complicated. diff --git a/guide/es/structure/package.md b/guide/es/structure/package.md index b19c9e66..9b64000b 100644 --- a/guide/es/structure/package.md +++ b/guide/es/structure/package.md @@ -14,7 +14,8 @@ to use it. This is useful if you are developing private packages that you want t Packages installed by Composer are stored in the `vendor` directory of your project. Because Composer is a dependency manager, when it installs a package, it will also install all its dependent packages. -> Warning: `vendor` directory of your application should never be modified. +> [!WARNING] +> `vendor` directory of your application should never be modified. A package could be installed with the following command: @@ -113,7 +114,8 @@ Each Composer package should have a package name which uniquely identifies the p The format of package names is `vendorName/projectName`. For example, in the package name `yiisoft/queue`, the vendor name and the project name are `yiisoft` and `queue`, respectively. -> Warning: Do NOT use `yiisoft` as your vendor name as it is reserved for use by the Yii itself. +> [!WARNING] +> Do NOT use `yiisoft` as your vendor name as it is reserved for use by the Yii itself. We recommend you prefix `yii-` to the project name for packages that are not able to work as general PHP packages and require Yii application. This will allow users to more easily tell whether a package is Yii specific.