Commit e0dd12fb by Alexander Makarov

Merge remote-tracking branch 'origin/master'

parents c6db38ff 7865a56d
......@@ -80,6 +80,10 @@ class Application extends Module
*/
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'.
*/
public $charset = 'UTF-8';
......@@ -99,6 +103,11 @@ class Application extends Module
* @var Controller the currently active controller instance
*/
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
public $localeDataPath = '@yii/i18n/data';
......
......@@ -69,6 +69,10 @@ class Controller extends Component implements Initable
* @var Action the action that is currently being executed
*/
public $action;
/**
* @var View the view currently being used
*/
private $_view;
/**
* @param string $id ID of this controller
......@@ -301,6 +305,12 @@ class Controller extends Component implements Initable
{
if ($this->beforeRender($view)) {
$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);
$this->afterRender($view);
}
......@@ -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()
{
return new View;
......
......@@ -50,6 +50,11 @@ class ErrorHandler extends ApplicationComponent
* @var \Exception the exception that is being handled currently
*/
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()
{
......@@ -95,6 +100,20 @@ class ErrorHandler extends ApplicationComponent
// use the most primitive way to display exception thrown in the error view
$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)
......@@ -269,6 +288,9 @@ class ErrorHandler extends ApplicationComponent
$category .= '\\' . $exception->getSeverity();
}
\Yii::error((string)$exception, $category);
if ($this->logErrors) {
error_log($exception);
}
}
public function clearOutput()
......
......@@ -9,6 +9,8 @@
namespace yii\base;
use yii\util\FileHelper;
/**
* Module is the base class for module and application classes.
*
......@@ -44,6 +46,12 @@ abstract class Module extends Component implements Initable
*/
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.
* Each name-value pair specifies the configuration of a single controller.
* A controller configuration can be either a string or an array.
......@@ -73,14 +81,18 @@ abstract class Module extends Component implements Initable
public $defaultRoute = 'default';
/**
* @var string the root directory of the module.
* @see getBasePath
* @see setBasePath
*/
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.
* @see getControllerPath
* @see setControllerPath
*/
protected $_controllerPath;
/**
......@@ -182,12 +194,7 @@ abstract class Module extends Component implements Initable
*/
public function setBasePath($path)
{
$p = \Yii::getAlias($path);
if ($p === false || !is_dir($p)) {
throw new Exception('Invalid base path: ' . $path);
} else {
$this->_basePath = realpath($p);
}
$this->_basePath = FileHelper::ensureDirectory($path);
}
/**
......@@ -212,15 +219,56 @@ abstract class Module extends Component implements Initable
*/
public function setControllerPath($path)
{
$p = \Yii::getAlias($path);
if ($p === false || !is_dir($p)) {
throw new Exception('Invalid controller path: ' . $path);
$this->_controllerPath = FileHelper::ensureDirectory($path);
}
/**
* @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 {
$this->_controllerPath = realpath($p);
return $this->_viewPath = $this->getBasePath() . DIRECTORY_SEPARATOR . 'views';
}
}
/**
* Sets the directory that contains the view files.
* @param string $path the root directory of view files.
* @throws Exception if the directory is invalid
*/
public function setViewPath($path)
{
$this->_viewPath = FileHelper::ensureDirectory($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';
}
}
/**
* Sets the directory that contains the layout files.
* @param string $path the root directory of layout files.
* @throws Exception if the directory is invalid
*/
public function setLayoutPath($path)
{
$this->_layoutPath = FileHelper::ensureDirectory($path);
}
/**
* Imports the specified path aliases.
* 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()]].
......
......@@ -20,9 +20,9 @@ namespace yii\base;
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.
*/
......@@ -30,10 +30,10 @@ class RenderEvent extends Event
/**
* 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
*/
public $owner;
/**
* @var string|array the base path where the view file should be looked for using the specified view name.
* This can be either a string representing a single base path, or an array representing multiple base paths.
* If the latter, the view file will be looked for in the given base paths in the order they are specified.
* Path aliases can be used. This property must be set before calling [[render()]].
* @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 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 a relative view name.
* @see roothPath
*/
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
* the value of [[Application::language]].
*/
......@@ -255,12 +264,25 @@ class View extends Component
}
if ($view[0] === '@') {
$file = \Yii::getAlias($view);
} elseif (!empty($this->basePath)) {
$basePaths = is_array($this->basePath) ? $this->basePath : array($this->basePath);
foreach ($basePaths as $basePath) {
$file = \Yii::getAlias($basePath . DIRECTORY_SEPARATOR . $view);
if (is_file($file)) {
break;
if ($file === false) {
return false;
}
} 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)) {
break;
}
}
}
}
......
......@@ -9,6 +9,8 @@
namespace yii\util;
use yii\base\Exception;
/**
* Filesystem helper
*
......@@ -30,6 +32,24 @@ class FileHelper
}
/**
* Checks the given path and ensures it is a directory.
* This method will call `realpath()` to "normalize" the given path.
* 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.
* @return string the normalized path
* @throws Exception if the path does not refer to an existing directory.
*/
public static function ensureDirectory($path)
{
$p = \Yii::getAlias($path);
if ($p !== false && ($p = realpath($p)) !== false && is_dir($p)) {
return $p;
} else {
throw new Exception('Directory does not exist: ' . $path);
}
}
/**
* Returns the localized version of a specified file.
*
* The searching is based on the specified language code. In particular,
......
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