mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-13 12:49:04 +08:00
Moved all filter classes to namespace yii\filters
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\web;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Action;
|
||||
use yii\base\ActionFilter;
|
||||
|
||||
/**
|
||||
* AccessControl provides simple access control based on a set of rules.
|
||||
*
|
||||
* AccessControl is an action filter. It will check its [[rules]] to find
|
||||
* the first rule that matches the current context variables (such as user IP address, user role).
|
||||
* The matching rule will dictate whether to allow or deny the access to the requested controller
|
||||
* action. If no rule matches, the access will be denied.
|
||||
*
|
||||
* To use AccessControl, declare it in the `behaviors()` method of your controller class.
|
||||
* For example, the following declarations will allow authenticated users to access the "create"
|
||||
* and "update" actions and deny all other users from accessing these two actions.
|
||||
*
|
||||
* ~~~
|
||||
* public function behaviors()
|
||||
* {
|
||||
* return [
|
||||
* 'access' => [
|
||||
* 'class' => \yii\web\AccessControl::className(),
|
||||
* 'only' => ['create', 'update'],
|
||||
* 'rules' => [
|
||||
* // deny all POST requests
|
||||
* [
|
||||
* 'allow' => false,
|
||||
* 'verbs' => ['POST']
|
||||
* ],
|
||||
* // allow authenticated users
|
||||
* [
|
||||
* 'allow' => true,
|
||||
* 'roles' => ['@'],
|
||||
* ],
|
||||
* // everything else is denied
|
||||
* ],
|
||||
* ],
|
||||
* ];
|
||||
* }
|
||||
* ~~~
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class AccessControl extends ActionFilter
|
||||
{
|
||||
/**
|
||||
* @var callable a callback that will be called if the access should be denied
|
||||
* to the current user. If not set, [[denyAccess()]] will be called.
|
||||
*
|
||||
* The signature of the callback should be as follows:
|
||||
*
|
||||
* ~~~
|
||||
* function ($rule, $action)
|
||||
* ~~~
|
||||
*
|
||||
* where `$rule` is this rule, and `$action` is the current [[Action|action]] object.
|
||||
* `$rule` will be `null` if access is denied because none of the rules matched.
|
||||
*/
|
||||
public $denyCallback;
|
||||
/**
|
||||
* @var array the default configuration of access rules. Individual rule configurations
|
||||
* specified via [[rules]] will take precedence when the same property of the rule is configured.
|
||||
*/
|
||||
public $ruleConfig = ['class' => 'yii\web\AccessRule'];
|
||||
/**
|
||||
* @var array a list of access rule objects or configuration arrays for creating the rule objects.
|
||||
* If a rule is specified via a configuration array, it will be merged with [[ruleConfig]] first
|
||||
* before it is used for creating the rule object.
|
||||
* @see ruleConfig
|
||||
*/
|
||||
public $rules = [];
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the [[rules]] array by instantiating rule objects from configurations.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
foreach ($this->rules as $i => $rule) {
|
||||
if (is_array($rule)) {
|
||||
$this->rules[$i] = Yii::createObject(array_merge($this->ruleConfig, $rule));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right before an action is to be executed (after all possible filters.)
|
||||
* You may override this method to do last-minute preparation for the action.
|
||||
* @param Action $action the action to be executed.
|
||||
* @return boolean whether the action should continue to be executed.
|
||||
*/
|
||||
public function beforeAction($action)
|
||||
{
|
||||
$user = Yii::$app->getUser();
|
||||
$request = Yii::$app->getRequest();
|
||||
/** @var AccessRule $rule */
|
||||
foreach ($this->rules as $rule) {
|
||||
if ($allow = $rule->allows($action, $user, $request)) {
|
||||
return true;
|
||||
} elseif ($allow === false) {
|
||||
if (isset($rule->denyCallback)) {
|
||||
call_user_func($rule->denyCallback, $rule, $action);
|
||||
} elseif (isset($this->denyCallback)) {
|
||||
call_user_func($this->denyCallback, $rule, $action);
|
||||
} else {
|
||||
$this->denyAccess($user);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (isset($this->denyCallback)) {
|
||||
call_user_func($this->denyCallback, null, $action);
|
||||
} else {
|
||||
$this->denyAccess($user);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Denies the access of the user.
|
||||
* The default implementation will redirect the user to the login page if he is a guest;
|
||||
* if the user is already logged, a 403 HTTP exception will be thrown.
|
||||
* @param User $user the current user
|
||||
* @throws ForbiddenHttpException if the user is already logged in.
|
||||
*/
|
||||
protected function denyAccess($user)
|
||||
{
|
||||
if ($user->getIsGuest()) {
|
||||
$user->loginRequired();
|
||||
} else {
|
||||
throw new ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\web;
|
||||
|
||||
use yii\base\Component;
|
||||
use yii\base\Action;
|
||||
|
||||
/**
|
||||
* This class represents an access rule defined by the [[AccessControl]] action filter
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class AccessRule extends Component
|
||||
{
|
||||
/**
|
||||
* @var boolean whether this is an 'allow' rule or 'deny' rule.
|
||||
*/
|
||||
public $allow;
|
||||
/**
|
||||
* @var array list of action IDs that this rule applies to. The comparison is case-sensitive.
|
||||
* If not set or empty, it means this rule applies to all actions.
|
||||
*/
|
||||
public $actions;
|
||||
/**
|
||||
* @var array list of controller IDs that this rule applies to. The comparison is case-sensitive.
|
||||
* If not set or empty, it means this rule applies to all controllers.
|
||||
*/
|
||||
public $controllers;
|
||||
/**
|
||||
* @var array list of roles that this rule applies to. Two special roles are recognized, and
|
||||
* they are checked via [[User::isGuest]]:
|
||||
*
|
||||
* - `?`: matches a guest user (not authenticated yet)
|
||||
* - `@`: matches an authenticated user
|
||||
*
|
||||
* Using additional role names requires RBAC (Role-Based Access Control), and
|
||||
* [[User::checkAccess()]] will be called.
|
||||
*
|
||||
* If this property is not set or empty, it means this rule applies to all roles.
|
||||
*/
|
||||
public $roles;
|
||||
/**
|
||||
* @var array list of user IP addresses that this rule applies to. An IP address
|
||||
* can contain the wildcard `*` at the end so that it matches IP addresses with the same prefix.
|
||||
* For example, '192.168.*' matches all IP addresses in the segment '192.168.'.
|
||||
* If not set or empty, it means this rule applies to all IP addresses.
|
||||
* @see Request::userIP
|
||||
*/
|
||||
public $ips;
|
||||
/**
|
||||
* @var array list of request methods (e.g. `GET`, `POST`) that this rule applies to.
|
||||
* The request methods must be specified in uppercase.
|
||||
* If not set or empty, it means this rule applies to all request methods.
|
||||
* @see Request::requestMethod
|
||||
*/
|
||||
public $verbs;
|
||||
/**
|
||||
* @var callable a callback that will be called to determine if the rule should be applied.
|
||||
* The signature of the callback should be as follows:
|
||||
*
|
||||
* ~~~
|
||||
* function ($rule, $action)
|
||||
* ~~~
|
||||
*
|
||||
* where `$rule` is this rule, and `$action` is the current [[Action|action]] object.
|
||||
* The callback should return a boolean value indicating whether this rule should be applied.
|
||||
*/
|
||||
public $matchCallback;
|
||||
/**
|
||||
* @var callable a callback that will be called if this rule determines the access to
|
||||
* the current action should be denied. If not set, the behavior will be determined by
|
||||
* [[AccessControl]].
|
||||
*
|
||||
* The signature of the callback should be as follows:
|
||||
*
|
||||
* ~~~
|
||||
* function ($rule, $action)
|
||||
* ~~~
|
||||
*
|
||||
* where `$rule` is this rule, and `$action` is the current [[Action|action]] object.
|
||||
*/
|
||||
public $denyCallback;
|
||||
|
||||
/**
|
||||
* Checks whether the Web user is allowed to perform the specified action.
|
||||
* @param Action $action the action to be performed
|
||||
* @param User $user the user object
|
||||
* @param Request $request
|
||||
* @return boolean|null true if the user is allowed, false if the user is denied, null if the rule does not apply to the user
|
||||
*/
|
||||
public function allows($action, $user, $request)
|
||||
{
|
||||
if ($this->matchAction($action)
|
||||
&& $this->matchRole($user)
|
||||
&& $this->matchIP($request->getUserIP())
|
||||
&& $this->matchVerb($request->getMethod())
|
||||
&& $this->matchController($action->controller)
|
||||
&& $this->matchCustom($action)
|
||||
) {
|
||||
return $this->allow ? true : false;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Action $action the action
|
||||
* @return boolean whether the rule applies to the action
|
||||
*/
|
||||
protected function matchAction($action)
|
||||
{
|
||||
return empty($this->actions) || in_array($action->id, $this->actions, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Controller $controller the controller
|
||||
* @return boolean whether the rule applies to the controller
|
||||
*/
|
||||
protected function matchController($controller)
|
||||
{
|
||||
return empty($this->controllers) || in_array($controller->uniqueId, $this->controllers, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user the user object
|
||||
* @return boolean whether the rule applies to the role
|
||||
*/
|
||||
protected function matchRole($user)
|
||||
{
|
||||
if (empty($this->roles)) {
|
||||
return true;
|
||||
}
|
||||
foreach ($this->roles as $role) {
|
||||
if ($role === '?') {
|
||||
if ($user->getIsGuest()) {
|
||||
return true;
|
||||
}
|
||||
} elseif ($role === '@') {
|
||||
if (!$user->getIsGuest()) {
|
||||
return true;
|
||||
}
|
||||
} elseif ($user->checkAccess($role)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ip the IP address
|
||||
* @return boolean whether the rule applies to the IP address
|
||||
*/
|
||||
protected function matchIP($ip)
|
||||
{
|
||||
if (empty($this->ips)) {
|
||||
return true;
|
||||
}
|
||||
foreach ($this->ips as $rule) {
|
||||
if ($rule === '*' || $rule === $ip || (($pos = strpos($rule, '*')) !== false && !strncmp($ip, $rule, $pos))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $verb the request method
|
||||
* @return boolean whether the rule applies to the request
|
||||
*/
|
||||
protected function matchVerb($verb)
|
||||
{
|
||||
return empty($this->verbs) || in_array($verb, $this->verbs, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Action $action the action to be performed
|
||||
* @return boolean whether the rule should be applied
|
||||
*/
|
||||
protected function matchCustom($action)
|
||||
{
|
||||
return empty($this->matchCallback) || call_user_func($this->matchCallback, $this, $action);
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\web;
|
||||
|
||||
use Yii;
|
||||
use yii\base\ActionFilter;
|
||||
use yii\base\Action;
|
||||
|
||||
/**
|
||||
* The HttpCache provides functionality for caching via HTTP Last-Modified and Etag headers.
|
||||
*
|
||||
* It is an action filter that can be added to a controller and handles the `beforeAction` event.
|
||||
*
|
||||
* To use AccessControl, declare it in the `behaviors()` method of your controller class.
|
||||
* In the following example the filter will be applied to the `list`-action and
|
||||
* the Last-Modified header will contain the date of the last update to the user table in the database.
|
||||
*
|
||||
* ~~~
|
||||
* public function behaviors()
|
||||
* {
|
||||
* return [
|
||||
* 'httpCache' => [
|
||||
* 'class' => \yii\web\HttpCache::className(),
|
||||
* 'only' => ['index'],
|
||||
* 'lastModified' => function ($action, $params) {
|
||||
* $q = new \yii\db\Query();
|
||||
* return $q->from('user')->max('updated_at');
|
||||
* },
|
||||
* // 'etagSeed' => function ($action, $params) {
|
||||
* // return // generate etag seed here
|
||||
* // }
|
||||
* ],
|
||||
* ];
|
||||
* }
|
||||
* ~~~
|
||||
*
|
||||
* @author Da:Sourcerer <webmaster@dasourcerer.net>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class HttpCache extends ActionFilter
|
||||
{
|
||||
/**
|
||||
* @var callable a PHP callback that returns the UNIX timestamp of the last modification time.
|
||||
* The callback's signature should be:
|
||||
*
|
||||
* ~~~
|
||||
* function ($action, $params)
|
||||
* ~~~
|
||||
*
|
||||
* where `$action` is the [[Action]] object that this filter is currently handling;
|
||||
* `$params` takes the value of [[params]]. The callback should return a UNIX timestamp.
|
||||
*/
|
||||
public $lastModified;
|
||||
/**
|
||||
* @var callable a PHP callback that generates the Etag seed string.
|
||||
* The callback's signature should be:
|
||||
*
|
||||
* ~~~
|
||||
* function ($action, $params)
|
||||
* ~~~
|
||||
*
|
||||
* where `$action` is the [[Action]] object that this filter is currently handling;
|
||||
* `$params` takes the value of [[params]]. The callback should return a string serving
|
||||
* as the seed for generating an Etag.
|
||||
*/
|
||||
public $etagSeed;
|
||||
/**
|
||||
* @var mixed additional parameters that should be passed to the [[lastModified]] and [[etagSeed]] callbacks.
|
||||
*/
|
||||
public $params;
|
||||
/**
|
||||
* @var string HTTP cache control header. If null, the header will not be sent.
|
||||
*/
|
||||
public $cacheControlHeader = 'max-age=3600, public';
|
||||
|
||||
/**
|
||||
* This method is invoked right before an action is to be executed (after all possible filters.)
|
||||
* You may override this method to do last-minute preparation for the action.
|
||||
* @param Action $action the action to be executed.
|
||||
* @return boolean whether the action should continue to be executed.
|
||||
*/
|
||||
public function beforeAction($action)
|
||||
{
|
||||
$verb = Yii::$app->getRequest()->getMethod();
|
||||
if ($verb !== 'GET' && $verb !== 'HEAD' || $this->lastModified === null && $this->etagSeed === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$lastModified = $etag = null;
|
||||
if ($this->lastModified !== null) {
|
||||
$lastModified = call_user_func($this->lastModified, $action, $this->params);
|
||||
}
|
||||
if ($this->etagSeed !== null) {
|
||||
$seed = call_user_func($this->etagSeed, $action, $this->params);
|
||||
$etag = $this->generateEtag($seed);
|
||||
}
|
||||
|
||||
$this->sendCacheControlHeader();
|
||||
$response = Yii::$app->getResponse();
|
||||
if ($etag !== null) {
|
||||
$response->getHeaders()->set('Etag', $etag);
|
||||
}
|
||||
|
||||
if ($this->validateCache($lastModified, $etag)) {
|
||||
$response->setStatusCode(304);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($lastModified !== null) {
|
||||
$response->getHeaders()->set('Last-Modified', gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if the HTTP cache contains valid content.
|
||||
* @param integer $lastModified the calculated Last-Modified value in terms of a UNIX timestamp.
|
||||
* If null, the Last-Modified header will not be validated.
|
||||
* @param string $etag the calculated ETag value. If null, the ETag header will not be validated.
|
||||
* @return boolean whether the HTTP cache is still valid.
|
||||
*/
|
||||
protected function validateCache($lastModified, $etag)
|
||||
{
|
||||
if ($lastModified !== null && (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) < $lastModified)) {
|
||||
return false;
|
||||
} else {
|
||||
return $etag === null || isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === $etag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the cache control header to the client
|
||||
* @see cacheControl
|
||||
*/
|
||||
protected function sendCacheControlHeader()
|
||||
{
|
||||
session_cache_limiter('public');
|
||||
$headers = Yii::$app->getResponse()->getHeaders();
|
||||
$headers->set('Pragma');
|
||||
if ($this->cacheControlHeader !== null) {
|
||||
$headers->set('Cache-Control', $this->cacheControlHeader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an Etag from the given seed string.
|
||||
* @param string $seed Seed for the ETag
|
||||
* @return string the generated Etag
|
||||
*/
|
||||
protected function generateEtag($seed)
|
||||
{
|
||||
return '"' . base64_encode(sha1($seed, true)) . '"';
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\web;
|
||||
|
||||
use Yii;
|
||||
use yii\base\ActionFilter;
|
||||
use yii\base\Action;
|
||||
use yii\caching\Dependency;
|
||||
|
||||
/**
|
||||
* The PageCache provides functionality for whole page caching
|
||||
*
|
||||
* It is an action filter that can be added to a controller and handles the `beforeAction` event.
|
||||
*
|
||||
* To use PageCache, declare it in the `behaviors()` method of your controller class.
|
||||
* In the following example the filter will be applied to the `list`-action and
|
||||
* cache the whole page for maximum 60 seconds or until the count of entries in the post table changes.
|
||||
* It also stores different versions of the page depended on the route ([[varyByRoute]] is true by default),
|
||||
* the application language and user id.
|
||||
*
|
||||
* ~~~
|
||||
* public function behaviors()
|
||||
* {
|
||||
* return [
|
||||
* 'pageCache' => [
|
||||
* 'class' => \yii\web\PageCache::className(),
|
||||
* 'only' => ['list'],
|
||||
* 'duration' => 60,
|
||||
* 'dependency' => [
|
||||
* 'class' => 'yii\caching\DbDependency',
|
||||
* 'sql' => 'SELECT COUNT(*) FROM post',
|
||||
* ],
|
||||
* 'variations' => [
|
||||
* Yii::$app->language,
|
||||
* Yii::$app->user->id
|
||||
* ]
|
||||
* ],
|
||||
* ];
|
||||
* }
|
||||
* ~~~
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class PageCache extends ActionFilter
|
||||
{
|
||||
/**
|
||||
* @var boolean whether the content being cached should be differentiated according to the route.
|
||||
* A route consists of the requested controller ID and action ID. Defaults to true.
|
||||
*/
|
||||
public $varyByRoute = true;
|
||||
/**
|
||||
* @var string the application component ID of the [[\yii\caching\Cache|cache]] object.
|
||||
*/
|
||||
public $cache = 'cache';
|
||||
/**
|
||||
* @var integer number of seconds that the data can remain valid in cache.
|
||||
* Use 0 to indicate that the cached data will never expire.
|
||||
*/
|
||||
public $duration = 60;
|
||||
/**
|
||||
* @var array|Dependency the dependency that the cached content depends on.
|
||||
* This can be either a [[Dependency]] object or a configuration array for creating the dependency object.
|
||||
* For example,
|
||||
*
|
||||
* ~~~
|
||||
* [
|
||||
* 'class' => 'yii\caching\DbDependency',
|
||||
* 'sql' => 'SELECT MAX(lastModified) FROM Post',
|
||||
* ]
|
||||
* ~~~
|
||||
*
|
||||
* would make the output cache depends on the last modified time of all posts.
|
||||
* If any post has its modification time changed, the cached content would be invalidated.
|
||||
*/
|
||||
public $dependency;
|
||||
/**
|
||||
* @var array list of factors that would cause the variation of the content being cached.
|
||||
* Each factor is a string representing a variation (e.g. the language, a GET parameter).
|
||||
* The following variation setting will cause the content to be cached in different versions
|
||||
* according to the current application language:
|
||||
*
|
||||
* ~~~
|
||||
* [
|
||||
* Yii::$app->language,
|
||||
* ]
|
||||
* ~~~
|
||||
*/
|
||||
public $variations;
|
||||
/**
|
||||
* @var boolean whether to enable the fragment cache. You may use this property to turn on and off
|
||||
* the fragment cache according to specific setting (e.g. enable fragment cache only for GET requests).
|
||||
*/
|
||||
public $enabled = true;
|
||||
/**
|
||||
* @var \yii\base\View the view component to use for caching. If not set, the default application view component
|
||||
* [[Application::view]] will be used.
|
||||
*/
|
||||
public $view;
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if ($this->view === null) {
|
||||
$this->view = Yii::$app->getView();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right before an action is to be executed (after all possible filters.)
|
||||
* You may override this method to do last-minute preparation for the action.
|
||||
* @param Action $action the action to be executed.
|
||||
* @return boolean whether the action should continue to be executed.
|
||||
*/
|
||||
public function beforeAction($action)
|
||||
{
|
||||
$properties = [];
|
||||
foreach (['cache', 'duration', 'dependency', 'variations', 'enabled'] as $name) {
|
||||
$properties[$name] = $this->$name;
|
||||
}
|
||||
$id = $this->varyByRoute ? $action->getUniqueId() : __CLASS__;
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
if ($this->view->beginCache($id, $properties)) {
|
||||
return true;
|
||||
} else {
|
||||
Yii::$app->getResponse()->content = ob_get_clean();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function afterAction($action, $result)
|
||||
{
|
||||
echo $result;
|
||||
$this->view->endCache();
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\web;
|
||||
|
||||
use Yii;
|
||||
use yii\base\ActionEvent;
|
||||
use yii\base\Behavior;
|
||||
|
||||
/**
|
||||
* VerbFilter is an action filter that filters by HTTP request methods.
|
||||
*
|
||||
* It allows to define allowed HTTP request methods for each action and will throw
|
||||
* an HTTP 405 error when the method is not allowed.
|
||||
*
|
||||
* To use VerbFilter, declare it in the `behaviors()` method of your controller class.
|
||||
* For example, the following declarations will define a typical set of allowed
|
||||
* request methods for REST CRUD actions.
|
||||
*
|
||||
* ~~~
|
||||
* public function behaviors()
|
||||
* {
|
||||
* return [
|
||||
* 'verbs' => [
|
||||
* 'class' => \yii\web\VerbFilter::className(),
|
||||
* 'actions' => [
|
||||
* 'index' => ['get'],
|
||||
* 'view' => ['get'],
|
||||
* 'create' => ['get', 'post'],
|
||||
* 'update' => ['get', 'put', 'post'],
|
||||
* 'delete' => ['post', 'delete'],
|
||||
* ],
|
||||
* ],
|
||||
* ];
|
||||
* }
|
||||
* ~~~
|
||||
*
|
||||
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.7
|
||||
* @author Carsten Brandt <mail@cebe.cc>
|
||||
* @since 2.0
|
||||
*/
|
||||
class VerbFilter extends Behavior
|
||||
{
|
||||
/**
|
||||
* @var array this property defines the allowed request methods for each action.
|
||||
* For each action that should only support limited set of request methods
|
||||
* you add an entry with the action id as array key and an array of
|
||||
* allowed methods (e.g. GET, HEAD, PUT) as the value.
|
||||
* If an action is not listed all request methods are considered allowed.
|
||||
*
|
||||
* You can use '*' to stand for all actions. When an action is explicitly
|
||||
* specified, it takes precedence over the specification given by '*'.
|
||||
*
|
||||
* For example,
|
||||
*
|
||||
* ~~~
|
||||
* [
|
||||
* 'create' => ['get', 'post'],
|
||||
* 'update' => ['get', 'put', 'post'],
|
||||
* 'delete' => ['post', 'delete'],
|
||||
* '*' => ['get'],
|
||||
* ]
|
||||
* ~~~
|
||||
*/
|
||||
public $actions = [];
|
||||
|
||||
/**
|
||||
* Declares event handlers for the [[owner]]'s events.
|
||||
* @return array events (array keys) and the corresponding event handler methods (array values).
|
||||
*/
|
||||
public function events()
|
||||
{
|
||||
return [Controller::EVENT_BEFORE_ACTION => 'beforeAction'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ActionEvent $event
|
||||
* @return boolean
|
||||
* @throws HttpException when the request method is not allowed.
|
||||
*/
|
||||
public function beforeAction($event)
|
||||
{
|
||||
$action = $event->action->id;
|
||||
if (isset($this->actions[$action])) {
|
||||
$verbs = $this->actions[$action];
|
||||
} elseif (isset($this->actions['*'])) {
|
||||
$verbs = $this->actions['*'];
|
||||
} else {
|
||||
return $event->isValid;
|
||||
}
|
||||
|
||||
$verb = Yii::$app->getRequest()->getMethod();
|
||||
$allowed = array_map('strtoupper', $verbs);
|
||||
if (!in_array($verb, $allowed)) {
|
||||
$event->isValid = false;
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.7
|
||||
Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', $allowed));
|
||||
throw new MethodNotAllowedHttpException('Method Not Allowed. This url can only handle the following request methods: ' . implode(', ', $allowed) . '.');
|
||||
}
|
||||
|
||||
return $event->isValid;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user