Browse Source

refactored logging.

MVC WIP
tags/2.0.0-beta
Qiang Xue 12 years ago
parent
commit
3fa22483c1
  1. 8
      framework/YiiBase.php
  2. 291
      framework/base/Application.php
  3. 209
      framework/base/Controller.php
  4. 21
      framework/base/InvalidRouteException.php
  5. 128
      framework/base/Module.php
  6. 2
      framework/base/View.php
  7. 2
      framework/base/Widget.php
  8. 9
      framework/logging/DbTarget.php
  9. 9
      framework/logging/EmailTarget.php
  10. 25
      framework/logging/FileTarget.php
  11. 33
      framework/logging/Logger.php
  12. 21
      framework/logging/Router.php
  13. 63
      framework/logging/Target.php
  14. 5
      framework/util/FileHelper.php

8
framework/YiiBase.php

@ -121,8 +121,8 @@ class YiiBase
* *
* To import a class or a directory, one can use either path alias or class name (can be namespaced): * To import a class or a directory, one can use either path alias or class name (can be namespaced):
* *
* - `@app/components/GoogleMap`: importing the `GoogleMap` class with a path alias; * - `@application/components/GoogleMap`: importing the `GoogleMap` class with a path alias;
* - `@app/components/*`: importing the whole `components` directory with a path alias; * - `@application/components/*`: importing the whole `components` directory with a path alias;
* - `GoogleMap`: importing the `GoogleMap` class with a class name. [[autoload()]] will be used * - `GoogleMap`: importing the `GoogleMap` class with a class name. [[autoload()]] will be used
* when this class is used for the first time. * when this class is used for the first time.
* *
@ -322,12 +322,12 @@ class YiiBase
* the class. For example, * the class. For example,
* *
* - `\app\components\GoogleMap`: fully-qualified namespaced class. * - `\app\components\GoogleMap`: fully-qualified namespaced class.
* - `@app/components/GoogleMap`: an alias * - `@application/components/GoogleMap`: an alias
* *
* Below are some usage examples: * Below are some usage examples:
* *
* ~~~ * ~~~
* $object = \Yii::createObject('@app/components/GoogleMap'); * $object = \Yii::createObject('@application/components/GoogleMap');
* $object = \Yii::createObject(array( * $object = \Yii::createObject(array(
* 'class' => '\app\components\GoogleMap', * 'class' => '\app\components\GoogleMap',
* 'apiKey' => 'xyz', * 'apiKey' => 'xyz',

291
framework/base/Application.php

@ -10,8 +10,8 @@
namespace yii\base; namespace yii\base;
use Yii; use Yii;
use yii\util\FileHelper;
use yii\base\InvalidCallException; use yii\base\InvalidCallException;
use yii\util\StringHelper;
/** /**
* Application is the base class for all application classes. * Application is the base class for all application classes.
@ -37,7 +37,7 @@ use yii\util\StringHelper;
* Yii framework messages. This application component is dynamically loaded when needed.</li> * Yii framework messages. This application component is dynamically loaded when needed.</li>
* </ul> * </ul>
* *
* Application will undergo the following lifecycles when processing a user request: * Application will undergo the following life cycles when processing a user request:
* <ol> * <ol>
* <li>load application configuration;</li> * <li>load application configuration;</li>
* <li>set up class autoloader and error handling;</li> * <li>set up class autoloader and error handling;</li>
@ -50,28 +50,6 @@ use yii\util\StringHelper;
* Starting from lifecycle 3, if a PHP error or an uncaught exception occurs, * Starting from lifecycle 3, if a PHP error or an uncaught exception occurs,
* the application will switch to its error handling logic and jump to step 6 afterwards. * the application will switch to its error handling logic and jump to step 6 afterwards.
* *
* @property string $basePath Returns the root path of the application.
* @property CCache $cache Returns the cache component.
* @property CPhpMessageSource $coreMessages Returns the core message translations.
* @property CDateFormatter $dateFormatter Returns the locale-dependent date formatter.
* @property \yii\db\Connection $db Returns the database connection component.
* @property CErrorHandler $errorHandler Returns the error handler component.
* @property string $extensionPath Returns the root directory that holds all third-party extensions.
* @property string $id Returns the unique identifier for the application.
* @property string $language Returns the language that the user is using and the application should be targeted to.
* @property CLocale $locale Returns the locale instance.
* @property string $localeDataPath Returns the directory that contains the locale data.
* @property CMessageSource $messages Returns the application message translations component.
* @property CNumberFormatter $numberFormatter The locale-dependent number formatter.
* @property CHttpRequest $request Returns the request component.
* @property string $runtimePath Returns the directory that stores runtime files.
* @property CSecurityManager $securityManager Returns the security manager component.
* @property CStatePersister $statePersister Returns the state persister component.
* @property string $timeZone Returns the time zone used by this application.
* @property UrlManager $urlManager Returns the URL manager component.
* @property string $baseUrl Returns the relative URL for the application
* @property string $homeUrl the homepage URL
*
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
@ -134,7 +112,7 @@ class Application extends Module
$this->setBasePath($basePath); $this->setBasePath($basePath);
$this->registerDefaultAliases(); $this->registerDefaultAliases();
$this->registerCoreComponents(); $this->registerCoreComponents();
parent::__construct($id, $this, $config); Component::__construct($config);
} }
/** /**
@ -204,27 +182,6 @@ class Application extends Module
} }
/** /**
* Runs a controller with the given route and parameters.
* @param string $route the route (e.g. `post/create`)
* @param array $params the parameters to be passed to the controller action
* @return integer the exit status (0 means normal, non-zero values mean abnormal)
* @throws InvalidRequestException if the route cannot be resolved into a controller
*/
public function runController($route, $params = array())
{
$result = $this->createController($route);
if ($result === false) {
throw new InvalidRequestException(Yii::t('yii', 'Unable to resolve the request.'));
}
$priorController = $this->controller;
$this->controller = $controllerObject;
$status = $controllerObject->run($action, $params);
$this->controller = $priorController;
return $status;
}
/**
* Returns the directory that stores runtime files. * Returns the directory that stores runtime files.
* @return string the directory that stores runtime files. Defaults to 'protected/runtime'. * @return string the directory that stores runtime files. Defaults to 'protected/runtime'.
*/ */
@ -239,15 +196,15 @@ class Application extends Module
/** /**
* Sets the directory that stores runtime files. * Sets the directory that stores runtime files.
* @param string $path the directory that stores runtime files. * @param string $path the directory that stores runtime files.
* @throws InvalidCallException if the directory does not exist or is not writable * @throws InvalidConfigException if the directory does not exist or is not writable
*/ */
public function setRuntimePath($path) public function setRuntimePath($path)
{ {
$p = Yii::getAlias($path); $p = FileHelper::ensureDirectory($path);
if ($p === false || !is_dir($p) || !is_writable($path)) { if (is_writable($p)) {
throw new InvalidCallException("Application runtime path \"$path\" is invalid. Please make sure it is a directory writable by the Web server process.");
} else {
$this->_runtimePath = $p; $this->_runtimePath = $p;
} else {
throw new InvalidConfigException("Runtime path must be writable by the Web server process: $path");
} }
} }
@ -296,34 +253,61 @@ class Application extends Module
date_default_timezone_set($value); date_default_timezone_set($value);
} }
/** // /**
* Returns the locale instance. // * Returns the security manager component.
* @param string $localeID the locale ID (e.g. en_US). If null, the {@link getLanguage application language ID} will be used. // * @return SecurityManager the security manager application component.
* @return CLocale the locale instance // */
*/ // public function getSecurityManager()
public function getLocale($localeID = null) // {
{ // return $this->getComponent('securityManager');
return CLocale::getInstance($localeID === null ? $this->getLanguage() : $localeID); // }
} //
// /**
/** // * Returns the locale instance.
* @return CNumberFormatter the locale-dependent number formatter. // * @param string $localeID the locale ID (e.g. en_US). If null, the {@link getLanguage application language ID} will be used.
* The current {@link getLocale application locale} will be used. // * @return CLocale the locale instance
*/ // */
public function getNumberFormatter() // public function getLocale($localeID = null)
{ // {
return $this->getLocale()->getNumberFormatter(); // return CLocale::getInstance($localeID === null ? $this->getLanguage() : $localeID);
} // }
//
/** // /**
* Returns the locale-dependent date formatter. // * @return CNumberFormatter the locale-dependent number formatter.
* @return CDateFormatter the locale-dependent date formatter. // * The current {@link getLocale application locale} will be used.
* The current {@link getLocale application locale} will be used. // */
*/ // public function getNumberFormatter()
public function getDateFormatter() // {
{ // return $this->getLocale()->getNumberFormatter();
return $this->getLocale()->getDateFormatter(); // }
} //
// /**
// * Returns the locale-dependent date formatter.
// * @return CDateFormatter the locale-dependent date formatter.
// * The current {@link getLocale application locale} will be used.
// */
// public function getDateFormatter()
// {
// return $this->getLocale()->getDateFormatter();
// }
//
// /**
// * Returns the core message translations component.
// * @return \yii\i18n\MessageSource the core message translations
// */
// public function getCoreMessages()
// {
// return $this->getComponent('coreMessages');
// }
//
// /**
// * Returns the application message translations component.
// * @return \yii\i18n\MessageSource the application message translations
// */
// public function getMessages()
// {
// return $this->getComponent('messages');
// }
/** /**
* Returns the database connection component. * Returns the database connection component.
@ -353,15 +337,6 @@ class Application extends Module
} }
/** /**
* Returns the security manager component.
* @return SecurityManager the security manager application component.
*/
public function getSecurityManager()
{
return $this->getComponent('securityManager');
}
/**
* Returns the cache component. * Returns the cache component.
* @return \yii\caching\Cache the cache application component. Null if the component is not enabled. * @return \yii\caching\Cache the cache application component. Null if the component is not enabled.
*/ */
@ -371,24 +346,6 @@ class Application extends Module
} }
/** /**
* Returns the core message translations component.
* @return \yii\i18n\MessageSource the core message translations
*/
public function getCoreMessages()
{
return $this->getComponent('coreMessages');
}
/**
* Returns the application message translations component.
* @return \yii\i18n\MessageSource the application message translations
*/
public function getMessages()
{
return $this->getComponent('messages');
}
/**
* Returns the request component. * Returns the request component.
* @return Request the request component * @return Request the request component
*/ */
@ -417,15 +374,6 @@ class Application extends Module
'errorHandler' => array( 'errorHandler' => array(
'class' => 'yii\base\ErrorHandler', 'class' => 'yii\base\ErrorHandler',
), ),
'request' => array(
'class' => 'yii\base\Request',
),
'response' => array(
'class' => 'yii\base\Response',
),
'format' => array(
'class' => 'yii\base\Formatter',
),
'coreMessages' => array( 'coreMessages' => array(
'class' => 'yii\i18n\PhpMessageSource', 'class' => 'yii\i18n\PhpMessageSource',
'language' => 'en_us', 'language' => 'en_us',
@ -442,117 +390,4 @@ class Application extends Module
), ),
)); ));
} }
/**
* Performs a controller action specified by a route.
* This method parses the specified route and creates the corresponding controller and action
* instances under the context of the specified module. It then runs the created action
* with the given parameters.
* @param string $route the route that specifies the action.
* @param array $params the parameters to be passed to the action
* @param Module $module the module which serves as the context of the route
* @return integer the action
* @throws InvalidConfigException if the module's defaultRoute is empty or the controller's defaultAction is empty
* @throws InvalidRequestException if the requested route cannot be resolved into an action successfully
*/
public function runAction($route, $params = array(), $module = null)
{
if ($module === null) {
$module = $this;
}
$route = trim($route, '/');
if ($route === '') {
$route = trim($module->defaultRoute, '/');
if ($route == '') {
throw new InvalidConfigException(get_class($module) . '::defaultRoute cannot be empty.');
}
}
if (($pos = strpos($route, '/')) !== false) {
$id = substr($route, 0, $pos);
$route = substr($route, $pos + 1);
} else {
$id = $route;
$route = '';
}
$childModule = $module->getModule($id);
if ($childModule !== null) {
return $this->runAction($route, $params, $childModule);
}
$controller = $this->createController($id, $module);
if ($controller !== null) {
if ($route === '') {
$route = $controller->defaultAction;
if ($route == '') {
throw new InvalidConfigException(get_class($controller) . '::defaultAction cannot be empty.');
}
}
$action = $this->createAction($route, $controller);
if ($action !== null) {
return $action->runWithParams($params);
}
}
throw new InvalidRequestException("Unable to resolve the request: $route");
}
/**
* Creates a controller instance based on the controller ID.
*
* The controller is created within the given module. The method first attempts to
* create the controller based on the [[controllerMap]] of the module. If not available,
* it will look for the controller class under the [[controllerPath]] and create an
* instance of it.
*
* @param string $id the controller ID
* @param Module $module the module that owns the controller
* @return Controller the newly created controller instance
*/
public function createController($id, $module)
{
if (isset($module->controllerMap[$id])) {
return Yii::createObject($module->controllerMap[$id], $id, $module);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id)) {
$className = StringHelper::id2camel($id) . 'Controller';
$classFile = $module->controllerPath . DIRECTORY_SEPARATOR . $className . '.php';
if (is_file($classFile)) {
$className = $module->controllerNamespace . '\\' . $className;
if (!class_exists($className, false)) {
require($classFile);
}
if (class_exists($className, false) && is_subclass_of($className, '\yii\base\Controller')) {
return new $className($id, $module);
}
}
}
return null;
}
/**
* Creates an action based on the given action ID.
* The action is created within the given controller. The method first attempts to
* create the action based on [[Controller::actions()]]. If not available,
* it will look for the inline action method within the controller.
* @param string $id the action ID
* @param Controller $controller the controller that owns the action
* @return Action the newly created action instance
*/
public function createAction($id, $controller)
{
if (isset($controller->actionMap[$id])) {
return Yii::createObject($controller->actionMap[$id], $id, $controller);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id)) {
$methodName = 'action' . StringHelper::id2camel($id);
if (method_exists($controller, $methodName)) {
$method = new \ReflectionMethod($controller, $methodName);
if ($method->getName() === $methodName) {
return new InlineAction($id, $controller);
}
}
}
return null;
}
} }

209
framework/base/Controller.php

@ -9,6 +9,9 @@
namespace yii\base; namespace yii\base;
use Yii;
use yii\util\StringHelper;
/** /**
* Controller is the base class for classes containing controller logic. * Controller is the base class for classes containing controller logic.
* *
@ -27,6 +30,10 @@ namespace yii\base;
*/ */
class Controller extends Component class Controller extends Component
{ {
const EVENT_AUTHORIZE = 'authorize';
const EVENT_BEFORE_ACTION = 'beforeAction';
const EVENT_AFTER_ACTION = 'afterAction';
/** /**
* @var string the ID of this controller * @var string the ID of this controller
*/ */
@ -91,65 +98,138 @@ class Controller extends Component
} }
/** /**
* Runs the controller with the specified action and parameters. * Runs an action with the specified action ID and parameters.
* @param Action|string $action the action to be executed. This can be either an action object * If the action ID is empty, the method will use [[defaultAction]].
* or the ID of the action. * @param string $id the ID of the action to be executed.
* @param array $params the parameters (name-value pairs) to be passed to the action. * @param array $params the parameters (name-value pairs) to be passed to the action.
* If null, the result of [[getActionParams()]] will be used as action parameters. * @return integer the status of the action execution. 0 means normal, other values mean abnormal.
* @return integer the exit status of the action. 0 means normal, other values mean abnormal. * @throws InvalidRouteException if the requested action ID cannot be resolved into an action successfully.
* @see missingAction
* @see createAction * @see createAction
*/ */
public function run($action, $params = null) public function runAction($id, $params = array())
{ {
if (is_string($action)) { if ($id === '') {
if (($a = $this->createAction($action)) !== null) { $id = $this->defaultAction;
$action = $a;
} else {
$this->missingAction($action);
return 1;
}
} }
$priorAction = $this->action; $action = $this->createAction($id);
if ($action !== null) {
$oldAction = $this->action;
$this->action = $action; $this->action = $action;
if ($this->authorize($action) && $this->beforeAction($action)) { if ($this->authorize($action) && $this->beforeAction($action)) {
if ($params === null) {
$params = $this->getActionParams();
}
$status = $action->runWithParams($params); $status = $action->runWithParams($params);
$this->afterAction($action); $this->afterAction($action);
} else { } else {
$status = 1; $status = 1;
} }
$this->action = $priorAction; $this->action = $oldAction;
return $status; return $status;
} else {
throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $id);
}
} }
/** /**
* Creates the action instance based on the action ID. * Runs a request specified in terms of a route.
* The action can be either an inline action or an object. * The route can be either an ID of an action within this controller or a complete route consisting
* The latter is created by looking up the action map specified in [[actions]]. * of module IDs, controller ID and action ID. If the route starts with a slash '/', the parsing of
* @param string $actionID ID of the action. If empty, it will take the value of [[defaultAction]]. * the route will start from the application; otherwise, it will start from the parent module of this controller.
* @return Action the action instance, null if the action does not exist. * @param string $route the route to be handled, e.g., 'view', 'comment/view', '/admin/comment/view'.
* @see actions * @param array $params the parameters to be passed to the action.
* @return integer the status code returned by the action execution. 0 means normal, and other values mean abnormal.
* @see runAction
* @see forward
*/ */
public function createAction($actionID) public function run($route, $params = array())
{ {
if ($actionID === '') { $pos = strpos($route, '/');
$actionID = $this->defaultAction; if ($pos === false) {
} return $this->runAction($route, $params);
$actions = $this->actions(); } elseif ($pos > 0) {
if (isset($actions[$actionID])) { return $this->module->runAction($route, $params);
return \Yii::createObject($actions[$actionID], $actionID, $this);
} elseif (method_exists($this, 'action' . $actionID)) {
return new InlineAction($actionID, $this);
} else { } else {
return \Yii::$application->runAction($route, $params);
}
}
/**
* Forwards the current execution flow to handle a new request specified by a route.
* The only difference between this method and [[run()]] is that after calling this method,
* the application will exit.
* @param string $route the route to be handled, e.g., 'view', 'comment/view', '/admin/comment/view'.
* @param array $params the parameters to be passed to the action.
* @return integer the status code returned by the action execution. 0 means normal, and other values mean abnormal.
* @see run
*/
public function forward($route, $params = array())
{
$status = $this->run($route, $params);
exit($status);
}
/**
* Creates an action based on the given action ID.
* The method first checks if the action ID has been declared in [[actions()]]. If so,
* it will use the configuration declared there to create the action object.
* If not, it will look for a controller method whose name is in the format of `actionXyz`
* where `Xyz` stands for the action ID. If found, an [[InlineAction]] representing that
* method will be created and returned.
* @param string $id the action ID
* @return Action the newly created action instance. Null if the ID doesn't resolve into any action.
*/
public function createAction($id)
{
$actionMap = $this->actions();
if (isset($actionMap[$id])) {
return Yii::createObject($actionMap[$id], $id, $this);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id)) {
$methodName = 'action' . StringHelper::id2camel($id);
if (method_exists($this, $methodName)) {
$method = new \ReflectionMethod($this, $methodName);
if ($method->getName() === $methodName) {
return new InlineAction($id, $this);
}
}
}
return null; return null;
} }
/**
* This method is invoked when checking the access for the action to be executed.
* @param Action $action the action to be executed.
* @return boolean whether the action is allowed to be executed.
*/
public function authorize($action)
{
$event = new ActionEvent($action);
$this->trigger(self::EVENT_AUTHORIZE, $event);
return $event->isValid;
}
/**
* 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)
{
$event = new ActionEvent($action);
$this->trigger(self::EVENT_BEFORE_ACTION, $event);
return $event->isValid;
}
/**
* This method is invoked right after an action is executed.
* You may override this method to do some postprocessing for the action.
* @param Action $action the action just executed.
*/
public function afterAction($action)
{
$this->trigger(self::EVENT_AFTER_ACTION, new ActionEvent($action));
} }
/** /**
@ -217,67 +297,6 @@ class Controller extends Component
return $this->action !== null ? $this->getUniqueId() . '/' . $this->action->id : $this->getUniqueId(); return $this->action !== null ? $this->getUniqueId() . '/' . $this->action->id : $this->getUniqueId();
} }
/**
* Processes the request using another controller action.
* @param string $route the route of the new controller action. This can be an action ID, or a complete route
* with module ID (optional in the current module), controller ID and action ID. If the former,
* the action is assumed to be located within the current controller.
* @param array $params the parameters to be passed to the action.
* If null, the result of [[getActionParams()]] will be used as action parameters.
* Note that the parameters must be name-value pairs with the names corresponding to
* the parameter names as declared by the action.
* @param boolean $exit whether to end the application after this call. Defaults to true.
*/
public function forward($route, $params = array(), $exit = true)
{
if (strpos($route, '/') === false) {
$status = $this->run($route, $params);
} else {
if ($route[0] !== '/' && !$this->module instanceof Application) {
$route = '/' . $this->module->getUniqueId() . '/' . $route;
}
$status = \Yii::$application->runController($route, $params);
}
if ($exit) {
\Yii::$application->end($status);
}
}
/**
* This method is invoked when checking the access for the action to be executed.
* @param Action $action the action to be executed.
* @return boolean whether the action is allowed to be executed.
*/
public function authorize($action)
{
$event = new ActionEvent($action);
$this->trigger(__METHOD__, $event);
return $event->isValid;
}
/**
* 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)
{
$event = new ActionEvent($action);
$this->trigger(__METHOD__, $event);
return $event->isValid;
}
/**
* This method is invoked right after an action is executed.
* You may override this method to do some postprocessing for the action.
* @param Action $action the action just executed.
*/
public function afterAction($action)
{
$this->trigger(__METHOD__, new ActionEvent($action));
}
public function render($view, $params = array()) public function render($view, $params = array())
{ {
return $this->createView()->render($view, $params); return $this->createView()->render($view, $params);

21
framework/base/InvalidRouteException.php

@ -0,0 +1,21 @@
<?php
/**
* InvalidRouteException class file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\base;
/**
* InvalidRouteException represents an exception caused by an invalid route.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class InvalidRouteException extends \Exception
{
}

128
framework/base/Module.php

@ -16,13 +16,19 @@ use yii\util\FileHelper;
/** /**
* Module is the base class for module and application classes. * Module is the base class for module and application classes.
* *
* Module mainly manages application components and sub-modules that belongs to a module. * A module represents a sub-application which contains MVC elements by itself, such as
* models, views, controllers, etc.
*
* A module may consist of [[modules|sub-modules]].
*
* [[components|Components]] may be registered with the module so that they are globally
* accessible within the module.
* *
* @property string $uniqueId An ID that uniquely identifies this module among all modules within * @property string $uniqueId An ID that uniquely identifies this module among all modules within
* the current application. * the current application.
* @property string $basePath The root directory of the module. Defaults to the directory containing the module class. * @property string $basePath The root directory of the module. Defaults to the directory containing the module class.
* @property array $modules The configuration of the currently installed modules (module ID => configuration). * @property array $modules The configuration of the currently installed modules (module ID => configuration).
* @property array $components The application components (indexed by their IDs). * @property array $components The components (indexed by their IDs) registered within this module.
* @property array $import List of aliases to be imported. This property is write-only. * @property array $import List of aliases to be imported. This property is write-only.
* @property array $aliases List of aliases to be defined. This property is write-only. * @property array $aliases List of aliases to be defined. This property is write-only.
* *
@ -36,7 +42,7 @@ abstract class Module extends Component
*/ */
public $params = array(); public $params = array();
/** /**
* @var array the IDs of the application components that should be preloaded when this module is created. * @var array the IDs of the components that should be preloaded when this module is created.
*/ */
public $preload = array(); public $preload = array();
/** /**
@ -88,27 +94,27 @@ abstract class Module extends Component
/** /**
* @var string the root directory of the module. * @var string the root directory of the module.
*/ */
protected $_basePath; private $_basePath;
/** /**
* @var string the root directory that contains view files for this module * @var string the root directory that contains view files for this module
*/ */
protected $_viewPath; private $_viewPath;
/** /**
* @var string the root directory that contains layout view files for this module. * @var string the root directory that contains layout view files for this module.
*/ */
protected $_layoutPath; private $_layoutPath;
/** /**
* @var string the directory containing controller classes in the module. * @var string the directory containing controller classes in the module.
*/ */
protected $_controllerPath; private $_controllerPath;
/** /**
* @var array child modules of this module * @var array child modules of this module
*/ */
protected $_modules = array(); private $_modules = array();
/** /**
* @var array application components of this module * @var array components registered under this module
*/ */
protected $_components = array(); private $_components = array();
/** /**
* Constructor. * Constructor.
@ -125,9 +131,9 @@ abstract class Module extends Component
/** /**
* Getter magic method. * Getter magic method.
* This method is overridden to support accessing application components * This method is overridden to support accessing components
* like reading module properties. * like reading module properties.
* @param string $name application component or property name * @param string $name component or property name
* @return mixed the named property value * @return mixed the named property value
*/ */
public function __get($name) public function __get($name)
@ -142,7 +148,7 @@ abstract class Module extends Component
/** /**
* Checks if a property value is null. * Checks if a property value is null.
* This method overrides the parent implementation by checking * This method overrides the parent implementation by checking
* if the named application component is loaded. * if the named component is loaded.
* @param string $name the property name or the event name * @param string $name the property name or the event name
* @return boolean whether the property value is null * @return boolean whether the property value is null
*/ */
@ -163,7 +169,7 @@ abstract class Module extends Component
*/ */
public function init() public function init()
{ {
\Yii::setAlias('@' . $this->id, $this->getBasePath()); Yii::setAlias('@' . $this->id, $this->getBasePath());
$this->preloadComponents(); $this->preloadComponents();
} }
@ -282,19 +288,19 @@ abstract class Module extends Component
/** /**
* Imports the specified path aliases. * Imports the specified path aliases.
* This method is provided so that you can import a set of path aliases when configuring a module. * This method is provided so that you can import a set of path aliases when configuring a module.
* The path aliases will be imported by calling [[\Yii::import()]]. * The path aliases will be imported by calling [[Yii::import()]].
* @param array $aliases list of path aliases to be imported * @param array $aliases list of path aliases to be imported
*/ */
public function setImport($aliases) public function setImport($aliases)
{ {
foreach ($aliases as $alias) { foreach ($aliases as $alias) {
\Yii::import($alias); Yii::import($alias);
} }
} }
/** /**
* Defines path aliases. * Defines path aliases.
* This method calls [[\Yii::setAlias()]] to register the path aliases. * This method calls [[Yii::setAlias()]] to register the path aliases.
* This method is provided so that you can define path aliases when configuring a module. * This method is provided so that you can define path aliases when configuring a module.
* @param array $aliases list of path aliases to be defined. The array keys are alias names * @param array $aliases list of path aliases to be defined. The array keys are alias names
* (must start with '@') and the array values are the corresponding paths or aliases. * (must start with '@') and the array values are the corresponding paths or aliases.
@ -302,7 +308,7 @@ abstract class Module extends Component
* *
* ~~~ * ~~~
* array( * array(
* '@models' => '@app/models', // an existing alias * '@models' => '@application/models', // an existing alias
* '@backend' => __DIR__ . '/../backend', // a directory * '@backend' => __DIR__ . '/../backend', // a directory
* ) * )
* ~~~ * ~~~
@ -310,7 +316,7 @@ abstract class Module extends Component
public function setAliases($aliases) public function setAliases($aliases)
{ {
foreach ($aliases as $name => $alias) { foreach ($aliases as $name => $alias) {
\Yii::setAlias($name, $alias); Yii::setAlias($name, $alias);
} }
} }
@ -339,8 +345,8 @@ abstract class Module extends Component
if ($this->_modules[$id] instanceof Module) { if ($this->_modules[$id] instanceof Module) {
return $this->_modules[$id]; return $this->_modules[$id];
} elseif ($load) { } elseif ($load) {
\Yii::trace("Loading \"$id\" module", __CLASS__); Yii::trace("Loading module: $id", __CLASS__);
return $this->_modules[$id] = \Yii::createObject($this->_modules[$id], $id, $this); return $this->_modules[$id] = Yii::createObject($this->_modules[$id], $id, $this);
} }
} }
return null; return null;
@ -393,7 +399,7 @@ abstract class Module extends Component
* *
* Each sub-module should be specified as a name-value pair, where * Each sub-module should be specified as a name-value pair, where
* name refers to the ID of the module and value the module or a configuration * name refers to the ID of the module and value the module or a configuration
* array that can be used to create the module. In the latter case, [[\Yii::createObject()]] * array that can be used to create the module. In the latter case, [[Yii::createObject()]]
* will be used to create the module. * will be used to create the module.
* *
* If a new sub-module has the same ID as an existing one, the existing one will be overwritten silently. * If a new sub-module has the same ID as an existing one, the existing one will be overwritten silently.
@ -423,8 +429,8 @@ abstract class Module extends Component
/** /**
* Checks whether the named component exists. * Checks whether the named component exists.
* @param string $id application component ID * @param string $id component ID
* @return boolean whether the named application component exists. Both loaded and unloaded components * @return boolean whether the named component exists. Both loaded and unloaded components
* are considered. * are considered.
*/ */
public function hasComponent($id) public function hasComponent($id)
@ -433,11 +439,10 @@ abstract class Module extends Component
} }
/** /**
* Retrieves the named application component. * Retrieves the named component.
* @param string $id application component ID (case-sensitive) * @param string $id component ID (case-sensitive)
* @param boolean $load whether to load the component if it is not yet loaded. * @param boolean $load whether to load the component if it is not yet loaded.
* @return Component|null the application component instance, null if the application component * @return Component|null the component instance, null if the component does not exist.
* does not exist.
* @see hasComponent() * @see hasComponent()
*/ */
public function getComponent($id, $load = true) public function getComponent($id, $load = true)
@ -446,22 +451,22 @@ abstract class Module extends Component
if ($this->_components[$id] instanceof Component) { if ($this->_components[$id] instanceof Component) {
return $this->_components[$id]; return $this->_components[$id];
} elseif ($load) { } elseif ($load) {
\Yii::trace("Loading \"$id\" application component", __CLASS__); Yii::trace("Loading component: $id", __CLASS__);
return $this->_components[$id] = \Yii::createObject($this->_components[$id]); return $this->_components[$id] = Yii::createObject($this->_components[$id]);
} }
} }
return null; return null;
} }
/** /**
* Registers an application component in this module. * Registers a component with this module.
* @param string $id component ID * @param string $id component ID
* @param Component|array|null $component the component to be added to the module. This can * @param Component|array|null $component the component to be registered with the module. This can
* be one of the followings: * be one of the followings:
* *
* - a [[Component]] object * - a [[Component]] object
* - a configuration array: when [[getComponent()]] is called initially for this component, the array * - a configuration array: when [[getComponent()]] is called initially for this component, the array
* will be used to instantiate the component * will be used to instantiate the component via [[Yii::createObject()]].
* - null: the named component will be removed from the module * - null: the named component will be removed from the module
*/ */
public function setComponent($id, $component) public function setComponent($id, $component)
@ -474,11 +479,11 @@ abstract class Module extends Component
} }
/** /**
* Returns the application components. * Returns the registered components.
* @param boolean $loadedOnly whether to return the loaded components only. If this is set false, * @param boolean $loadedOnly whether to return the loaded components only. If this is set false,
* then all components specified in the configuration will be returned, whether they are loaded or not. * then all components specified in the configuration will be returned, whether they are loaded or not.
* Loaded components will be returned as objects, while unloaded components as configuration arrays. * Loaded components will be returned as objects, while unloaded components as configuration arrays.
* @return array the application components (indexed by their IDs) * @return array the components (indexed by their IDs)
*/ */
public function getComponents($loadedOnly = false) public function getComponents($loadedOnly = false)
{ {
@ -496,11 +501,11 @@ abstract class Module extends Component
} }
/** /**
* Registers a set of application components in this module. * Registers a set of components in this module.
* *
* Each application component should be specified as a name-value pair, where * Each component should be specified as a name-value pair, where
* name refers to the ID of the component and value the component or a configuration * name refers to the ID of the component and value the component or a configuration
* array that can be used to create the component. In the latter case, [[\Yii::createObject()]] * array that can be used to create the component. In the latter case, [[Yii::createObject()]]
* will be used to create the component. * will be used to create the component.
* *
* If a new component has the same ID as an existing one, the existing one will be overwritten silently. * If a new component has the same ID as an existing one, the existing one will be overwritten silently.
@ -520,7 +525,7 @@ abstract class Module extends Component
* ) * )
* ~~~ * ~~~
* *
* @param array $components application components (id => component configuration or instance) * @param array $components components (id => component configuration or instance)
*/ */
public function setComponents($components) public function setComponents($components)
{ {
@ -530,7 +535,7 @@ abstract class Module extends Component
} }
/** /**
* Loads application components that are declared in [[preload]]. * Loads components that are declared in [[preload]].
*/ */
public function preloadComponents() public function preloadComponents()
{ {
@ -540,54 +545,47 @@ abstract class Module extends Component
} }
/** /**
* Performs a controller action specified by a route. * Runs a controller action specified by a route.
* This method parses the specified route and creates the corresponding controller and action * This method parses the specified route and creates the corresponding child module(s), controller and action
* instances under the context of the specified module. It then runs the created action * instances. It then calls [[Controller::runAction()]] to run the action with the given parameters.
* with the given parameters. * If the route is empty, the method will use [[defaultRoute]].
* @param string $route the route that specifies the action. * @param string $route the route that specifies the action.
* @param array $params the parameters to be passed to the action * @param array $params the parameters to be passed to the action
* @return integer the action * @return integer the status code returned by the action execution. 0 means normal, and other values mean abnormal.
* @throws InvalidConfigException if the module's defaultRoute is empty or the controller's defaultAction is empty * @throws InvalidRouteException if the requested route cannot be resolved into an action successfully
* @throws InvalidRequestException if the requested route cannot be resolved into an action successfully
*/ */
public function runAction($route, $params = array()) public function runAction($route, $params = array())
{ {
$route = trim($route, '/'); $route = trim($route, '/');
if ($route === '') { if ($route === '') {
$route = trim($this->defaultRoute, '/'); $route = trim($this->defaultRoute, '/');
if ($route == '') {
throw new InvalidConfigException(get_class($this) . '::defaultRoute cannot be empty.');
}
} }
if (($pos = strpos($route, '/')) !== false) { if (($pos = strpos($route, '/')) !== false) {
$id = substr($route, 0, $pos); $id = substr($route, 0, $pos);
$route = substr($route, $pos + 1); $route2 = substr($route, $pos + 1);
} else { } else {
$id = $route; $id = $route;
$route = ''; $route2 = '';
} }
$module = $this->getModule($id); $module = $this->getModule($id);
if ($module !== null) { if ($module !== null) {
return $module->runAction($route, $params); return $module->runAction($route2, $params);
} }
$controller = $this->createController($id); $controller = $this->createController($id);
if ($controller !== null) { if ($controller !== null) {
if ($route === '') { $oldController = Yii::$application->controller;
$route = $controller->defaultAction; Yii::$application->controller = $controller;
if ($route == '') {
throw new InvalidConfigException(get_class($controller) . '::defaultAction cannot be empty.');
}
}
$action = $controller->createAction($route); $status = $controller->runAction($route2, $params);
if ($action !== null) {
return $action->runWithParams($params);
}
}
throw new InvalidRequestException('Unable to resolve the request: ' . ltrim($this->getUniqueId() . '/' . $route, '/')); Yii::$application->controller = $oldController;
return $status;
} else {
throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $route);
}
} }
/** /**

2
framework/base/View.php

@ -97,7 +97,7 @@ class View extends Component
* To determine which view file should be rendered, the method calls [[findViewFile()]] which * To determine which view file should be rendered, the method calls [[findViewFile()]] which
* will search in the directories as specified by [[basePath]]. * will search in the directories as specified by [[basePath]].
* *
* View name can be a path alias representing an absolute file path (e.g. `@app/views/layout/index`), * View name can be a path alias representing an absolute file path (e.g. `@application/views/layout/index`),
* or a path relative to [[basePath]]. The file suffix is optional and defaults to `.php` if not given * or a path relative to [[basePath]]. The file suffix is optional and defaults to `.php` if not given
* in the view name. * in the view name.
* *

2
framework/base/Widget.php

@ -80,7 +80,7 @@ class Widget extends Component
* To determine which view file should be rendered, the method calls [[findViewFile()]] which * To determine which view file should be rendered, the method calls [[findViewFile()]] which
* will search in the directories as specified by [[basePath]]. * will search in the directories as specified by [[basePath]].
* *
* View name can be a path alias representing an absolute file path (e.g. `@app/views/layout/index`), * View name can be a path alias representing an absolute file path (e.g. `@application/views/layout/index`),
* or a path relative to [[basePath]]. The file suffix is optional and defaults to `.php` if not given * or a path relative to [[basePath]]. The file suffix is optional and defaults to `.php` if not given
* in the view name. * in the view name.
* *

9
framework/logging/DbTarget.php

@ -89,16 +89,17 @@ class DbTarget extends Target
} }
/** /**
* Stores log [[messages]] to DB. * Stores log messages to DB.
* @param boolean $final whether this method is called at the end of the current application * @param array $messages the messages to be exported. See [[Logger::messages]] for the structure
* of each message.
*/ */
public function exportMessages($final) public function export($messages)
{ {
$db = $this->getDb(); $db = $this->getDb();
$tableName = $db->quoteTableName($this->tableName); $tableName = $db->quoteTableName($this->tableName);
$sql = "INSERT INTO $tableName (level, category, log_time, message) VALUES (:level, :category, :log_time, :message)"; $sql = "INSERT INTO $tableName (level, category, log_time, message) VALUES (:level, :category, :log_time, :message)";
$command = $db->createCommand($sql); $command = $db->createCommand($sql);
foreach ($this->messages as $message) { foreach ($messages as $message) {
$command->bindValues(array( $command->bindValues(array(
':level' => $message[1], ':level' => $message[1],
':category' => $message[2], ':category' => $message[2],

9
framework/logging/EmailTarget.php

@ -39,13 +39,14 @@ class EmailTarget extends Target
public $headers = array(); public $headers = array();
/** /**
* Sends log [[messages]] to specified email addresses. * Sends log messages to specified email addresses.
* @param boolean $final whether this method is called at the end of the current application * @param array $messages the messages to be exported. See [[Logger::messages]] for the structure
* of each message.
*/ */
public function exportMessages($final) public function export($messages)
{ {
$body = ''; $body = '';
foreach ($this->messages as $message) { foreach ($messages as $message) {
$body .= $this->formatMessage($message); $body .= $this->formatMessage($message);
} }
$body = wordwrap($body, 70); $body = wordwrap($body, 70);

25
framework/logging/FileTarget.php

@ -65,19 +65,28 @@ class FileTarget extends Target
} }
/** /**
* Sends log [[messages]] to specified email addresses. * Sends log messages to specified email addresses.
* @param boolean $final whether this method is called at the end of the current application * @param array $messages the messages to be exported. See [[Logger::messages]] for the structure
* of each message.
*/ */
public function exportMessages($final) public function export($messages)
{ {
$text = '';
foreach ($messages as $message) {
$text .= $this->formatMessage($message);
}
$fp = @fopen($this->logFile, 'a');
@flock($fp, LOCK_EX);
if (@filesize($this->logFile) > $this->maxFileSize * 1024) { if (@filesize($this->logFile) > $this->maxFileSize * 1024) {
$this->rotateFiles(); $this->rotateFiles();
@flock($fp,LOCK_UN);
@fclose($fp);
@file_put_contents($this->logFile, $text, FILE_APPEND | LOCK_EX);
} else {
@fwrite($fp, $text);
@flock($fp,LOCK_UN);
@fclose($fp);
} }
$messages = array();
foreach ($this->messages as $message) {
$messages[] = $this->formatMessage($message);
}
@file_put_contents($this->logFile, implode('', $messages), FILE_APPEND | LOCK_EX);
} }
/** /**

33
framework/logging/Logger.php

@ -8,16 +8,13 @@
*/ */
namespace yii\logging; namespace yii\logging;
use yii\base\InvalidConfigException;
use yii\base\Event;
use yii\base\Exception;
/** /**
* Logger records logged messages in memory. * Logger records logged messages in memory.
* *
* When [[flushInterval()]] is reached or when application terminates, it will * When the application ends or [[flushInterval]] is reached, Logger will call [[flush()]]
* call [[flush()]] to send logged messages to different log targets, such as * to send logged messages to different log targets, such as file, email, Web.
* file, email, Web.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
@ -25,15 +22,6 @@ use yii\base\Exception;
class Logger extends \yii\base\Component class Logger extends \yii\base\Component
{ {
/** /**
* @event Event an event that is triggered when [[flush()]] is called.
*/
const EVENT_FLUSH = 'flush';
/**
* @event Event an event that is triggered when [[flush()]] is called at the end of application.
*/
const EVENT_FINAL_FLUSH = 'finalFlush';
/**
* Error message level. An error message is one that indicates the abnormal termination of the * Error message level. An error message is one that indicates the abnormal termination of the
* application and may require developer's handling. * application and may require developer's handling.
*/ */
@ -82,7 +70,7 @@ class Logger extends \yii\base\Component
* *
* ~~~ * ~~~
* array( * array(
* [0] => message (mixed) * [0] => message (mixed, can be a string or some complex data, such as an exception object)
* [1] => level (integer) * [1] => level (integer)
* [2] => category (string) * [2] => category (string)
* [3] => timestamp (float, obtained by microtime(true)) * [3] => timestamp (float, obtained by microtime(true))
@ -90,6 +78,10 @@ class Logger extends \yii\base\Component
* ~~~ * ~~~
*/ */
public $messages = array(); public $messages = array();
/**
* @var Router the log target router registered with this logger.
*/
public $router;
/** /**
* Initializes the logger by registering [[flush()]] as a shutdown function. * Initializes the logger by registering [[flush()]] as a shutdown function.
@ -138,7 +130,9 @@ class Logger extends \yii\base\Component
*/ */
public function flush($final = false) public function flush($final = false)
{ {
$this->trigger($final ? self::EVENT_FINAL_FLUSH : self::EVENT_FLUSH); if ($this->router) {
$this->router->dispatch($this->messages, $final);
}
$this->messages = array(); $this->messages = array();
} }
@ -149,7 +143,7 @@ class Logger extends \yii\base\Component
* of [[YiiBase]] class file. * of [[YiiBase]] class file.
* @return float the total elapsed time in seconds for current request. * @return float the total elapsed time in seconds for current request.
*/ */
public function getExecutionTime() public function getElapsedTime()
{ {
return microtime(true) - YII_BEGIN_TIME; return microtime(true) - YII_BEGIN_TIME;
} }
@ -218,7 +212,7 @@ class Logger extends \yii\base\Component
if (($last = array_pop($stack)) !== null && $last[0] === $token) { if (($last = array_pop($stack)) !== null && $last[0] === $token) {
$timings[] = array($token, $category, $timestamp - $last[3]); $timings[] = array($token, $category, $timestamp - $last[3]);
} else { } else {
throw new Exception("Unmatched profiling block: $token"); throw new InvalidConfigException("Unmatched profiling block: $token");
} }
} }
} }
@ -231,5 +225,4 @@ class Logger extends \yii\base\Component
return $timings; return $timings;
} }
} }

21
framework/logging/Router.php

@ -81,26 +81,21 @@ class Router extends Component
$this->targets[$name] = Yii::createObject($target); $this->targets[$name] = Yii::createObject($target);
} }
} }
Yii::getLogger()->router = $this;
Yii::getLogger()->on(Logger::EVENT_FLUSH, array($this, 'processMessages'));
Yii::getLogger()->on(Logger::EVENT_FINAL_FLUSH, array($this, 'processMessages'));
} }
/** /**
* Retrieves and processes log messages from the system logger. * Dispatches log messages to [[targets]].
* This method mainly serves the event handler to the [[Logger::EVENT_FLUSH]] event * This method is called by [[Logger]] when its [[Logger::flush()]] method is called.
* and the [[Logger::EVENT_FINAL_FLUSH]] event. * It will forward the messages to each log target registered in [[targets]].
* It will retrieve the available log messages from the [[Yii::getLogger()|system logger]] * @param array $messages the messages to be processed
* and invoke the registered [[targets|log targets]] to do the actual processing. * @param boolean $final whether this is the final call during a request cycle
* @param \yii\base\Event $event event parameter
*/ */
public function processMessages($event) public function dispatch($messages, $final = false)
{ {
$messages = Yii::getLogger()->messages;
$final = $event->name === Logger::EVENT_FINAL_FLUSH;
foreach ($this->targets as $target) { foreach ($this->targets as $target) {
if ($target->enabled) { if ($target->enabled) {
$target->processMessages($messages, $final); $target->collect($messages, $final);
} }
} }
} }

63
framework/logging/Target.php

@ -50,15 +50,6 @@ abstract class Target extends \yii\base\Component
*/ */
public $except = array(); public $except = array();
/** /**
* @var boolean whether to prefix each log message with the current session ID. Defaults to false.
*/
public $prefixSession = false;
/**
* @var boolean whether to prefix each log message with the current user name and ID. Defaults to false.
* @see \yii\web\User
*/
public $prefixUser = false;
/**
* @var boolean whether to log a message containing the current user name and ID. Defaults to false. * @var boolean whether to log a message containing the current user name and ID. Defaults to false.
* @see \yii\web\User * @see \yii\web\User
*/ */
@ -77,19 +68,18 @@ abstract class Target extends \yii\base\Component
public $exportInterval = 1000; public $exportInterval = 1000;
/** /**
* @var array the messages that are retrieved from the logger so far by this log target. * @var array the messages that are retrieved from the logger so far by this log target.
* @see autoExport
*/ */
public $messages = array(); private $_messages = array();
private $_levels = 0; private $_levels = 0;
/** /**
* Exports log messages to a specific destination. * Exports log messages to a specific destination.
* Child classes must implement this method. Note that you may need * Child classes must implement this method.
* to clean up [[messages]] in this method to avoid re-exporting messages. * @param array $messages the messages to be exported. See [[Logger::messages]] for the structure
* @param boolean $final whether this method is called at the end of the current application * of each message.
*/ */
abstract public function exportMessages($final); abstract public function export($messages);
/** /**
* Processes the given log messages. * Processes the given log messages.
@ -99,45 +89,16 @@ abstract class Target extends \yii\base\Component
* of each message. * of each message.
* @param boolean $final whether this method is called at the end of the current application * @param boolean $final whether this method is called at the end of the current application
*/ */
public function processMessages($messages, $final) public function collect($messages, $final)
{ {
$messages = $this->filterMessages($messages); $this->_messages = array($this->_messages, $this->filterMessages($messages));
$this->messages = array_merge($this->messages, $messages); $count = count($this->_messages);
$count = count($this->messages);
if ($count > 0 && ($final || $this->exportInterval > 0 && $count >= $this->exportInterval)) { if ($count > 0 && ($final || $this->exportInterval > 0 && $count >= $this->exportInterval)) {
$this->prepareExport($final); if (($context = $this->getContextMessage()) !== '') {
$this->exportMessages($final); $this->_messages[] = array($context, Logger::LEVEL_INFO, 'application', YII_BEGIN_TIME);
$this->messages = array();
}
}
/**
* Prepares the [[messages]] for exporting.
* This method will modify each message by prepending extra information
* if [[prefixSession]] and/or [[prefixUser]] are set true.
* It will also add an additional message showing context information if
* [[logUser]] and/or [[logVars]] are set.
* @param boolean $final whether this method is called at the end of the current application
*/
protected function prepareExport($final)
{
$prefix = array();
if ($this->prefixSession && ($id = session_id()) !== '') {
$prefix[] = "[$id]";
}
if ($this->prefixUser && ($user = \Yii::$application->getComponent('user', false)) !== null) {
$prefix[] = '[' . $user->getName() . ']';
$prefix[] = '[' . $user->getId() . ']';
}
if ($prefix !== array()) {
$prefix = implode(' ', $prefix);
foreach ($this->messages as $i => $message) {
$this->messages[$i][0] = $prefix . ' ' . $this->messages[$i][0];
}
} }
if ($final && ($context = $this->getContextMessage()) !== '') { $this->export($this->_messages);
$this->messages[] = array($context, Logger::LEVEL_INFO, 'application', YII_BEGIN_TIME); $this->_messages = array();
} }
} }

5
framework/util/FileHelper.php

@ -10,6 +10,7 @@
namespace yii\util; namespace yii\util;
use yii\base\Exception; use yii\base\Exception;
use yii\base\InvalidConfigException;
/** /**
* Filesystem helper * Filesystem helper
@ -37,7 +38,7 @@ class FileHelper
* If the given path does not refer to an existing directory, an exception will be thrown. * If the given path does not refer to an existing directory, an exception will be thrown.
* @param string $path the given path. This can also be a path alias. * @param string $path the given path. This can also be a path alias.
* @return string the normalized path * @return string the normalized path
* @throws Exception if the path does not refer to an existing directory. * @throws InvalidConfigException if the path does not refer to an existing directory.
*/ */
public static function ensureDirectory($path) public static function ensureDirectory($path)
{ {
@ -45,7 +46,7 @@ class FileHelper
if ($p !== false && ($p = realpath($p)) !== false && is_dir($p)) { if ($p !== false && ($p = realpath($p)) !== false && is_dir($p)) {
return $p; return $p;
} else { } else {
throw new Exception('Directory does not exist: ' . $path); throw new InvalidConfigException('Directory does not exist: ' . $path);
} }
} }

Loading…
Cancel
Save