Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
bd320533
Commit
bd320533
authored
Jan 30, 2013
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MVC WIP
parent
9165a159
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
273 additions
and
193 deletions
+273
-193
YiiBase.php
framework/YiiBase.php
+7
-12
Controller.php
framework/base/Controller.php
+11
-0
ErrorHandler.php
framework/base/ErrorHandler.php
+1
-1
Theme.php
framework/base/Theme.php
+82
-23
View.php
framework/base/View.php
+145
-157
Widget.php
framework/base/Widget.php
+13
-0
FileHelper.php
framework/util/FileHelper.php
+14
-0
No files found.
framework/YiiBase.php
View file @
bd320533
...
...
@@ -8,9 +8,8 @@
*/
use
yii\base\Exception
;
use
yii\logging\Logger
;
use
yii\base\InvalidCallException
;
use
yii\base\InvalidConfigException
;
use
yii\logging\Logger
;
/**
* Gets the application start timestamp.
...
...
@@ -189,14 +188,14 @@ class YiiBase
*
* Note, this method does not ensure the existence of the resulting path.
* @param string $alias alias
* @param boolean $throwException whether to throw exception if the alias is invalid.
* @return string|boolean path corresponding to the alias, false if the root alias is not previously registered.
* @throws Exception if the alias is invalid and $throwException is true.
* @see setAlias
*/
public
static
function
getAlias
(
$alias
,
$throwException
=
false
)
public
static
function
getAlias
(
$alias
)
{
if
(
isset
(
self
::
$aliases
[
$alias
]))
{
if
(
!
is_string
(
$alias
))
{
return
false
;
}
elseif
(
isset
(
self
::
$aliases
[
$alias
]))
{
return
self
::
$aliases
[
$alias
];
}
elseif
(
$alias
===
''
||
$alias
[
0
]
!==
'@'
)
{
// not an alias
return
$alias
;
...
...
@@ -206,11 +205,7 @@ class YiiBase
return
self
::
$aliases
[
$alias
]
=
self
::
$aliases
[
$rootAlias
]
.
substr
(
$alias
,
$pos
);
}
}
if
(
$throwException
)
{
throw
new
Exception
(
"Invalid path alias:
$alias
"
);
}
else
{
return
false
;
}
return
false
;
}
/**
...
...
@@ -361,7 +356,7 @@ class YiiBase
$class
=
$config
[
'class'
];
unset
(
$config
[
'class'
]);
}
else
{
throw
new
InvalidC
all
Exception
(
'Object configuration must be an array containing a "class" element.'
);
throw
new
InvalidC
onfig
Exception
(
'Object configuration must be an array containing a "class" element.'
);
}
if
(
!
class_exists
(
$class
,
false
))
{
...
...
framework/base/Controller.php
View file @
bd320533
...
...
@@ -279,4 +279,15 @@ class Controller extends Component
{
return
new
View
(
$this
);
}
/**
* Returns the directory containing view files for this controller.
* The default implementation returns the directory named as controller [[id]] under the [[module]]'s
* [[viewPath]] directory.
* @return string the directory containing the view files for this controller.
*/
public
function
getViewPath
()
{
return
$this
->
module
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
$this
->
id
;
}
}
framework/base/ErrorHandler.php
View file @
bd320533
...
...
@@ -321,7 +321,7 @@ class ErrorHandler extends Component
public
function
renderAsHtml
(
$exception
)
{
$view
=
new
View
;
$view
->
context
=
$this
;
$view
->
_owner
=
$this
;
$name
=
!
YII_DEBUG
||
$exception
instanceof
HttpException
?
$this
->
errorView
:
$this
->
exceptionView
;
echo
$view
->
render
(
$name
,
array
(
'exception'
=>
$exception
,
...
...
framework/base/Theme.php
View file @
bd320533
...
...
@@ -9,55 +9,114 @@
namespace
yii\base
;
use
Yii
;
use
yii\base\InvalidConfigException
;
use
yii\util\FileHelper
;
/**
* Theme represents an application theme.
*
* A theme is directory consisting of view and layout files which are meant to replace their
* non-themed counterparts.
*
* Theme uses [[pathMap]] to achieve the file replacement. A view or layout file will be replaced
* with its themed version if part of its path matches one of the keys in [[pathMap]].
* Then the matched part will be replaced with the corresponding array value.
*
* For example, if [[pathMap]] is `array('/www/views' => '/www/themes/basic')`,
* then the themed version for a view file `/www/views/site/index.php` will be
* `/www/themes/basic/site/index.php`.
*
* @property string $baseUrl the base URL for this theme. This is mainly used by [[getUrl()]].
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
Theme
extends
Component
{
/**
* @var string the root path of this theme.
* @see pathMap
*/
public
$basePath
;
public
$baseUrl
;
/**
* @var array the mapping between view directories and their corresponding themed versions.
* If not set, it will be initialized as a mapping from [[Application::basePath]] to [[basePath]].
* This property is used by [[apply()]] when a view is trying to apply the theme.
*/
public
$pathMap
;
private
$_baseUrl
;
/**
* Initializes the theme.
* @throws InvalidConfigException if [[basePath]] is not set.
*/
public
function
init
()
{
if
(
$this
->
basePath
!==
null
)
{
$this
->
basePath
=
\Yii
::
getAlias
(
$this
->
basePath
,
true
);
}
else
{
throw
new
InvalidConfigException
(
"Theme.basePath must be set."
);
parent
::
init
();
if
(
empty
(
$this
->
pathMap
))
{
if
(
$this
->
basePath
!==
null
)
{
$this
->
basePath
=
FileHelper
::
ensureDirectory
(
$this
->
basePath
);
$this
->
pathMap
=
array
(
Yii
::
$application
->
getBasePath
()
=>
$this
->
basePath
);
}
else
{
throw
new
InvalidConfigException
(
"Theme::basePath must be set."
);
}
}
if
(
$this
->
baseUrl
!==
null
)
{
$this
->
baseUrl
=
\Yii
::
getAlias
(
$this
->
baseUrl
,
true
);
}
else
{
throw
new
InvalidConfigException
(
"Theme.baseUrl must be set."
);
$paths
=
array
();
foreach
(
$this
->
pathMap
as
$from
=>
$to
)
{
$paths
[
FileHelper
::
normalizePath
(
$from
)
.
DIRECTORY_SEPARATOR
]
=
FileHelper
::
normalizePath
(
$to
)
.
DIRECTORY_SEPARATOR
;
}
$this
->
pathMap
=
$paths
;
}
/**
* Returns the base URL for this theme.
* The method [[getUrl()]] will prefix this to the given URL.
* @return string the base URL for this theme.
*/
public
function
getBaseUrl
()
{
return
$this
->
_baseUrl
;
}
/**
* Sets the base URL for this theme.
* @param string $value the base URL for this theme.
*/
public
function
setBaseUrl
(
$value
)
{
$this
->
_baseUrl
=
rtrim
(
Yii
::
getAlias
(
$value
),
'/'
);
}
/**
* @param Application|Module|Controller|Object $context
* @return string
* Converts a file to a themed file if possible.
* If there is no corresponding themed file, the original file will be returned.
* @param string $path the file to be themed
* @return string the themed file, or the original file if the themed version is not available.
*/
public
function
getViewPath
(
$context
=
null
)
public
function
apply
(
$path
)
{
$viewPath
=
$this
->
basePath
.
DIRECTORY_SEPARATOR
.
'views'
;
if
(
$context
===
null
||
$context
instanceof
Application
)
{
return
$viewPath
;
}
elseif
(
$context
instanceof
Controller
||
$context
instanceof
Module
)
{
return
$viewPath
.
DIRECTORY_SEPARATOR
.
$context
->
getUniqueId
();
}
else
{
return
$viewPath
.
DIRECTORY_SEPARATOR
.
str_replace
(
'\\'
,
'_'
,
get_class
(
$context
));
$path
=
FileHelper
::
normalizePath
(
$path
);
foreach
(
$this
->
pathMap
as
$from
=>
$to
)
{
if
(
strpos
(
$path
,
$from
)
===
0
)
{
$n
=
strlen
(
$from
);
$file
=
$to
.
substr
(
$path
,
$n
);
if
(
is_file
(
$file
))
{
return
$file
;
}
}
}
return
$path
;
}
/**
* @param Module $module
* @return string
* Converts a relative URL into an absolute URL using [[basePath]].
* @param string $url the relative URL to be converted.
* @return string the absolute URL
*/
public
function
get
LayoutPath
(
$module
=
nul
l
)
public
function
get
Url
(
$ur
l
)
{
return
$this
->
getViewPath
(
$module
)
.
DIRECTORY_SEPARATOR
.
'layouts'
;
return
$this
->
baseUrl
.
'/'
.
ltrim
(
$url
,
'/'
)
;
}
}
framework/base/View.php
View file @
bd320533
...
...
@@ -9,27 +9,26 @@
namespace
yii\base
;
use
Yii
;
use
yii\util\FileHelper
;
use
yii\base\Application
;
/**
* View represents a view object in the MVC pattern.
*
* View provides a set of methods (e.g. [[render()]]) for rendering purpose.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
View
extends
Component
{
/**
* @var Controller|Widget|Object the context under which this view is being rendered
* @var string the layout to be applied when [[render()]] or [[renderContent()]] is called.
* If not set, it will use the value of [[Application::layout]].
*/
public
$context
;
/**
* @var string|array the directories where the view file should be looked for when 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 directories in the order they are specified.
* Path aliases can be used. If this property is not set, relative view names should be treated as absolute ones.
* @see roothPath
*/
public
$basePath
;
public
$layout
;
/**
* @var string the language that the view should be rendered in. If not set, it will use
* the value of [[Application::language]].
...
...
@@ -45,45 +44,76 @@ class View extends Component
* Note that when this is true, if a localized view cannot be found, the original view will be rendered.
* No error will be reported.
*/
public
$
localizeView
=
true
;
public
$
enableI18N
=
true
;
/**
* @var boolean whether to theme the view when possible. Defaults to true.
* Note that theming will be disabled if [[Application::theme]] is n
ull
.
* Note that theming will be disabled if [[Application::theme]] is n
ot set
.
*/
public
$
themeView
=
true
;
public
$
enableTheme
=
true
;
/**
* @var mixed custom parameters that are available in the view template
*/
public
$params
;
/**
* @var object the object that owns this view.
*/
private
$_owner
;
/**
* @var Widget[] the widgets that are currently not ended
*/
pr
otected
$
widgetStack
=
array
();
pr
ivate
$_
widgetStack
=
array
();
/**
* Constructor.
* @param
Controller|Widget|Object $context the context under which this view is being rendered (e.g. controller, widget)
* @param
object $owner the owner of this view. This usually is a controller or a widget.
* @param array $config name-value pairs that will be used to initialize the object properties
*/
public
function
__construct
(
$
context
=
null
,
$config
=
array
())
public
function
__construct
(
$
owner
,
$config
=
array
())
{
$this
->
context
=
$context
;
$this
->
_owner
=
$owner
;
parent
::
__construct
(
$config
);
}
/**
* Returns the owner of this view.
* @return object the owner of this view.
*/
public
function
getOwner
()
{
return
$this
->
_owner
;
}
/**
* Renders a view within the layout specified by [[owner]].
* This method is similar to [[renderPartial()]] except that if [[owner]] specifies a layout,
* this method will embed the view result into the layout and then return it.
* @param string $view the view to be rendered. This can be either a path alias or a path relative to [[searchPaths]].
* @param array $params the parameters that should be made available in the view. The PHP function `extract()`
* will be called on this variable to extract the variables from this parameter.
* @return string the rendering result
* @throws InvalidCallException if the view file cannot be found
* @see renderPartial()
*/
public
function
render
(
$view
,
$params
=
array
())
{
$content
=
$this
->
renderPartial
(
$view
,
$params
);
return
$this
->
render
Tex
t
(
$content
);
return
$this
->
render
Conten
t
(
$content
);
}
public
function
renderText
(
$text
)
/**
* Renders a text content within the layout specified by [[owner]].
* If the [[owner]] does not specify any layout, the content will be returned back.
* @param string $content the content to be rendered
* @return string the rendering result
*/
public
function
renderContent
(
$content
)
{
$layoutFile
=
$this
->
findLayoutFile
();
if
(
$layoutFile
!==
false
)
{
return
$this
->
renderFile
(
$layoutFile
,
array
(
'content'
=>
$
tex
t
));
return
$this
->
renderFile
(
$layoutFile
,
array
(
'content'
=>
$
conten
t
));
}
else
{
return
$
tex
t
;
return
$
conten
t
;
}
}
...
...
@@ -94,18 +124,16 @@ class View extends Component
* It then calls [[renderFile()]] to render the view file. The rendering result is returned
* as a string. If the view file does not exist, an exception will be thrown.
*
* To determine which view file should be rendered, the method calls [[findViewFile()]] which
* will search in the directories as specified by [[basePath]].
*
* 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 [[
searchPaths
]]. The file suffix is optional and defaults to `.php` if not given
* in the view name.
*
* @param string $view the view to be rendered. This can be either a path alias or a path relative to [[
basePath
]].
* @param string $view the view to be rendered. This can be either a path alias or a path relative to [[
searchPaths
]].
* @param array $params the parameters that should be made available in the view. The PHP function `extract()`
* will be called on this variable to extract the variables from this parameter.
* @return string the rendering result
* @throws InvalidCallException if the view file cannot be found
* @see findViewFile()
*/
public
function
renderPartial
(
$view
,
$params
=
array
())
{
...
...
@@ -119,19 +147,25 @@ class View extends Component
/**
* Renders a view file.
* @param string $file the view file path
* @param array $params the parameters to be extracted and made available in the view file
* This method will extract the given parameters and include the view file.
* It captures the output of the included view file and returns it as a string.
* @param string $_file_ the view file.
* @param array $_params_ the parameters (name-value pairs) that will be extracted and made available in the view file.
* @return string the rendering result
*/
public
function
renderFile
(
$
file
,
$params
=
array
())
public
function
renderFile
(
$
_file_
,
$_params_
=
array
())
{
return
$this
->
renderFileInternal
(
$file
,
$params
);
ob_start
();
ob_implicit_flush
(
false
);
extract
(
$_params_
,
EXTR_OVERWRITE
);
require
(
$_file_
);
return
ob_get_clean
();
}
public
function
createWidget
(
$class
,
$properties
=
array
())
{
$properties
[
'class'
]
=
$class
;
return
\Yii
::
createObject
(
$properties
,
$this
->
context
);
return
Yii
::
createObject
(
$properties
,
$this
->
_owner
);
}
public
function
widget
(
$class
,
$properties
=
array
(),
$captureOutput
=
false
)
...
...
@@ -158,7 +192,7 @@ class View extends Component
public
function
beginWidget
(
$class
,
$properties
=
array
())
{
$widget
=
$this
->
createWidget
(
$class
,
$properties
);
$this
->
widgetStack
[]
=
$widget
;
$this
->
_
widgetStack
[]
=
$widget
;
return
$widget
;
}
...
...
@@ -173,7 +207,7 @@ class View extends Component
public
function
endWidget
()
{
/** @var $widget Widget */
if
((
$widget
=
array_pop
(
$this
->
widgetStack
))
!==
null
)
{
if
((
$widget
=
array_pop
(
$this
->
_
widgetStack
))
!==
null
)
{
$widget
->
run
();
return
$widget
;
}
else
{
...
...
@@ -273,141 +307,75 @@ class View extends Component
}
/**
* Renders a view file.
* This method will extract the given parameters and include the view file.
* It captures the output of the included view file and returns it as a string.
* @param string $_file_ the view file.
* @param array $_params_ the parameters (name-value pairs) that will be extracted and made available in the view file.
* @return string the rendering result
*/
protected
function
renderFileInternal
(
$_file_
,
$_params_
=
array
())
{
ob_start
();
ob_implicit_flush
(
false
);
extract
(
$_params_
,
EXTR_OVERWRITE
);
require
(
$_file_
);
return
ob_get_clean
();
}
/**
* Finds the view file based on the given view name.
*
* The rule for searching for the view file is as follows:
*
* - If the view name is given as a path alias, return the actual path corresponding to the alias;
* - If the view name does NOT start with a slash:
* * If the view owner is a controller or widget, look for the view file under
* the controller or widget's view path (see [[Controller::viewPath]] and [[Widget::viewPath]]);
* * If the view owner is an object, look for the view file under the "views" sub-directory
* of the directory containing the object class file;
* * Otherwise, look for the view file under the application's [[Application::viewPath|view path]].
* - If the view name starts with a single slash, look for the view file under the currently active
* module's [[Module::viewPath|view path]];
* - If the view name starts with double slashes, look for the view file under the application's
* [[Application::viewPath|view path]].
*
* If [[enableTheme]] is true and there is an active application them, the method will also
* attempt to use a themed version of the view file, when available.
*
* @param string $view the view name or path alias. If the view name does not specify
* the view file extension name, it will use `.php` as the extension name.
* @return string|boolean the view file if it exists. False if the view file cannot be found.
* @return string|boolean the view file
path
if it exists. False if the view file cannot be found.
*/
public
function
findViewFile
(
$view
)
{
if
(
(
$extension
=
FileHelper
::
getExtension
(
$view
)
)
===
''
)
{
if
(
FileHelper
::
getExtension
(
$view
)
===
''
)
{
$view
.=
'.php'
;
}
if
(
strncmp
(
$view
,
'@'
,
1
)
===
0
)
{
$file
=
\Yii
::
getAlias
(
$view
);
// e.g. "@application/views/common"
$file
=
Yii
::
getAlias
(
$view
);
}
elseif
(
strncmp
(
$view
,
'/'
,
1
)
!==
0
)
{
$file
=
$this
->
findRelativeViewFile
(
$view
);
}
else
{
$file
=
$this
->
findAbsoluteViewFile
(
$view
);
}
if
(
$file
===
false
||
!
is_file
(
$file
))
{
return
false
;
}
elseif
(
$this
->
localizeView
)
{
return
FileHelper
::
localize
(
$file
,
$this
->
language
,
$this
->
sourceLanguage
);
}
else
{
return
$file
;
}
}
/**
* Finds the view file corresponding to the given relative view name.
* The method will look for the view file under a set of directories returned by [[resolveBasePath()]].
* If no base path is given, the view will be treated as an absolute view and the result of
* [[findAbsoluteViewFile()]] will be returned.
* @param string $view the relative view name
* @return string|boolean the view file path, or false if the view file cannot be found
*/
protected
function
findRelativeViewFile
(
$view
)
{
$paths
=
$this
->
resolveBasePath
();
if
(
$paths
===
array
())
{
return
$this
->
findAbsoluteViewFile
(
$view
);
}
if
(
$this
->
themeView
&&
$this
->
context
!==
null
&&
(
$theme
=
\Yii
::
$application
->
getTheme
())
!==
null
)
{
array_unshift
(
$paths
,
$theme
->
getViewPath
(
$this
->
context
));
}
foreach
(
$paths
as
$path
)
{
$file
=
\Yii
::
getAlias
(
$path
.
'/'
.
$view
);
if
(
$file
!==
false
&&
is_file
(
$file
))
{
return
$file
;
// e.g. "index"
if
(
$this
->
_owner
instanceof
Controller
||
$this
->
_owner
instanceof
Widget
)
{
$path
=
$this
->
_owner
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
$view
;
}
elseif
(
$this
->
_owner
!==
null
)
{
$class
=
new
\ReflectionClass
(
$this
->
_owner
);
$path
=
dirname
(
$class
->
getFileName
())
.
DIRECTORY_SEPARATOR
.
'views'
;
}
else
{
$path
=
Yii
::
$application
->
getViewPath
();
}
}
return
$paths
===
array
()
?
$this
->
findAbsoluteViewFile
(
$view
)
:
false
;
}
/**
* Finds the view file corresponding to the given absolute view name.
* If the view name starts with double slashes `//`, the method will look for the view file
* under [[Application::getViewPath()]]. Otherwise, it will look for the view file under the
* view path of the currently active module.
* @param string $view the absolute view name
* @return string|boolean the view file path, or false if the view file cannot be found
*/
protected
function
findAbsoluteViewFile
(
$view
)
{
$app
=
\Yii
::
$application
;
if
(
strncmp
(
$view
,
'//'
,
2
)
!==
0
&&
$app
->
controller
!==
null
)
{
$module
=
$app
->
controller
->
module
;
$file
=
$path
.
DIRECTORY_SEPARATOR
.
$view
;
}
elseif
(
strncmp
(
$view
,
'//'
,
2
)
!==
0
&&
Yii
::
$application
->
controller
!==
null
)
{
// e.g. "/site/index"
$file
=
Yii
::
$application
->
controller
->
module
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
else
{
$module
=
$app
;
// e.g. "//layouts/main"
$file
=
Yii
::
$application
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
if
(
$this
->
themeView
&&
(
$theme
=
$app
->
getTheme
())
!==
null
)
{
$paths
[]
=
$theme
->
getViewPath
(
$module
);
}
$paths
[]
=
$module
->
getViewPath
();
$view
=
ltrim
(
$view
,
'/'
);
foreach
(
$paths
as
$path
)
{
$file
=
\Yii
::
getAlias
(
$path
.
'/'
.
$view
);
if
(
$file
!==
false
&&
is_file
(
$file
))
{
return
$file
;
}
}
return
false
;
}
/**
* Resolves the base paths that will be used to determine view files for relative view names.
* The method resolves the base path using the following algorithm:
*
* - If [[basePath]] is not empty, it is returned;
* - If [[context]] is a controller, it will return the subdirectory named as
* [[Controller::uniqueId]] under the controller's module view path;
* - If [[context]] is an object, it will return the `views` subdirectory under
* the directory containing the object class file.
* - Otherwise, it will return false.
* @return array the base paths
*/
protected
function
resolveBasePath
()
{
if
(
!
empty
(
$this
->
basePath
))
{
return
(
array
)
$this
->
basePath
;
}
elseif
(
$this
->
context
instanceof
Controller
)
{
return
array
(
$this
->
context
->
module
->
getViewPath
()
.
'/'
.
$this
->
context
->
getUniqueId
());
}
elseif
(
$this
->
context
!==
null
)
{
$class
=
new
\ReflectionClass
(
$this
->
context
);
return
array
(
dirname
(
$class
->
getFileName
())
.
'/views'
);
if
(
is_file
(
$file
))
{
if
(
$this
->
enableTheme
&&
(
$theme
=
Yii
::
$application
->
getTheme
())
!==
null
)
{
$file
=
$theme
->
apply
(
$file
);
}
return
$this
->
enableI18N
?
FileHelper
::
localize
(
$file
,
$this
->
language
,
$this
->
sourceLanguage
)
:
$file
;
}
else
{
return
array
()
;
return
false
;
}
}
/**
* Finds the layout file for the current [[
context
]].
* The method will return false if [[
context
]] is not a controller.
* When [[
context
]] is a controller, the following algorithm is used to determine the layout file:
* Finds the layout file for the current [[
owner
]].
* The method will return false if [[
owner
]] is not a controller.
* When [[
owner
]] is a controller, the following algorithm is used to determine the layout file:
*
* - If `conte
xt
.layout` is false, it will return false;
* - If `
context
.layout` is a string, it will look for the layout file under the [[Module::layoutPath|layout path]]
* - If `conte
nt` is not a controller or if `owner
.layout` is false, it will return false;
* - If `
owner
.layout` is a string, it will look for the layout file under the [[Module::layoutPath|layout path]]
* of the controller's parent module;
* - If `
context
.layout` is null, the following steps are taken to resolve the actual layout to be returned:
* - If `
owner
.layout` is null, the following steps are taken to resolve the actual layout to be returned:
* * Check the `layout` property of the parent module. If it is null, check the grand parent module and so on
* until a non-null layout is encountered. Let's call this module the *effective module*.
* * If the layout is null or false, it will return false;
...
...
@@ -415,15 +383,21 @@ class View extends Component
*
* The themed layout file will be returned if theme is enabled and the theme contains such a layout file.
*
* @return string|boolean the layout file path, or false if the
context
does not need layout.
* @return string|boolean the layout file path, or false if the
owner
does not need layout.
* @throws InvalidCallException if the layout file cannot be found
*/
public
function
findLayoutFile
()
{
if
(
!
$this
->
context
instanceof
Controller
||
$this
->
context
->
layout
===
false
)
{
if
(
$this
->
layout
===
null
||
!
$this
->
_owner
instanceof
Controller
)
{
$layout
=
Yii
::
$application
->
layout
;
}
elseif
(
$this
->
_owner
->
layout
!==
false
)
{
}
if
(
!
$this
->
_owner
instanceof
Controller
||
$this
->
_owner
->
layout
===
false
)
{
return
false
;
}
$module
=
$this
->
context
->
module
;
/** @var $module Module */
$module
=
$this
->
_owner
->
module
;
while
(
$module
!==
null
&&
$module
->
layout
===
null
)
{
$module
=
$module
->
module
;
}
...
...
@@ -432,21 +406,35 @@ class View extends Component
}
$view
=
$module
->
layout
;
if
(
(
$extension
=
FileHelper
::
getExtension
(
$view
)
)
===
''
)
{
if
(
FileHelper
::
getExtension
(
$view
)
===
''
)
{
$view
.=
'.php'
;
}
if
(
strncmp
(
$view
,
'@'
,
1
)
===
0
)
{
$file
=
\Yii
::
getAlias
(
$view
);
$file
=
Yii
::
getAlias
(
$view
);
}
elseif
(
strncmp
(
$view
,
'/'
,
1
)
!==
0
)
{
// e.g. "main"
if
(
$this
->
_owner
instanceof
Controller
||
$this
->
_owner
instanceof
Widget
)
{
$path
=
$this
->
_owner
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
$view
;
}
elseif
(
$this
->
_owner
!==
null
)
{
$class
=
new
\ReflectionClass
(
$this
->
_owner
);
$path
=
dirname
(
$class
->
getFileName
())
.
DIRECTORY_SEPARATOR
.
'views'
;
}
else
{
$path
=
Yii
::
$application
->
getViewPath
();
}
$file
=
$path
.
DIRECTORY_SEPARATOR
.
$view
;
}
elseif
(
strncmp
(
$view
,
'//'
,
2
)
!==
0
&&
Yii
::
$application
->
controller
!==
null
)
{
// e.g. "/main"
$file
=
Yii
::
$application
->
controller
->
module
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
else
{
// e.g. "//main"
$file
=
Yii
::
$application
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
elseif
(
strncmp
(
$view
,
'/'
,
1
)
===
0
)
{
$file
=
$this
->
findAbsoluteViewFile
(
$view
);
}
else
{
if
(
$this
->
themeView
&&
(
$theme
=
\Yii
::
$application
->
getTheme
())
!==
null
)
{
$paths
[]
=
$theme
->
getLayoutPath
(
$module
);
}
$paths
[]
=
$module
->
getLayoutPath
();
$file
=
false
;
foreach
(
$paths
as
$path
)
{
$f
=
\
Yii
::
getAlias
(
$path
.
'/'
.
$view
);
$f
=
Yii
::
getAlias
(
$path
.
'/'
.
$view
);
if
(
$f
!==
false
&&
is_file
(
$f
))
{
$file
=
$f
;
break
;
...
...
@@ -455,7 +443,7 @@ class View extends Component
}
if
(
$file
===
false
||
!
is_file
(
$file
))
{
throw
new
InvalidCallException
(
"Unable to find the layout file for layout '
{
$module
->
layout
}
' (specified by "
.
get_class
(
$module
)
.
")"
);
}
elseif
(
$this
->
localizeView
)
{
}
elseif
(
$this
->
enableI18N
)
{
return
FileHelper
::
localize
(
$file
,
$this
->
language
,
$this
->
sourceLanguage
);
}
else
{
return
$file
;
...
...
framework/base/Widget.php
View file @
bd320533
...
...
@@ -102,4 +102,16 @@ class Widget extends Component
{
return
new
View
(
$this
);
}
/**
* Returns the directory containing the view files for this widget.
* The default implementation returns the 'views' subdirectory under the directory containing the widget class file.
* @return string the directory containing the view files for this widget.
*/
public
function
getViewPath
()
{
$className
=
get_class
(
$this
);
$class
=
new
\ReflectionClass
(
$className
);
return
dirname
(
$class
->
getFileName
())
.
DIRECTORY_SEPARATOR
.
'views'
;
}
}
\ No newline at end of file
framework/util/FileHelper.php
View file @
bd320533
...
...
@@ -51,6 +51,20 @@ class FileHelper
}
/**
* Normalizes a file/directory path.
* After normalization, the directory separators in the path will be `DIRECTORY_SEPARATOR`,
* and any trailing directory separators will be removed. For example, '/home\demo/' on Linux
* will be normalized as '/home/demo'.
* @param string $path the file/directory path to be normalized
* @param string $ds the directory separator to be used in the normalized result. Defaults to `DIRECTORY_SEPARATOR`.
* @return string the normalized file/directory path
*/
public
static
function
normalizePath
(
$path
,
$ds
=
DIRECTORY_SEPARATOR
)
{
return
rtrim
(
strtr
(
$path
,
array
(
'/'
=>
$ds
,
'\\'
=>
$ds
)),
$ds
);
}
/**
* Returns the localized version of a specified file.
*
* The searching is based on the specified language code. In particular,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment