diff --git a/framework/web/Application.php b/framework/web/Application.php
index 2533f04..b839d92 100644
--- a/framework/web/Application.php
+++ b/framework/web/Application.php
@@ -7,7 +7,7 @@
namespace yii\web;
-use yii\base\InvalidParamException;
+use Yii;
/**
* Application is the base class for all application classes.
@@ -28,7 +28,7 @@ class Application extends \yii\base\Application
public function registerDefaultAliases()
{
parent::registerDefaultAliases();
- \Yii::$aliases['@webroot'] = dirname($_SERVER['SCRIPT_FILENAME']);
+ Yii::$aliases['@webroot'] = dirname($_SERVER['SCRIPT_FILENAME']);
}
/**
@@ -41,6 +41,32 @@ class Application extends \yii\base\Application
return $this->runAction($route, $params);
}
+ private $_homeUrl;
+
+ /**
+ * @return string the homepage URL
+ */
+ public function getHomeUrl()
+ {
+ if ($this->_homeUrl === null) {
+ if ($this->getUrlManager()->showScriptName) {
+ return $this->getRequest()->getScriptUrl();
+ } else {
+ return $this->getRequest()->getBaseUrl() . '/';
+ }
+ } else {
+ return $this->_homeUrl;
+ }
+ }
+
+ /**
+ * @param string $value the homepage URL
+ */
+ public function setHomeUrl($value)
+ {
+ $this->_homeUrl = $value;
+ }
+
/**
* Returns the request component.
* @return Request the request component
diff --git a/framework/web/Controller.php b/framework/web/Controller.php
index 93b74aa..126fbbc 100644
--- a/framework/web/Controller.php
+++ b/framework/web/Controller.php
@@ -8,6 +8,7 @@
namespace yii\web;
use Yii;
+use yii\helpers\Html;
/**
* Controller is the base class of Web controllers.
@@ -41,4 +42,18 @@ class Controller extends \yii\base\Controller
return Yii::$app->getUrlManager()->createUrl($route, $params);
}
+ /**
+ * Redirects the browser to the specified URL or route (controller/action).
+ * @param mixed $url the URL to be redirected to. If the parameter is an array,
+ * the first element must be a route to a controller action and the rest
+ * are GET parameters in name-value pairs.
+ * @param boolean $terminate whether to terminate the current application after calling this method. Defaults to true.
+ * @param integer $statusCode the HTTP status code. Defaults to 302. See {@link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html}
+ * for details about HTTP status code.
+ */
+ public function redirect($url, $terminate = true, $statusCode = 302)
+ {
+ $url = Html::url($url);
+ Yii::$app->getResponse()->redirect($url, $terminate, $statusCode);
+ }
}
\ No newline at end of file
diff --git a/framework/web/Identity.php b/framework/web/Identity.php
index 805d3d4..5f07d58 100644
--- a/framework/web/Identity.php
+++ b/framework/web/Identity.php
@@ -38,7 +38,8 @@ interface Identity
* Finds an identity by the given ID.
* @param string|integer $id the ID to be looked for
* @return Identity the identity object that matches the given ID.
- * Null should be returned if such an identity cannot be found.
+ * Null should be returned if such an identity cannot be found
+ * or the identity is not in an active state (disabled, deleted, etc.)
*/
public static function findIdentity($id);
}
\ No newline at end of file
diff --git a/framework/web/Response.php b/framework/web/Response.php
index d23c5b9..8133132 100644
--- a/framework/web/Response.php
+++ b/framework/web/Response.php
@@ -107,37 +107,42 @@ class Response extends \yii\base\Response
*
addHeaders: an array of additional http headers in header-value pairs (available since version 1.1.10)
*
*/
- public function xSendFile($filePath, $options=array())
+ public function xSendFile($filePath, $options = array())
{
- if(!isset($options['forceDownload']) || $options['forceDownload'])
- $disposition='attachment';
- else
- $disposition='inline';
+ if (!isset($options['forceDownload']) || $options['forceDownload']) {
+ $disposition = 'attachment';
+ } else {
+ $disposition = 'inline';
+ }
- if(!isset($options['saveName']))
- $options['saveName']=basename($filePath);
+ if (!isset($options['saveName'])) {
+ $options['saveName'] = basename($filePath);
+ }
- if(!isset($options['mimeType']))
- {
- if(($options['mimeType']=CFileHelper::getMimeTypeByExtension($filePath))===null)
- $options['mimeType']='text/plain';
+ if (!isset($options['mimeType'])) {
+ if (($options['mimeType'] = CFileHelper::getMimeTypeByExtension($filePath)) === null) {
+ $options['mimeType'] = 'text/plain';
+ }
}
- if(!isset($options['xHeader']))
- $options['xHeader']='X-Sendfile';
+ if (!isset($options['xHeader'])) {
+ $options['xHeader'] = 'X-Sendfile';
+ }
- if($options['mimeType'] !== null)
- header('Content-type: '.$options['mimeType']);
- header('Content-Disposition: '.$disposition.'; filename="'.$options['saveName'].'"');
- if(isset($options['addHeaders']))
- {
- foreach($options['addHeaders'] as $header=>$value)
- header($header.': '.$value);
+ if ($options['mimeType'] !== null) {
+ header('Content-type: ' . $options['mimeType']);
+ }
+ header('Content-Disposition: ' . $disposition . '; filename="' . $options['saveName'] . '"');
+ if (isset($options['addHeaders'])) {
+ foreach ($options['addHeaders'] as $header => $value) {
+ header($header . ': ' . $value);
+ }
}
- header(trim($options['xHeader']).': '.$filePath);
+ header(trim($options['xHeader']) . ': ' . $filePath);
- if(!isset($options['terminate']) || $options['terminate'])
- Yii::app()->end();
+ if (!isset($options['terminate']) || $options['terminate']) {
+ Yii::$app->end();
+ }
}
/**
@@ -148,13 +153,15 @@ class Response extends \yii\base\Response
* @param integer $statusCode the HTTP status code. Defaults to 302. See {@link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html}
* for details about HTTP status code.
*/
- public function redirect($url,$terminate=true,$statusCode=302)
+ public function redirect($url, $terminate = true, $statusCode = 302)
{
- if(strpos($url,'/')===0 && strpos($url,'//')!==0)
- $url=$this->getHostInfo().$url;
- header('Location: '.$url, true, $statusCode);
- if($terminate)
- Yii::app()->end();
+ if (strpos($url, '/') === 0 && strpos($url, '//') !== 0) {
+ $url = Yii::$app->getRequest()->getHostInfo() . $url;
+ }
+ header('Location: ' . $url, true, $statusCode);
+ if ($terminate) {
+ Yii::$app->end();
+ }
}
diff --git a/framework/web/User.php b/framework/web/User.php
index 74b5f18..aa9e421 100644
--- a/framework/web/User.php
+++ b/framework/web/User.php
@@ -9,7 +9,9 @@ namespace yii\web;
use Yii;
use yii\base\Component;
+use yii\base\HttpException;
use yii\base\InvalidConfigException;
+use yii\helpers\Html;
/**
* @author Qiang Xue
@@ -17,15 +19,21 @@ use yii\base\InvalidConfigException;
*/
class User extends Component
{
- const ID_VAR = '__id';
- const AUTH_EXPIRE_VAR = '__expire';
-
const EVENT_BEFORE_LOGIN = 'beforeLogin';
const EVENT_AFTER_LOGIN = 'afterLogin';
const EVENT_BEFORE_LOGOUT = 'beforeLogout';
const EVENT_AFTER_LOGOUT = 'afterLogout';
/**
+ * @var Identity the identity object associated with the currently logged user.
+ * This property is set automatically be the User component. Do not modify it directly
+ * unless you understand the consequence. You should normally use [[login()]], [[logout()]],
+ * or [[switchIdentity()]] to update the identity associated with the current user.
+ *
+ * If this property is null, it means the current user is a guest (not authenticated).
+ */
+ public $identity;
+ /**
* @var string the class name of the [[identity]] object.
*/
public $identityClass;
@@ -64,24 +72,12 @@ class User extends Component
* is initially logged in. When this is true, the identity cookie will expire after the specified duration
* since the user visits the site the last time.
* @see enableAutoLogin
- * @since 1.1.0
- */
- public $autoRenewCookie = false;
- /**
- * @var string value that will be echoed in case that user session has expired during an ajax call.
- * When a request is made and user session has expired, {@link loginRequired} redirects to {@link loginUrl} for login.
- * If that happens during an ajax call, the complete HTML login page is returned as the result of that ajax call. That could be
- * a problem if the ajax call expects the result to be a json array or a predefined string, as the login page is ignored in that case.
- * To solve this, set this property to the desired return value.
- *
- * If this property is set, this value will be returned as the result of the ajax call in case that the user session has expired.
- * @since 1.1.9
- * @see loginRequired
*/
- public $loginRequiredAjaxResponse;
-
+ public $autoRenewCookie = true;
- public $stateVar = '__states';
+ public $idSessionVar = '__id';
+ public $authTimeoutSessionVar = '__expire';
+ public $returnUrlSessionVar = '__returnUrl';
/**
* Initializes the application component.
@@ -99,6 +95,8 @@ class User extends Component
Yii::$app->getSession()->open();
+ $this->loadIdentity();
+
$this->renewAuthStatus();
if ($this->enableAutoLogin) {
@@ -110,29 +108,16 @@ class User extends Component
}
}
- /**
- * @var Identity the identity object associated with the currently logged user.
- */
- private $_identity = false;
-
- public function getIdentity()
+ public function loadIdentity()
{
- if ($this->_identity === false) {
- $id = $this->getId();
- if ($id === null) {
- $this->_identity = null;
- } else {
- /** @var $class Identity */
- $class = $this->identityClass;
- $this->_identity = $class::findIdentity($this->getId());
- }
+ $id = $this->getId();
+ if ($id === null) {
+ $this->identity = null;
+ } else {
+ /** @var $class Identity */
+ $class = $this->identityClass;
+ $this->identity = $class::findIdentity($this->getId());
}
- return $this->_identity;
- }
-
- public function setIdentity($identity)
- {
- $this->switchIdentity($identity);
}
/**
@@ -157,7 +142,7 @@ class User extends Component
if ($this->beforeLogin($identity, false)) {
$this->switchIdentity($identity);
if ($duration > 0 && $this->enableAutoLogin) {
- $this->saveIdentityCookie($identity, $duration);
+ $this->sendIdentityCookie($identity, $duration);
}
$this->afterLogin($identity, false);
}
@@ -169,7 +154,7 @@ class User extends Component
* This method is used when automatic login ({@link enableAutoLogin}) is enabled.
* The user identity information is recovered from cookie.
* Sufficient security measures are used to prevent cookie data from being tampered.
- * @see saveIdentityCookie
+ * @see sendIdentityCookie
*/
protected function loginByCookie()
{
@@ -182,18 +167,16 @@ class User extends Component
/** @var $class Identity */
$class = $this->identityClass;
$identity = $class::findIdentity($id);
- if ($identity === null || !$identity->validateAuthKey($authKey)) {
- if ($identity !== null) {
- Yii::warning("Invalid auth key attempted for user '$id': $authKey", __METHOD__);
+ if ($identity !== null && $identity->validateAuthKey($authKey)) {
+ if ($this->beforeLogin($identity, true)) {
+ $this->switchIdentity($identity);
+ if ($this->autoRenewCookie) {
+ $this->sendIdentityCookie($identity, $duration);
+ }
+ $this->afterLogin($identity, true);
}
- return;
- }
- if ($this->beforeLogin($identity, true)) {
- $this->switchIdentity($identity);
- if ($this->autoRenewCookie) {
- $this->saveIdentityCookie($identity, $duration);
- }
- $this->afterLogin($identity, true);
+ } elseif ($identity !== null) {
+ Yii::warning("Invalid auth key attempted for user '$id': $authKey", __METHOD__);
}
}
}
@@ -208,7 +191,7 @@ class User extends Component
*/
public function logout($destroySession = true)
{
- $identity = $this->getIdentity();
+ $identity = $this->identity;
if ($identity !== null && $this->beforeLogout($identity)) {
$this->switchIdentity(null);
if ($this->enableAutoLogin) {
@@ -227,7 +210,7 @@ class User extends Component
*/
public function getIsGuest()
{
- return $this->getIdentity() === null;
+ return $this->identity === null;
}
/**
@@ -236,7 +219,7 @@ class User extends Component
*/
public function getId()
{
- return $this->getState(static::ID_VAR);
+ return Yii::$app->getSession()->get($this->idSessionVar);
}
/**
@@ -244,7 +227,7 @@ class User extends Component
*/
public function setId($value)
{
- $this->setState(static::ID_VAR, $value);
+ Yii::$app->getSession()->set($this->idSessionVar, $value);
}
/**
@@ -258,12 +241,12 @@ class User extends Component
*/
public function getReturnUrl($defaultUrl = null)
{
- if ($defaultUrl === null) {
- $defaultReturnUrl = Yii::app()->getUrlManager()->showScriptName ? Yii::app()->getRequest()->getScriptUrl() : Yii::app()->getRequest()->getBaseUrl() . '/';
+ $url = Yii::$app->getSession()->get($this->returnUrlSessionVar, $defaultUrl);
+ if ($url === null) {
+ return Yii::$app->getHomeUrl();
} else {
- $defaultReturnUrl = CHtml::normalizeUrl($defaultUrl);
+ return Html::url($url);
}
- return $this->getState('__returnUrl', $defaultReturnUrl);
}
/**
@@ -271,7 +254,7 @@ class User extends Component
*/
public function setReturnUrl($value)
{
- $this->setState('__returnUrl', $value);
+ Yii::$app->getSession()->set($this->returnUrlSessionVar, $value);
}
/**
@@ -285,24 +268,22 @@ class User extends Component
*/
public function loginRequired()
{
- $app = Yii::app();
- $request = $app->getRequest();
-
- if (!$request->getIsAjaxRequest()) {
- $this->setReturnUrl($request->getUrl());
- } elseif (isset($this->loginRequiredAjaxResponse)) {
- echo $this->loginRequiredAjaxResponse;
- Yii::app()->end();
- }
-
if (($url = $this->loginUrl) !== null) {
- if (is_array($url)) {
- $route = isset($url[0]) ? $url[0] : $app->defaultController;
- $url = $app->createUrl($route, array_splice($url, 1));
+ $url = Html::url($url);
+ $request = Yii::$app->getRequest();
+ if (strpos($url, '/') === 0 && strpos($url, '//') !== 0) {
+ $url = $request->getHostInfo() . $url;
+ }
+ if ($request->getIsAjaxRequest()) {
+ echo json_encode(array(
+ 'redirect' => $url,
+ ));
+ Yii::$app->end();
+ } else {
+ Yii::$app->getResponse()->redirect($url);
}
- $request->redirect($url);
} else {
- throw new CHttpException(403, Yii::t('yii', 'Login Required'));
+ throw new HttpException(403, Yii::t('yii|Login Required'));
}
}
@@ -399,7 +380,7 @@ class User extends Component
* @param integer $duration number of seconds that the user can remain in logged-in status. Defaults to 0, meaning login till the user closes the browser.
* @see loginByCookie
*/
- protected function saveIdentityCookie($identity, $duration)
+ protected function sendIdentityCookie($identity, $duration)
{
$cookie = new Cookie($this->identityCookie);
$cookie->value = json_encode(array(
@@ -423,14 +404,16 @@ class User extends Component
protected function switchIdentity($identity)
{
Yii::$app->getSession()->regenerateID(true);
- $this->setIdentity($identity);
+ $this->identity = $identity;
if ($identity instanceof Identity) {
$this->setId($identity->getId());
if ($this->authTimeout !== null) {
- $this->setState(self::AUTH_EXPIRE_VAR, time() + $this->authTimeout);
+ Yii::$app->getSession()->set($this->authTimeoutSessionVar, time() + $this->authTimeout);
}
} else {
- $this->removeAllStates();
+ $session = Yii::$app->getSession();
+ $session->remove($this->idSessionVar);
+ $session->remove($this->authTimeoutSessionVar);
}
}
@@ -442,115 +425,12 @@ class User extends Component
protected function renewAuthStatus()
{
if ($this->authTimeout !== null && !$this->getIsGuest()) {
- $expire = $this->getState(self::AUTH_EXPIRE_VAR);
+ $expire = Yii::$app->getSession()->get($this->authTimeoutSessionVar);
if ($expire !== null && $expire < time()) {
$this->logout(false);
} else {
- $this->setState(self::AUTH_EXPIRE_VAR, time() + $this->authTimeout);
+ Yii::$app->getSession()->set($this->authTimeoutSessionVar, time() + $this->authTimeout);
}
}
}
-
- /**
- * Returns a user state.
- * A user state is a session data item associated with the current user.
- * If the user logs out, all his/her user states will be removed.
- * @param string $key the key identifying the state
- * @param mixed $defaultValue value to be returned if the state does not exist.
- * @return mixed the state
- */
- public function getState($key, $defaultValue = null)
- {
- $manifest = isset($_SESSION[$this->stateVar]) ? $_SESSION[$this->stateVar] : null;
- if (is_array($manifest) && isset($manifest[$key], $_SESSION[$key])) {
- return $_SESSION[$key];
- } else {
- return $defaultValue;
- }
- }
-
- /**
- * Returns all user states.
- * @return array states (key => state).
- */
- public function getAllStates()
- {
- $manifest = isset($_SESSION[$this->stateVar]) ? $_SESSION[$this->stateVar] : null;
- $states = array();
- if (is_array($manifest)) {
- foreach (array_keys($manifest) as $key) {
- if (isset($_SESSION[$key])) {
- $states[$key] = $_SESSION[$key];
- }
- }
- }
- return $states;
- }
-
- /**
- * Stores a user state.
- * A user state is a session data item associated with the current user.
- * If the user logs out, all his/her user states will be removed.
- * @param string $key the key identifying the state. Note that states
- * and normal session variables share the same name space. If you have a normal
- * session variable using the same name, its value will be overwritten by this method.
- * @param mixed $value state
- */
- public function setState($key, $value)
- {
- $manifest = isset($_SESSION[$this->stateVar]) ? $_SESSION[$this->stateVar] : array();
- $manifest[$value] = true;
- $_SESSION[$key] = $value;
- $_SESSION[$this->stateVar] = $manifest;
- }
-
- /**
- * Removes a user state.
- * If the user logs out, all his/her user states will be removed automatically.
- * @param string $key the key identifying the state. Note that states
- * and normal session variables share the same name space. If you have a normal
- * session variable using the same name, it will be removed by this method.
- * @return mixed the removed state. Null if the state does not exist.
- */
- public function removeState($key)
- {
- $manifest = isset($_SESSION[$this->stateVar]) ? $_SESSION[$this->stateVar] : null;
- if (is_array($manifest) && isset($manifest[$key], $_SESSION[$key])) {
- $value = $_SESSION[$key];
- } else {
- $value = null;
- }
- unset($_SESSION[$this->stateVar][$key], $_SESSION[$key]);
- return $value;
- }
-
- /**
- * Removes all states.
- * If the user logs out, all his/her user states will be removed automatically
- * without the need to call this method manually.
- *
- * Note that states and normal session variables share the same name space.
- * If you have a normal session variable using the same name, it will be removed
- * by this method.
- */
- public function removeAllStates()
- {
- $manifest = isset($_SESSION[$this->stateVar]) ? $_SESSION[$this->stateVar] : null;
- if (is_array($manifest)) {
- foreach (array_keys($manifest) as $key) {
- unset($_SESSION[$key]);
- }
- }
- unset($_SESSION[$this->stateVar]);
- }
-
- /**
- * Returns a value indicating whether there is a state associated with the specified key.
- * @param string $key key identifying the state
- * @return boolean whether the specified state exists
- */
- public function hasState($key)
- {
- return $this->getState($key) !== null;
- }
}