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
10061359
Commit
10061359
authored
Mar 04, 2014
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixes #1467: Added support for organizing controllers in subdirectories
parent
80e9b800
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
88 additions
and
24 deletions
+88
-24
controller.md
docs/guide/controller.md
+7
-4
CHANGELOG.md
framework/CHANGELOG.md
+1
-0
Module.php
framework/base/Module.php
+80
-20
No files found.
docs/guide/controller.md
View file @
10061359
...
...
@@ -81,13 +81,16 @@ Routes
------
Each controller action has a corresponding internal route. In our example above
`actionIndex`
has
`site/index`
route
and
`actionTest`
has
`site/test`
route. In this route
`site`
is referred to as controller ID while
`test`
is referred to
as action ID.
and
`actionTest`
has
`site/test`
route. In this route
`site`
is referred to as controller ID while
`test`
is action ID.
By default you can access specific controller and action using the
`http://example.com/?r=controller/action`
URL. This
behavior is fully customizable. For
details
refer to
[
URL Management
](
url.md
)
.
behavior is fully customizable. For
more details please
refer to
[
URL Management
](
url.md
)
.
If controller is located inside a module its action internal route will be
`module/controller/action`
.
If a controller is located inside a module, the route of its actions will be in the format of
`module/controller/action`
.
A controller can be located under a subdirectory of the controller directory of an application or module. The route
will be prefixed with the corresponding directory names. For example, you may have a
`UserController`
under
`controllers/admin`
.
The route of its
`actionIndex`
would be
`admin/user/index`
, and
`admin/user`
would be the controller ID.
In case module, controller or action specified isn't found Yii will return "not found" page and HTTP status code 404.
...
...
framework/CHANGELOG.md
View file @
10061359
...
...
@@ -71,6 +71,7 @@ Yii Framework 2 Change Log
-
Enh #1293: Replaced Console::showProgress() with a better approach. See Console::startProgress() for details (cebe)
-
Enh #1406: DB Schema support for Oracle Database (p0larbeer, qiangxue)
-
Enh #1437: Added ListView::viewParams (qiangxue)
-
Enh #1467: Added support for organizing controllers in subdirectories (qiangxue)
-
Enh #1469: ActiveRecord::find() now works with default conditions (default scope) applied by createQuery (cebe)
-
Enh #1476: Add yii
\w
eb
\S
ession::handler property (nineinchnick)
-
Enh #1499: Added
`ActionColumn::controller`
property to support customizing the controller for handling GridView actions (qiangxue)
...
...
framework/base/Module.php
View file @
10061359
...
...
@@ -593,12 +593,21 @@ class Module extends Component
}
/**
* Creates a controller instance based on the
controller ID
.
* Creates a controller instance based on the
given route
.
*
* The controller is created within this 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.
* The route should be relative to this module. The method implements the following algorithm
* to resolve the given route:
*
* 1. If the route is empty, use [[defaultRoute]];
* 2. If the first segment of the route is a valid module ID as declared in [[modules]],
* call the module's `createController()` with the rest part of the route;
* 3. If the first segment of the route is found in [[controllerMap]], create a controller
* based on the corresponding configuration found in [[controllerMap]];
* 4. The given route is in the format of `abc/def/xyz`. Try either `abc\DefController`
* or `abc\def\XyzController` class within the [[controllerNamespace|controller namespace]].
*
* If any of the above steps resolves into a controller, it is returned together with the rest
* part of the route which will be treated as the action ID. Otherwise, false will be returned.
*
* @param string $route the route consisting of module, controller and action IDs.
* @return array|boolean If the controller is created successfully, it will be returned together
...
...
@@ -610,6 +619,13 @@ class Module extends Component
if
(
$route
===
''
)
{
$route
=
$this
->
defaultRoute
;
}
// double slashes or leading/ending slashes may cause substr problem
$route
=
trim
(
$route
,
'/'
);
if
(
strpos
(
$route
,
'//'
)
!==
false
)
{
return
false
;
}
if
(
strpos
(
$route
,
'/'
)
!==
false
)
{
list
(
$id
,
$route
)
=
explode
(
'/'
,
$route
,
2
);
}
else
{
...
...
@@ -617,29 +633,73 @@ class Module extends Component
$route
=
''
;
}
// module and controller map take precedence
$module
=
$this
->
getModule
(
$id
);
if
(
$module
!==
null
)
{
return
$module
->
createController
(
$route
);
}
if
(
isset
(
$this
->
controllerMap
[
$id
]))
{
$controller
=
Yii
::
createObject
(
$this
->
controllerMap
[
$id
],
$id
,
$this
);
}
elseif
(
preg_match
(
'/^[a-z0-9\\-_]+$/'
,
$id
)
&&
strpos
(
$id
,
'--'
)
===
false
&&
trim
(
$id
,
'-'
)
===
$id
)
{
$className
=
str_replace
(
' '
,
''
,
ucwords
(
str_replace
(
'-'
,
' '
,
$id
)))
.
'Controller'
;
$classFile
=
$this
->
controllerPath
.
DIRECTORY_SEPARATOR
.
$className
.
'.php'
;
if
(
!
is_file
(
$classFile
))
{
return
false
;
}
$className
=
ltrim
(
$this
->
controllerNamespace
.
'\\'
.
$className
,
'\\'
);
Yii
::
$classMap
[
$className
]
=
$classFile
;
if
(
is_subclass_of
(
$className
,
'yii\base\Controller'
))
{
$controller
=
new
$className
(
$id
,
$this
);
}
elseif
(
YII_DEBUG
)
{
throw
new
InvalidConfigException
(
"Controller class must extend from
\\
yii
\\
base
\\
Controller."
);
}
return
[
$controller
,
$route
];
}
if
((
$pos
=
strrpos
(
$route
,
'/'
))
!==
false
)
{
$id
.=
'/'
.
substr
(
$route
,
0
,
$pos
);
$route
=
substr
(
$route
,
$pos
+
1
);
}
$controller
=
$this
->
createControllerByID
(
$id
);
if
(
$controller
===
null
&&
$route
!==
''
)
{
$controller
=
$this
->
createControllerByID
(
$id
.
'/'
.
$route
);
$route
=
''
;
}
return
$controller
===
null
?
false
:
[
$controller
,
$route
];
}
/**
* Creates a controller based on the given controller ID.
*
* The controller ID is relative to this module. The controller class
* should be located under [[controllerPath]] and namespaced under [[controllerNamespace]].
*
* Note that this method does not check [[modules]] or [[controllerMap]].
*
* @param string $id the controller ID
* @return Controller the newly created controller instance, or null if the controller ID is invalid.
* @throws InvalidConfigException if the controller class and its file name do not match.
* This exception is only thrown when in debug mode.
*/
public
function
createControllerByID
(
$id
)
{
if
(
!
preg_match
(
'%^[a-z0-9\\-_/]+$%'
,
$id
))
{
return
null
;
}
return
isset
(
$controller
)
?
[
$controller
,
$route
]
:
false
;
$pos
=
strrpos
(
$id
,
'/'
);
if
(
$pos
===
false
)
{
$prefix
=
''
;
$className
=
$id
;
}
else
{
$prefix
=
substr
(
$id
,
0
,
$pos
+
1
);
$className
=
substr
(
$id
,
$pos
+
1
);
}
$className
=
str_replace
(
' '
,
''
,
ucwords
(
str_replace
(
'-'
,
' '
,
$className
)))
.
'Controller'
;
$classFile
=
$this
->
controllerPath
.
'/'
.
$prefix
.
$className
.
'.php'
;
$className
=
$this
->
controllerNamespace
.
'\\'
.
str_replace
(
'/'
,
'\\'
,
$prefix
)
.
$className
;
if
(
strpos
(
$className
,
'-'
)
!==
false
||
!
is_file
(
$classFile
))
{
return
null
;
}
Yii
::
$classMap
[
$className
]
=
$classFile
;
if
(
is_subclass_of
(
$className
,
'yii\base\Controller'
))
{
return
new
$className
(
$id
,
$this
);
}
elseif
(
YII_DEBUG
)
{
throw
new
InvalidConfigException
(
"Controller class must extend from
\\
yii
\\
base
\\
Controller."
);
}
else
{
return
null
;
}
}
/**
...
...
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