diff --git a/build/controllers/AppController.php b/build/controllers/AppController.php index a113483..1af0398 100644 --- a/build/controllers/AppController.php +++ b/build/controllers/AppController.php @@ -8,9 +8,7 @@ namespace yii\build\controllers; use Yii; -use yii\base\InvalidParamException; use yii\console\Controller; -use yii\helpers\Console; use yii\helpers\FileHelper; /** @@ -77,6 +75,12 @@ class AppController extends Controller $this->stdout("done.\n"); } + /** + * Finds linkable applications + * + * @param string $dir directory to search in + * @return array list of applications command can link + */ protected function findDirs($dir) { $list = []; diff --git a/docs/guide/README.md b/docs/guide/README.md index f3ece5c..02bf016 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -32,9 +32,11 @@ Application Structure * [Entry Scripts](structure-entry-scripts.md) * [Applications](structure-applications.md) -* [Controllers and Actions](structure-controllers.md) +* [Application Components](structure-application-components.md) +* [Controllers](structure-controllers.md) * [Views](structure-views.md) * [Models](structure-models.md) +* **TBD** [Filters](structure-filters.md) * **TBD** [Widgets](structure-widgets.md) * **TBD** [Modules](structure-modules.md) * **TBD** [Extensions](structure-extensions.md) @@ -49,7 +51,7 @@ Handling Requests * **TBD** [Responses](runtime-responses.md) * **TBD** [Sessions and Cookies](runtime-sessions-cookies.md) * [URL Parsing and Generation](runtime-url-handling.md) -* **TBD** [Filtering](runtime-filtering.md) + Key Concepts diff --git a/docs/guide/structure-application-components.md b/docs/guide/structure-application-components.md new file mode 100644 index 0000000..67a23df --- /dev/null +++ b/docs/guide/structure-application-components.md @@ -0,0 +1,93 @@ +Application Components +====================== + +Applications are [service locators](concept-service-locators.md). They host a set of the so-called +*application components* that provide different services for processing requests. For example, +the `urlManager` component is responsible for routing Web requests to appropriate controllers; +the `db` component provides DB-related services; and so on. + +Each application component has an ID that uniquely identifies itself among other application components +in the same application. You can access an application component through the expression + +```php +\Yii::$app->ComponentID +``` + +For example, you can use `\Yii::$app->db` to get the [[yii\db\Connection|DB connection]], +and `\Yii::$app->cache` to get the [[yii\caching\Cache|primary cache]] registered with the application. + +Application components can be any objects. You can register them by configuring +the [[yii\base\Application::components]] property in [application configurations](structure-applications.md#application-configurations). +For example, + +```php +[ + 'components' => [ + // register "cache" component using a class name + 'cache' => 'yii\caching\ApcCache', + + // register "db" component using a configuration array + 'db' => [ + 'class' => 'yii\db\Connection', + 'dsn' => 'mysql:host=localhost;dbname=demo', + 'username' => 'root', + 'password' => '', + ], + + // register "search" component using an anonymous function + 'search' => function () { + return new app\components\SolrService; + }, + ], +] +``` + +> Info: While you can register as many application components as you want, you should do this judiciously. + Application components are like global variables. Using too many application components can potentially + make your code harder to test and maintain. In many cases, you can simply create a local component + and use it when needed. + + +## Core Application Components + +Yii defines a set of *core* application components with fixed IDs and default configurations. For example, +the [[yii\web\Application::request|request]] component is used to collect information about +a user request and resolve it into a [route](runtime-routing.md); the [[yii\base\Application::db|db]] +component represents a database connection through which you can perform database queries. +It is with help of these core application components that Yii applications are able to handle user requests. + +Below is the list of the predefined core application components. You may configure and customize them +like you do with normal application components. When you are configuring a core application component, +if you do not specify its class, the default one will be used. + +* [[yii\web\AssetManager|assetManager]]: manages asset bundles and asset publishing. + Please refer to the [Managing Assets](output-assets.md) section for more details. +* [[yii\db\Connection|db]]: represents a database connection through which you can perform DB queries. + Note that when you configure this component, you must specify the component class as well as other required + component properties, such as [[yii\db\Connection::dsn]]. + Please refer to the [Data Access Objects](db-dao.md) section for more details. +* [[yii\base\Application::errorHandler|errorHandler]]: handles PHP errors and exceptions. + Please refer to the [Handling Errors](tutorial-handling-errors.md) section for more details. +* [[yii\base\Formatter|formatter]]: formats data when they are displayed to end users. For example, a number + may be displayed with thousand separator, a date may be formatted in long format. + Please refer to the [Data Formatting](output-formatting.md) section for more details. +* [[yii\i18n\I18N|i18n]]: supports message translation and formatting. + Please refer to the [Internationalization](tutorial-i18n.md) section for more details. +* [[yii\log\Dispatcher|log]]: manages log targets. + Please refer to the [Logging](tutorial-logging.md) section for more details. +* [[yii\swiftmailer\Mailer|mail]]: supports mail composing and sending. + Please refer to the [Mailing](tutorial-mailing.md) section for more details. +* [[yii\base\Application::response|response]]: represents the response being sent to end users. + Please refer to the [Responses](runtime-responses.md) section for more details. +* [[yii\base\Application::request|request]]: represents the request received from end users. + Please refer to the [Requests](runtime-requests.md) section for more details. +* [[yii\web\Session|session]]: represents the session information. This component is only available + in [[yii\web\Application|Web applications]]. + Please refer to the [Sessions and Cookies](runtime-sessions-cookies.md) section for more details. +* [[yii\web\UrlManager|urlManager]]: supports URL parsing and creation. + Please refer to the [URL Parsing and Generation](runtime-url-handling.md) section for more details. +* [[yii\web\User|user]]: represents the user authentication information. This component is only available + in [[yii\web\Application|Web applications]] + Please refer to the [Authentication](security-authentication.md) section for more details. +* [[yii\web\View|view]]: supports view rendering. + Please refer to the [Views](structure-views.md) section for more details. diff --git a/docs/guide/structure-applications.md b/docs/guide/structure-applications.md index bd2c790..6706b15 100644 --- a/docs/guide/structure-applications.md +++ b/docs/guide/structure-applications.md @@ -177,7 +177,7 @@ The rest of the array elements (key-value pairs) specify the parameters to be bo #### [[yii\base\Application::components|components]] This is the single most important property. It allows you to register a list of named components -called [application components](#application-components) that you can use in other places. For example, +called [application components](#structure-application-components.md) that you can use in other places. For example, ```php [ @@ -199,7 +199,7 @@ while the value represents the component class name or [configuration](concept-c You can register any component with an application, and the component can later be accessed globally using the expression `\Yii::$app->ComponentID`. -Please read the [application components](#application-components) section for details. +Please read the [Application Components](structure-application-components.md) section for details. #### [[yii\base\Application::controllerMap|controllerMap]] @@ -217,7 +217,7 @@ specific controllers. In the following example, `account` will be mapped to 'account' => 'app\controllers\UserController', 'article' => [ 'class' => 'app\controllers\PostController', - 'pageTitle' => 'something new', + 'enableCsrfValidation' => false, ], ], ], @@ -569,71 +569,6 @@ as for that of `beforeAction`. That is, controllers are the first objects trigge followed by modules (if any), and finally applications. -## Application Components - -Applications are [service locators](concept-service-locators.md). They host a set of the so-called -*application components* that provide different services for processing requests. For example, -the `urlManager` component is responsible for routing Web requests to appropriate controllers; -the `db` component provides DB-related services; and so on. - -Each application component has an ID that uniquely identifies itself among other application components -in the same application. You can access an application component through the expression `$app->ID`, -where `$app` refers to an application instance, and `ID` stands for the ID of an application component. -For example, you can use `Yii::$app->db` to get the [[yii\db\Connection|DB connection]], and `Yii::$app->cache` -to get the [[yii\caching\Cache|primary cache]] registered with the application. - -Application components can be any objects. You can register them with an application to make them -globally accessible. This is usually done by configuring the [[yii\base\Application::components]] property, -as described in the [components](#components) subsection. - -> Info: While you can register as many application components as you want, you should do this judiciously. - Application components are like global variables. Using too many application components can potentially - make your code harder to test and maintain. In many cases, you can simply create a local component - and use it when needed. - -Yii defines a set of *core* application components with fixed IDs and default configurations. For example, -the [[yii\web\Application::request|request]] component is used to collect information about -a user request and resolve it into a [route](runtime-routing.md); the [[yii\base\Application::db|db]] -component represents a database connection through which you can perform database queries. -It is with help of these core application components that Yii applications are able to handle user requests. - -Below is the list of the predefined core application components. You may configure and customize them -like you do with normal application components. When you are configuring a core application component, -if you do not specify its class, the default one will be used. - -* [[yii\web\AssetManager|assetManager]]: manages asset bundles and asset publishing. - Please refer to the [Managing Assets](output-assets.md) section for more details. -* [[yii\db\Connection|db]]: represents a database connection through which you can perform DB queries. - Note that when you configure this component, you must specify the component class as well as other required - component properties, such as [[yii\db\Connection::dsn]]. - Please refer to the [Data Access Objects](db-dao.md) section for more details. -* [[yii\base\Application::errorHandler|errorHandler]]: handles PHP errors and exceptions. - Please refer to the [Handling Errors](tutorial-handling-errors.md) section for more details. -* [[yii\base\Formatter|formatter]]: formats data when they are displayed to end users. For example, a number - may be displayed with thousand separator, a date may be formatted in long format. - Please refer to the [Data Formatting](output-formatting.md) section for more details. -* [[yii\i18n\I18N|i18n]]: supports message translation and formatting. - Please refer to the [Internationalization](tutorial-i18n.md) section for more details. -* [[yii\log\Dispatcher|log]]: manages log targets. - Please refer to the [Logging](tutorial-logging.md) section for more details. -* [[yii\swiftmailer\Mailer|mail]]: supports mail composing and sending. - Please refer to the [Mailing](tutorial-mailing.md) section for more details. -* [[yii\base\Application::response|response]]: represents the response being sent to end users. - Please refer to the [Responses](runtime-responses.md) section for more details. -* [[yii\base\Application::request|request]]: represents the request received from end users. - Please refer to the [Requests](runtime-requests.md) section for more details. -* [[yii\web\Session|session]]: represents the session information. This component is only available - in [[yii\web\Application|Web applications]]. - Please refer to the [Sessions and Cookies](runtime-sessions-cookies.md) section for more details. -* [[yii\web\UrlManager|urlManager]]: supports URL parsing and creation. - Please refer to the [URL Parsing and Generation](runtime-url-handling.md) section for more details. -* [[yii\web\User|user]]: represents the user authentication information. This component is only available - in [[yii\web\Application|Web applications]] - Please refer to the [Authentication](security-authentication.md) section for more details. -* [[yii\web\View|view]]: supports view rendering. - Please refer to the [Views](structure-views.md) section for more details. - - ## Application Lifecycle When an [entry script](structure-entry-scripts.md) is being executed to handle a request, diff --git a/docs/guide/structure-controllers.md b/docs/guide/structure-controllers.md index 04ab6a2..518abac 100644 --- a/docs/guide/structure-controllers.md +++ b/docs/guide/structure-controllers.md @@ -1,19 +1,107 @@ -Controller -========== +Controllers +=========== -> Note: This section is under development. +Controllers are part of the [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture. +They contain the actual logic about processing requests and generating responses. In particular, after +taking over the control from [applications](structure-applications.md), controllers will analyze incoming request data, +pass them to [models](structure-models.md), inject model results into [views](structure-views.md), +and finally generate outgoing responses. -Controller is one of the key parts of the application. It determines how to handle incoming request and creates a response. +Controllers are composed by *actions*, each of which deals with one particular type of request. A controller +can have one or multiple actions. -Most often a controller takes HTTP request data and returns HTML, JSON or XML as a response. +> Info: You may consider a controller as a grouping of similar actions. The controller provides an environment + for sharing common data among its actions. -Basics ------- -Controller resides in application's `controllers` directory and is named like `SiteController.php`, -where the `Site` part could be anything describing a set of actions it contains. +## IDs and Routes -The basic web controller is a class that extends [[yii\web\Controller]] and could be very simple: +Both controllers and actions have IDs. Controller IDs are used to uniquely identify controllers within the same +application, while actions IDs are used to identify actions within the same controller. The combination of +a controller ID and an action ID forms a *route* which takes the format of `ControllerID/ActionID`. + +End users can address any controller action through the corresponding route. For example, the URL +`http://hostname/index.php?r=site/index` specifies that the request should be handled by the `site` controller +using its `index` action. + +By default, controller and action IDs should contain lower-case alphanumeric characters and dashes only. +For example, `site`, `index`, `post-comment` and `comment2` are all valid controller/action IDs, while +`Site`, `postComment` and `index?` are not. To use other characters in the IDs, you should configure +[[yii\base\Application::controllerMap]] and/or override [[yii\base\Controller::actions()]]. + +In practice, a controller is often designed to handle the requests about a specific type of resource, +while each action within it supports a specific manipulation about that resource type. For this reason, +controller IDs are often nouns, while action IDs are often verbs. For example, you may create an `article` +controller to handle all requests about article data; and within the `article` controller, you may create +actions such as `create`, `update`, `delete` to support the corresponding manipulations about articles. + + +## Creating Controllers + +In [[yii\web\Application|Web applications]], controllers should extend from [[yii\web\Controller]] or its +child classes. Similarly in [[yii\console\Application|console applications]], controllers should extend from +[[yii\console\Controller]] or its child classes. + +Controller classes should be [autoloadable](concept-autoloading.md). They should be created under +the namespace as specified by [[yii\base\Application::controllerNamespace]]. By default, it is `app\controllers`. +This means controller classes should usually be located under the path aliased as `@app/controllers`. + +The following code defines a `site` controller: + +```php +namespace app\controllers; + +use yii\web\Controller; + +class SiteController extends Controller +{ +} +``` + +As aforementioned, the class should be saved in the file `@app/controllers/SiteController.php`. + + +### Controller Class Naming + +The controller class name `SiteController` is derived from the controller ID `site` according to the following rules: + +* Turn the first letter in each word into upper case; +* Remove dashes; +* Append the suffix `Controller`. + +For example, `site` becomes `SiteController`, and `post-comment` becomes `PostCommentController`. + +If you want to name controller classes in a different way, you may configure the [[yii\base\Application::controllerMap]] +property, like the following in an [application configuration](structure-applications.md#application-configurations): + +```php +[ + 'controllerMap' => [ + [ + 'account' => 'app\controllers\UserController', + 'article' => [ + 'class' => 'app\controllers\PostController', + 'enableCsrfValidation' => false, + ], + ], + ], +] +``` + + +## Creating Actions + +You can create actions in two ways: inline actions and standalone actions. An inline action is +defined as a method in the controller class, while a standalone action is a class extending +[[yii\base\Action]] or its child class. Inline actions take less effort to create and are often preferred +if you have no intention to reuse these actions. Standalone actions, on the other hand, are mainly +created to be used in different controllers or be redistributed as [extensions](structure-extensions.md). + + +### Inline Actions + +Inline actions are defined in terms of *public* `action*` methods in controller classes. The following code defines +two actions `index` and `hello-world`. ```php namespace app\controllers; @@ -24,62 +112,117 @@ class SiteController extends Controller { public function actionIndex() { - // will render view from "views/site/index.php" return $this->render('index'); } - public function actionTest() + public function actionHelloWorld() { - // will just print "test" to the browser - return 'test'; + return 'Hello World'; } } ``` -As you can see, typical controller contains actions that are public class methods named as `actionSomething`. -The output of an action is what the method returns: it could be a string or an instance of [[yii\web\Response]], [for example](#custom-response-class). -The return value will be handled by the `response` application -component which can convert the output to different formats such as JSON for example. The default behavior -is to output the value unchanged though. +Action IDs for inline actions must contain lower-case alphanumeric characters and dashes only. And the names +of the `action*` methods are derived from action IDs according to the following criteria: +* Turn the first letter in each word of the action ID into upper case; +* Remove dashes; +* Prepend the prefix `action`. -Routes ------- +For example, `index` becomes `actionIndex`, and `hello-world` becomes `actionHelloWorld`, as shown in the +above example. -Each controller action has a corresponding internal route. In our example above `actionIndex` has `site/index` route -and `actionTest` has `site/test` route. In this route `site` is referred to as controller ID while `test` is action ID. +> Note: The names of `action*` methods are *case-sensitive*. If you have a method named `ActionIndex`, + it will not be considered as an `action*` method, and as a result, the request for the `index` action + will result in an exception. Also note that `action*` methods must be public. A private or protected + `action*` method does NOT define an inline action. -By default you can access specific controller and action using the `http://example.com/?r=controller/action` URL. This -behavior is fully customizable. For more details please refer to [URL Management](url.md). +The return value of an `action*` method can be either a [response](runtime-responses.md) object or +the data to be populated into a [response](runtime-responses.md). In particular, for Web applications, +the data will be assigned to [[yii\web\Response::data]], while for console applications, the data +will be assigned to [[yii\console\Response::exitStatus]]. In the example above, each action returns +a string which will be assigned to [[yii\web\Response::data]] and further displayed to end users. -If a controller is located inside a module, the route of its actions will be in the format of `module/controller/action`. +Inline actions are preferred in most cases because they take little effort to create. However, if an action +can be reused in another controller or application, you may consider defining it as a standalone action. -A controller can be located under a subdirectory of the controller directory of an application or module. The route -will be prefixed with the corresponding directory names. For example, you may have a `UserController` under `controllers/admin`. -The route of its `actionIndex` would be `admin/user/index`, and `admin/user` would be the controller ID. -In case module, controller or action specified isn't found Yii will return "not found" page and HTTP status code 404. +### Standalone Actions -> Note: If module name, controller name or action name contains camelCased words, internal route will use dashes i.e. for -`DateTimeController::actionFastForward` route will be `date-time/fast-forward`. +Standalone actions are defined in terms of action classes extending [[yii\base\Action]] or its child classes. +For example, in the Yii releases, there are [[yii\web\ViewAction]] a nd [[yii\web\ErrorAction]], both of which +are standalone actions. + +To use a standalone action, you should override the [[yii\base\Controller::actions()]] method in your +controller classes like the following: + +```php +public function actions() +{ + return [ + // declares "error" action using a class name + 'error' => 'yii\web\ErrorAction', + + // declares "view" action using a configuration array + 'view' => [ + 'class' => 'yii\web\ViewAction', + 'viewPrefix' => '', + ], + ]; +} +``` + +The method should return an array whose keys are action IDs and values the corresponding action class names +or [configurations](concept-configurations.md). + +Action IDs for standalone actions can contain arbitrary characters, as long as they are declared in +the [[yii\base\Controller::actions()]] method. + +To create a standalone action class, you should extend [[yii\base\Action]] or its child class, and implement +a public method named `run()`. The role of the `run()` method is similar to an inline action method. For example, + +```php +render('home'); + } +} +``` -### Action parameters +### Action Parameters You can define named arguments for an action and these will be automatically populated from corresponding values from `$_GET`. This is very convenient both because of the short syntax and an ability to specify defaults: @@ -112,6 +255,9 @@ The action above can be accessed using either `http://example.com/?r=blog/view&i `http://example.com/?r=blog/view&id=42&version=3`. In the first case `version` isn't specified and default parameter value is used instead. + +### Action Patterns + ### Getting data from request If your action is working with data from HTTP POST or has too many GET parameters you can rely on request object that @@ -144,141 +290,21 @@ class BlogController extends Controller } ``` -Standalone actions ------------------- - -If action is generic enough it makes sense to implement it in a separate class to be able to reuse it. -Create `actions/Page.php` - -```php -namespace app\actions; - -class Page extends \yii\base\Action -{ - public $view = 'index'; - - public function run() - { - return $this->controller->render($view); - } -} -``` - -The following code is too simple to implement as a separate action but gives an idea of how it works. Action implemented -can be used in your controller as following: - -```php -class SiteController extends \yii\web\Controller -{ - public function actions() - { - return [ - 'about' => [ - 'class' => 'app\actions\Page', - 'view' => 'about', - ], - ]; - } -} -``` - -After doing so you can access your action as `http://example.com/?r=site/about`. - - -Action Filters --------------- - -You may apply some action filters to controller actions to accomplish tasks such as determining -who can access the current action, decorating the result of the action, etc. - -An action filter is an instance of a class extending [[yii\base\ActionFilter]]. -To use an action filter, attach it as a behavior to a controller or a module. The following -example shows how to enable HTTP caching for the `index` action: +## Controllers in Modules and Subdirectories -```php -public function behaviors() -{ - return [ - 'httpCache' => [ - 'class' => \yii\filters\HttpCache::className(), - 'only' => ['index'], - 'lastModified' => function ($action, $params) { - $q = new \yii\db\Query(); - return $q->from('user')->max('updated_at'); - }, - ], - ]; -} -``` - -You may use multiple action filters at the same time. These filters will be applied in the -order they are declared in `behaviors()`. If any of the filter cancels the action execution, -the filters after it will be skipped. - -When you attach a filter to a controller, it can be applied to all actions of that controller; -If you attach a filter to a module (or application), it can be applied to the actions of any controller -within that module (or application). - -To create a new action filter, extend from [[yii\base\ActionFilter]] and override the -[[yii\base\ActionFilter::beforeAction()|beforeAction()]] and [[yii\base\ActionFilter::afterAction()|afterAction()]] -methods. The former will be executed before an action runs while the latter after an action runs. -The return value of [[yii\base\ActionFilter::beforeAction()|beforeAction()]] determines whether -an action should be executed or not. If `beforeAction()` of a filter returns false, the filters after this one -will be skipped and the action will not be executed. - -The [authorization](authorization.md) section of this guide shows how to use the [[yii\filters\AccessControl]] filter, -and the [caching](caching.md) section gives more details about the [[yii\filters\PageCache]] and [[yii\filters\HttpCache]] filters. -These built-in filters are also good references when you learn to create your own filters. - - -Catching all incoming requests ------------------------------- - -Sometimes it is useful to handle all incoming requests with a single controller action. For example, displaying a notice -when website is in maintenance mode. In order to do it you should configure web application `catchAll` property either -dynamically or via application config: - -```php -return [ - 'id' => 'basic', - 'basePath' => dirname(__DIR__), - // ... - 'catchAll' => [ // <-- here - 'offline/notice', - 'param1' => 'value1', - 'param2' => 'value2', - ], -] -``` +If a controller is located inside a module, the route of its actions will be in the format of `module/controller/action`. -In the above `offline/notice` refer to `OfflineController::actionNotice()`. `param1` and `param2` are parameters passed -to action method. +A controller can be located under a subdirectory of the controller directory of an application or module. The route +will be prefixed with the corresponding directory names. For example, you may have a `UserController` under `controllers/admin`. +The route of its `actionIndex` would be `admin/user/index`, and `admin/user` would be the controller ID. -Custom response class ---------------------- +In case module, controller or action specified isn't found Yii will return "not found" page and HTTP status code 404. -```php -namespace app\controllers; -use yii\web\Controller; -use app\components\web\MyCustomResponse; #extended from yii\web\Response +> Note: If module name, controller name or action name contains camelCased words, internal route will use dashes i.e. for +`DateTimeController::actionFastForward` route will be `date-time/fast-forward`. -class SiteController extends Controller -{ - public function actionCustom() - { - /* - * do your things here - * since Response in extended from yii\base\Object, you can initialize its values by passing in - * __constructor() simple array. - */ - return new MyCustomResponse(['data' => $myCustomData]); - } -} -``` -See also --------- +## Controller Lifecycle -- [Console](console.md) diff --git a/docs/guide/structure-filters.md b/docs/guide/structure-filters.md new file mode 100644 index 0000000..9f94c38 --- /dev/null +++ b/docs/guide/structure-filters.md @@ -0,0 +1,42 @@ +You may apply some action filters to controller actions to accomplish tasks such as determining +who can access the current action, decorating the result of the action, etc. + +An action filter is an instance of a class extending [[yii\base\ActionFilter]]. + +To use an action filter, attach it as a behavior to a controller or a module. The following +example shows how to enable HTTP caching for the `index` action: + +```php +public function behaviors() +{ + return [ + 'httpCache' => [ + 'class' => \yii\filters\HttpCache::className(), + 'only' => ['index'], + 'lastModified' => function ($action, $params) { + $q = new \yii\db\Query(); + return $q->from('user')->max('updated_at'); + }, + ], + ]; +} +``` + +You may use multiple action filters at the same time. These filters will be applied in the +order they are declared in `behaviors()`. If any of the filter cancels the action execution, +the filters after it will be skipped. + +When you attach a filter to a controller, it can be applied to all actions of that controller; +If you attach a filter to a module (or application), it can be applied to the actions of any controller +within that module (or application). + +To create a new action filter, extend from [[yii\base\ActionFilter]] and override the +[[yii\base\ActionFilter::beforeAction()|beforeAction()]] and [[yii\base\ActionFilter::afterAction()|afterAction()]] +methods. The former will be executed before an action runs while the latter after an action runs. +The return value of [[yii\base\ActionFilter::beforeAction()|beforeAction()]] determines whether +an action should be executed or not. If `beforeAction()` of a filter returns false, the filters after this one +will be skipped and the action will not be executed. + +The [authorization](authorization.md) section of this guide shows how to use the [[yii\filters\AccessControl]] filter, +and the [caching](caching.md) section gives more details about the [[yii\filters\PageCache]] and [[yii\filters\HttpCache]] filters. +These built-in filters are also good references when you learn to create your own filters. diff --git a/extensions/apidoc/helpers/ApiIndexer.php b/extensions/apidoc/helpers/ApiIndexer.php index 8cb71c4..cab957b 100644 --- a/extensions/apidoc/helpers/ApiIndexer.php +++ b/extensions/apidoc/helpers/ApiIndexer.php @@ -11,7 +11,6 @@ namespace yii\apidoc\helpers; use cebe\jssearch\Indexer; use cebe\jssearch\tokenizer\StandardTokenizer; use cebe\jssearch\TokenizerInterface; -use yii\helpers\StringHelper; class ApiIndexer extends Indexer { diff --git a/extensions/apidoc/helpers/ApiMarkdown.php b/extensions/apidoc/helpers/ApiMarkdown.php index 7ce3836..57a22c6 100644 --- a/extensions/apidoc/helpers/ApiMarkdown.php +++ b/extensions/apidoc/helpers/ApiMarkdown.php @@ -9,7 +9,6 @@ namespace yii\apidoc\helpers; use cebe\markdown\GithubMarkdown; use phpDocumentor\Reflection\DocBlock\Type\Collection; -use yii\apidoc\models\MethodDoc; use yii\apidoc\models\TypeDoc; use yii\apidoc\renderers\BaseRenderer; use yii\helpers\Inflector; diff --git a/extensions/apidoc/helpers/ApiMarkdownTrait.php b/extensions/apidoc/helpers/ApiMarkdownTrait.php index d2e0825..d6bbee0 100644 --- a/extensions/apidoc/helpers/ApiMarkdownTrait.php +++ b/extensions/apidoc/helpers/ApiMarkdownTrait.php @@ -8,7 +8,6 @@ namespace yii\apidoc\helpers; -use cebe\markdown\GithubMarkdown; use phpDocumentor\Reflection\DocBlock\Type\Collection; use yii\apidoc\models\MethodDoc; use yii\apidoc\models\TypeDoc; diff --git a/extensions/apidoc/templates/pdf/GuideRenderer.php b/extensions/apidoc/templates/pdf/GuideRenderer.php index e34f775..5b1fba4 100644 --- a/extensions/apidoc/templates/pdf/GuideRenderer.php +++ b/extensions/apidoc/templates/pdf/GuideRenderer.php @@ -9,11 +9,9 @@ namespace yii\apidoc\templates\pdf; use cebe\markdown\latex\GithubMarkdown; use Yii; -use yii\apidoc\helpers\ApiIndexer; use yii\apidoc\helpers\ApiMarkdownLaTeX; use yii\apidoc\helpers\IndexFileAnalyzer; use yii\helpers\Console; -use yii\helpers\FileHelper; /** * diff --git a/extensions/elasticsearch/ActiveQuery.php b/extensions/elasticsearch/ActiveQuery.php index 499eccc..94fa0af 100644 --- a/extensions/elasticsearch/ActiveQuery.php +++ b/extensions/elasticsearch/ActiveQuery.php @@ -7,7 +7,6 @@ namespace yii\elasticsearch; -use yii\base\NotSupportedException; use yii\db\ActiveQueryInterface; use yii\db\ActiveQueryTrait; use yii\db\ActiveRelationTrait; diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index d068280..2047cca 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -38,6 +38,7 @@ Yii Framework 2 Change Log - Bug #3601: Fixed the bug that the refresh URL was not generated correctly by `Captcha` (qiangxue, klevron) - Bug: Fixed inconsistent return of `\yii\console\Application::runAction()` (samdark) - Bug: URL encoding for the route parameter added to `\yii\web\UrlManager` (klimov-paul) +- Bug: Fixed the bug that requesting protected or private action methods would cause 500 error instead of 404 (qiangxue) - Enh #2264: `CookieCollection::has()` will return false for expired or removed cookies (qiangxue) - Enh #2435: `yii\db\IntegrityException` is now thrown on database integrity errors instead of general `yii\db\Exception` (samdark) - Enh #2837: Error page now shows arguments in stack trace method calls (samdark) diff --git a/framework/base/Controller.php b/framework/base/Controller.php index 30da9bd..7412f91 100644 --- a/framework/base/Controller.php +++ b/framework/base/Controller.php @@ -216,7 +216,7 @@ class Controller extends Component implements ViewContextInterface $methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $id)))); if (method_exists($this, $methodName)) { $method = new \ReflectionMethod($this, $methodName); - if ($method->getName() === $methodName) { + if ($method->isPublic() && $method->getName() === $methodName) { return new InlineAction($id, $this, $methodName); } } diff --git a/framework/console/controllers/AssetController.php b/framework/console/controllers/AssetController.php index cdb989c..3ff88a4 100644 --- a/framework/console/controllers/AssetController.php +++ b/framework/console/controllers/AssetController.php @@ -10,7 +10,6 @@ namespace yii\console\controllers; use Yii; use yii\console\Exception; use yii\console\Controller; -use yii\helpers\StringHelper; use yii\helpers\VarDumper; /** diff --git a/framework/helpers/BaseVarDumper.php b/framework/helpers/BaseVarDumper.php index 364121d..882fa4e 100644 --- a/framework/helpers/BaseVarDumper.php +++ b/framework/helpers/BaseVarDumper.php @@ -7,8 +7,6 @@ namespace yii\helpers; -use yii\base\Arrayable; - /** * BaseVarDumper provides concrete implementation for [[VarDumper]]. * diff --git a/framework/rest/CreateAction.php b/framework/rest/CreateAction.php index 2530627..1f7ae91 100644 --- a/framework/rest/CreateAction.php +++ b/framework/rest/CreateAction.php @@ -9,7 +9,6 @@ namespace yii\rest; use Yii; use yii\base\Model; -use yii\db\ActiveRecord; use yii\helpers\Url; /** diff --git a/framework/rest/DeleteAction.php b/framework/rest/DeleteAction.php index 6c05acc..98e3c5a 100644 --- a/framework/rest/DeleteAction.php +++ b/framework/rest/DeleteAction.php @@ -8,7 +8,6 @@ namespace yii\rest; use Yii; -use yii\db\ActiveRecord; /** * DeleteAction implements the API endpoint for deleting a model. diff --git a/tests/unit/framework/helpers/VarDumperTest.php b/tests/unit/framework/helpers/VarDumperTest.php index 52467db..443ef99 100644 --- a/tests/unit/framework/helpers/VarDumperTest.php +++ b/tests/unit/framework/helpers/VarDumperTest.php @@ -1,7 +1,6 @@