Commit ed9f225f by Qiang Xue

...

parent e8b0fd13
...@@ -80,6 +80,10 @@ class Application extends Module ...@@ -80,6 +80,10 @@ class Application extends Module
*/ */
public $name = 'My Application'; public $name = 'My Application';
/** /**
* @var string the version of this application. Defaults to '1.0'.
*/
public $version = '1.0';
/**
* @var string the charset currently used for the application. Defaults to 'UTF-8'. * @var string the charset currently used for the application. Defaults to 'UTF-8'.
*/ */
public $charset = 'UTF-8'; public $charset = 'UTF-8';
...@@ -99,6 +103,11 @@ class Application extends Module ...@@ -99,6 +103,11 @@ class Application extends Module
* @var Controller the currently active controller instance * @var Controller the currently active controller instance
*/ */
public $controller; public $controller;
/**
* @var mixed the layout that should be applied for views in this application. Defaults to 'main'.
* If this is false, layout will be disabled.
*/
public $layout = 'main';
// todo // todo
public $localeDataPath = '@yii/i18n/data'; public $localeDataPath = '@yii/i18n/data';
......
...@@ -69,6 +69,10 @@ class Controller extends Component implements Initable ...@@ -69,6 +69,10 @@ class Controller extends Component implements Initable
* @var Action the action that is currently being executed * @var Action the action that is currently being executed
*/ */
public $action; public $action;
/**
* @var View the view currently being used
*/
private $_view;
/** /**
* @param string $id ID of this controller * @param string $id ID of this controller
...@@ -301,6 +305,12 @@ class Controller extends Component implements Initable ...@@ -301,6 +305,12 @@ class Controller extends Component implements Initable
{ {
if ($this->beforeRender($view)) { if ($this->beforeRender($view)) {
$v = $this->createView(); $v = $this->createView();
if (($theme = \Yii::$application->getTheme()) !== null) {
$v->basePath[] = $theme->getViewPath($this);
$v->rootPath[] = $theme->getViewPath();
}
$v->basePath[] = $this->getViewPath();
$v->rootPath[] = \Yii::$application->getViewPath();
$v->render($view, $params); $v->render($view, $params);
$this->afterRender($view); $this->afterRender($view);
} }
...@@ -317,6 +327,32 @@ class Controller extends Component implements Initable ...@@ -317,6 +327,32 @@ class Controller extends Component implements Initable
} }
public function resolveLayout()
{
$layout = $this->layout;
$module = $this->module;
while ($layout === null && $module !== null) {
$layout = $module->layout;
$module = $module->module;
$layout = $
}
}
public function getView()
{
if ($this->_view === null) {
$this->_view = $this->createView();
$this->_view->owner = $this;
if (($theme = \Yii::$application->getTheme()) !== null) {
$this->_view->basePath[] = $theme->getViewPath($this);
$this->_view->rootPath[] = $theme->getViewPath();
}
$this->_view->basePath[] = $this->getViewPath();
$this->_view->rootPath[] = \Yii::$application->getViewPath();
}
return $this->_view;
}
public function createView() public function createView()
{ {
return new View; return new View;
......
...@@ -50,6 +50,11 @@ class ErrorHandler extends ApplicationComponent ...@@ -50,6 +50,11 @@ class ErrorHandler extends ApplicationComponent
* @var \Exception the exception that is being handled currently * @var \Exception the exception that is being handled currently
*/ */
public $exception; public $exception;
/**
* @var boolean whether to log errors also using error_log(). Defaults to true.
* Note that errors captured by the error handler are always logged by [[\Yii::error()]].
*/
public $logErrors = true;
public function init() public function init()
{ {
...@@ -95,6 +100,20 @@ class ErrorHandler extends ApplicationComponent ...@@ -95,6 +100,20 @@ class ErrorHandler extends ApplicationComponent
// use the most primitive way to display exception thrown in the error view // use the most primitive way to display exception thrown in the error view
$this->renderAsText($e); $this->renderAsText($e);
} }
try {
\Yii::$application->end(1);
} catch (Exception $e2) {
// use the most primitive way to log error occurred in end()
$msg = get_class($e2) . ': ' . $e2->getMessage() . ' (' . $e2->getFile() . ':' . $e2->getLine() . ")\n";
$msg .= $e2->getTraceAsString() . "\n";
$msg .= "Previous error:\n";
$msg .= $e2->getTraceAsString() . "\n";
$msg .= '$_SERVER=' . var_export($_SERVER, true);
error_log($msg);
exit(1);
}
} }
protected function render($exception) protected function render($exception)
...@@ -269,6 +288,9 @@ class ErrorHandler extends ApplicationComponent ...@@ -269,6 +288,9 @@ class ErrorHandler extends ApplicationComponent
$category .= '\\' . $exception->getSeverity(); $category .= '\\' . $exception->getSeverity();
} }
\Yii::error((string)$exception, $category); \Yii::error((string)$exception, $category);
if ($this->logErrors) {
error_log($exception);
}
} }
public function clearOutput() public function clearOutput()
......
...@@ -44,6 +44,12 @@ abstract class Module extends Component implements Initable ...@@ -44,6 +44,12 @@ abstract class Module extends Component implements Initable
*/ */
public $module; public $module;
/** /**
* @var mixed the layout that should be applied for views within this module. This refers to a view name
* relative to [[layoutPath]]. If this is not set, it means the layout value of the [[module|parent module]]
* will be taken. If this is false, layout will be disabled within this module.
*/
public $layout;
/**
* @var array mapping from controller ID to controller configurations. * @var array mapping from controller ID to controller configurations.
* Each name-value pair specifies the configuration of a single controller. * Each name-value pair specifies the configuration of a single controller.
* A controller configuration can be either a string or an array. * A controller configuration can be either a string or an array.
...@@ -73,14 +79,18 @@ abstract class Module extends Component implements Initable ...@@ -73,14 +79,18 @@ abstract class Module extends Component implements Initable
public $defaultRoute = 'default'; public $defaultRoute = 'default';
/** /**
* @var string the root directory of the module. * @var string the root directory of the module.
* @see getBasePath
* @see setBasePath
*/ */
protected $_basePath; protected $_basePath;
/** /**
* @var string the root directory that contains view files.
*/
protected $_viewPath;
/**
* @var string the root directory that contains layout view files.
*/
protected $_layoutPath;
/**
* @var string the directory containing controller classes in the module. * @var string the directory containing controller classes in the module.
* @see getControllerPath
* @see setControllerPath
*/ */
protected $_controllerPath; protected $_controllerPath;
/** /**
...@@ -221,6 +231,56 @@ abstract class Module extends Component implements Initable ...@@ -221,6 +231,56 @@ abstract class Module extends Component implements Initable
} }
/** /**
* @return string the root directory of view files. Defaults to 'moduleDir/views' where
* moduleDir is the directory containing the module class.
*/
public function getViewPath()
{
if ($this->_viewPath !== null) {
return $this->_viewPath;
} else {
return $this->_viewPath = $this->getBasePath() . DIRECTORY_SEPARATOR . 'views';
}
}
/**
* @param string $path the root directory of view files.
* @throws CException if the directory does not exist.
*/
public function setViewPath($path)
{
if (($this->_viewPath = realpath($path)) === false || !is_dir($this->_viewPath)) {
throw new CException(Yii::t('yii', 'The view path "{path}" is not a valid directory.',
array('{path}' => $path)));
}
}
/**
* @return string the root directory of layout files. Defaults to 'moduleDir/views/layouts' where
* moduleDir is the directory containing the module class.
*/
public function getLayoutPath()
{
if ($this->_layoutPath !== null) {
return $this->_layoutPath;
} else {
return $this->_layoutPath = $this->getViewPath() . DIRECTORY_SEPARATOR . 'layouts';
}
}
/**
* @param string $path the root directory of layout files.
* @throws CException if the directory does not exist.
*/
public function setLayoutPath($path)
{
if (($this->_layoutPath = realpath($path)) === false || !is_dir($this->_layoutPath)) {
throw new CException(Yii::t('yii', 'The layout path "{path}" is not a valid directory.',
array('{path}' => $path)));
}
}
/**
* 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()]].
......
...@@ -20,9 +20,9 @@ namespace yii\base; ...@@ -20,9 +20,9 @@ namespace yii\base;
class RenderEvent extends Event class RenderEvent extends Event
{ {
/** /**
* @var Action the action currently being executed * @var string the view currently being rendered
*/ */
public $action; public $view;
/** /**
* @var boolean whether the action is in valid state and its life cycle should proceed. * @var boolean whether the action is in valid state and its life cycle should proceed.
*/ */
...@@ -30,10 +30,10 @@ class RenderEvent extends Event ...@@ -30,10 +30,10 @@ class RenderEvent extends Event
/** /**
* Constructor. * Constructor.
* @param Action $action the action associated with this action event. * @param string $view the view currently being rendered
*/ */
public function __construct(Action $action) public function __construct($view)
{ {
$this->action = $action; $this->view = $view;
} }
} }
...@@ -22,13 +22,22 @@ class View extends Component ...@@ -22,13 +22,22 @@ class View extends Component
*/ */
public $owner; public $owner;
/** /**
* @var string|array the base path where the view file should be looked for using the specified view name. * @var string|array the directories where the view file should be looked for a *relative* view name is given.
* This can be either a string representing a single base path, or an array representing multiple base paths. * This can be either a string representing a single directory, or an array representing multiple directories.
* If the latter, the view file will be looked for in the given base paths in the order they are specified. * If the latter, the view file will be looked for in the given directories in the order they are specified.
* Path aliases can be used. This property must be set before calling [[render()]]. * Path aliases can be used. This property must be set before calling [[render()]] with a relative view name.
* @see roothPath
*/ */
public $basePath; public $basePath;
/** /**
* @var string|array the directories where the view file should be looked for an *absolute* view name is given.
* This can be either a string representing a single directory, or an array representing multiple directories.
* If the latter, the view file will be looked for in the given directories in the order they are specified.
* Path aliases can be used. This property must be set before calling [[render()]] with an absolute view name.
* @see basePath
*/
public $rootPath;
/**
* @var string the language that the view should be rendered in. If not set, it will use * @var string the language that the view should be rendered in. If not set, it will use
* the value of [[Application::language]]. * the value of [[Application::language]].
*/ */
...@@ -255,15 +264,28 @@ class View extends Component ...@@ -255,15 +264,28 @@ class View extends Component
} }
if ($view[0] === '@') { if ($view[0] === '@') {
$file = \Yii::getAlias($view); $file = \Yii::getAlias($view);
} elseif (!empty($this->basePath)) { if ($file === false) {
$basePaths = is_array($this->basePath) ? $this->basePath : array($this->basePath); return false;
foreach ($basePaths as $basePath) { }
$file = \Yii::getAlias($basePath . DIRECTORY_SEPARATOR . $view); } else {
if ($view[0] === '/') {
$paths = $this->rootPath;
$view = substr($view, 1);
} else {
$paths = $this->basePath;
}
if (!empty($paths)) {
if (!is_array($paths)) {
$paths = array($paths);
}
foreach ($paths as $path) {
$file = \Yii::getAlias($path . '/' . $view);
if (is_file($file)) { if (is_file($file)) {
break; break;
} }
} }
} }
}
if (isset($file) && is_file($file)) { if (isset($file) && is_file($file)) {
$file = FileHelper::localize($file, $this->language, $this->sourceLanguage); $file = FileHelper::localize($file, $this->language, $this->sourceLanguage);
return is_file($file) ? $file : false; return is_file($file) ? $file : false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment