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
be8dd940
Commit
be8dd940
authored
May 12, 2012
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
5a72523a
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
163 additions
and
215 deletions
+163
-215
Action.php
framework/base/Action.php
+7
-6
Application.php
framework/base/Application.php
+29
-14
Controller.php
framework/base/Controller.php
+8
-4
InlineAction.php
framework/base/InlineAction.php
+8
-6
Module.php
framework/base/Module.php
+19
-36
Application.php
framework/console/Application.php
+28
-7
Controller.php
framework/console/Controller.php
+5
-122
ReflectionHelper.php
framework/util/ReflectionHelper.php
+59
-20
No files found.
framework/base/Action.php
View file @
be8dd940
...
...
@@ -9,6 +9,8 @@
namespace
yii\base
;
use
yii\util\ReflectionHelper
;
/**
* Action is the base class for all controller action classes.
*
...
...
@@ -52,13 +54,12 @@ class Action extends Component
*/
public
function
runWithParams
(
$params
)
{
$method
=
new
\ReflectionMethod
(
$this
,
'run'
);
$params
=
\yii\util\ReflectionHelper
::
bindParams
(
$method
,
$params
);
if
(
$params
===
false
)
{
$this
->
controller
->
invalidActionParams
(
$this
);
try
{
$params
=
ReflectionHelper
::
extractMethodParams
(
$this
,
'run'
,
$params
);
return
(
int
)
call_user_func_array
(
array
(
$this
,
'run'
),
$params
);
}
catch
(
Exception
$e
)
{
$this
->
controller
->
invalidActionParams
(
$this
,
$e
);
return
1
;
}
else
{
return
(
int
)
$method
->
invokeArgs
(
$this
,
$params
);
}
}
}
framework/base/Application.php
View file @
be8dd940
...
...
@@ -73,7 +73,7 @@ use yii\base\Exception;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
abstract
class
Application
extends
Module
class
Application
extends
Module
{
/**
* @var string the application name. Defaults to 'My Application'.
...
...
@@ -132,13 +132,6 @@ abstract class Application extends Module
}
/**
* Runs the application.
* This is the main entrance of an application. Derived classes must implement this method.
* @return integer the exit status (0 means normal, non-zero values mean abnormal)
*/
abstract
public
function
run
();
/**
* Terminates the application.
* This method replaces PHP's exit() function by calling [[afterRequest()]] before exiting.
* @param integer $status exit status (value 0 means normal exit while other values mean abnormal exit).
...
...
@@ -157,6 +150,19 @@ abstract class Application extends Module
}
/**
* Runs the application.
* This is the main entrance of an application.
* @return integer the exit status (0 means normal, non-zero values mean abnormal)
*/
public
function
run
()
{
$this
->
beforeRequest
();
$status
=
$this
->
processRequest
();
$this
->
afterRequest
();
return
$status
;
}
/**
* Raises the [[beforeRequest]] event right BEFORE the application processes the request.
*/
public
function
beforeRequest
()
...
...
@@ -174,16 +180,25 @@ abstract class Application extends Module
/**
* Processes the request.
* The request is represented in terms of a controller route and action parameters.
* @param string $route the route of the request. It may contain module ID, controller ID, and/or action ID.
* @param array $params parameters to be bound to the controller action.
* Child classes should override this method with actual request processing logic.
* @return integer the exit status of the controller action (0 means normal, non-zero values mean abnormal)
*/
public
function
processRequest
()
{
return
0
;
}
/**
* 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 Exception if the route cannot be resolved into a controller
*/
public
function
processRequest
(
$route
,
$params
=
array
())
public
function
runController
(
$route
,
$params
=
array
())
{
$result
=
$this
->
parseRoute
(
$route
);
if
(
$result
===
null
)
{
$result
=
$this
->
createController
(
$route
);
if
(
$result
===
false
)
{
throw
new
Exception
(
\Yii
::
t
(
'yii'
,
'Unable to resolve the request.'
));
}
list
(
$controller
,
$action
)
=
$result
;
...
...
framework/base/Controller.php
View file @
be8dd940
...
...
@@ -114,7 +114,10 @@ class Controller extends Component implements Initable
$this
->
action
=
$action
;
if
(
$this
->
authorize
(
$action
)
&&
$this
->
beforeAction
(
$action
))
{
$status
=
$action
->
runWithParams
(
$params
!==
null
?:
$this
->
getActionParams
());
if
(
$params
===
null
)
{
$params
=
$this
->
getActionParams
();
}
$status
=
$action
->
runWithParams
(
$params
);
$this
->
afterAction
(
$action
);
}
else
{
$status
=
1
;
...
...
@@ -163,11 +166,12 @@ class Controller extends Component implements Initable
* This method is invoked when the request parameters do not satisfy the requirement of the specified action.
* The default implementation will throw an exception.
* @param Action $action the action being executed
* @param Exception $exception the exception about the invalid parameters
* @throws Exception whenever this method is invoked
*/
public
function
invalidActionParams
(
$action
)
public
function
invalidActionParams
(
$action
,
$exception
)
{
throw
new
Exception
(
\Yii
::
t
(
'yii'
,
'Your request is invalid.'
))
;
throw
$exception
;
}
/**
...
...
@@ -219,7 +223,7 @@ class Controller extends Component implements Initable
if
(
$route
[
0
]
!==
'/'
&&
!
$this
->
module
instanceof
Application
)
{
$route
=
'/'
.
$this
->
module
->
getUniqueId
()
.
'/'
.
$route
;
}
$status
=
\Yii
::
$application
->
processRequest
(
$route
,
$params
);
$status
=
\Yii
::
$application
->
runController
(
$route
,
$params
);
}
if
(
$exit
)
{
\Yii
::
$application
->
end
(
$status
);
...
...
framework/base/InlineAction.php
View file @
be8dd940
...
...
@@ -9,6 +9,8 @@
namespace
yii\base
;
use
yii\util\ReflectionHelper
;
/**
* InlineAction represents an action that is defined as a controller method.
*
...
...
@@ -28,13 +30,13 @@ class InlineAction extends Action
*/
public
function
runWithParams
(
$params
)
{
$method
=
new
\ReflectionMethod
(
$this
->
controller
,
'action'
.
$this
->
id
);
$params
=
\yii\util\ReflectionHelper
::
bindParams
(
$method
,
$params
);
if
(
$params
===
false
)
{
$this
->
controller
->
invalidActionParams
(
$this
);
try
{
$method
=
'action'
.
$this
->
id
;
$params
=
ReflectionHelper
::
extractMethodParams
(
$this
->
controller
,
$method
,
$params
);
return
(
int
)
call_user_func_array
(
array
(
$this
->
controller
,
$method
),
$params
);
}
catch
(
Exception
$e
)
{
$this
->
controller
->
invalidActionParams
(
$this
,
$e
);
return
1
;
}
else
{
return
(
int
)
$method
->
invokeArgs
(
$this
,
$params
);
}
}
}
framework/base/Module.php
View file @
be8dd940
...
...
@@ -481,8 +481,8 @@ abstract class Module extends Component implements Initable
}
/**
*
Parses a given route into controller and action ID
.
* Th
e parsing process follows
the following algorithm:
*
Creates a controller instance based on the given route
.
* Th
is method tries to parse the given route (e.g. `post/create`) using
the following algorithm:
*
* 1. Get the first segment in route
* 2. If the segment matches
...
...
@@ -490,12 +490,12 @@ abstract class Module extends Component implements Initable
* and return the controller with the rest part of the route;
* - a controller class under [[controllerPath]], create the controller instance, and return it
* with the rest part of the route;
* - an ID in [[modules]],
let the corresponding module to parse the rest part of the rout
e.
* - an ID in [[modules]],
call the [[createController()]] method of the corresponding modul
e.
*
* @param string $route the route which may consist module ID, controller ID and/or action ID (e.g. `post/create`)
* @return array|
null the controller instance and action ID. Null
if the route cannot be resolved.
* @return array|
boolean the array of controller instance and action ID. False
if the route cannot be resolved.
*/
public
function
parseRoute
(
$route
)
public
function
createController
(
$route
)
{
if
((
$route
=
trim
(
$route
,
'/'
))
===
''
)
{
$route
=
$this
->
defaultRoute
;
...
...
@@ -509,40 +509,16 @@ abstract class Module extends Component implements Initable
$route
=
''
;
}
$controller
=
$this
->
createController
(
$id
);
if
(
$controller
!==
null
)
{
return
array
(
$controller
,
$route
);
}
if
((
$module
=
$this
->
getModule
(
$id
))
!==
null
)
{
return
$module
->
parseRoute
(
$route
);
}
return
null
;
}
/**
* Creates a controller instance according to the specified controller ID.
* For security reasons, the controller ID must start with a lower-case letter
* and consist of word characters only.
*
* This method will first match the controller ID in [[controllers]]. If found,
* it will create an instance of controller using the corresponding configuration.
* If not found, it will look for a controller class named `XyzController` under
* the [[controllerPath]] directory, where `xyz` is the controller ID with the first
* letter in upper-case.
* @param string $id the controller ID
* @return Controller|null the created controller instance. Null if the controller ID is invalid.
*/
public
function
createController
(
$id
)
{
// Controller IDs must start with a lower-case letter and consist of word characters only
if
(
!
preg_match
(
'/^[a-z][a-zA-Z0-9_]*$/'
,
$id
))
{
return
null
;
return
false
;
}
if
(
isset
(
$this
->
controllers
[
$id
]))
{
return
\Yii
::
createObject
(
$this
->
controllers
[
$id
],
$id
,
$this
);
return
array
(
\Yii
::
createObject
(
$this
->
controllers
[
$id
],
$id
,
$this
),
$route
,
);
}
$className
=
ucfirst
(
$id
)
.
'Controller'
;
...
...
@@ -552,10 +528,17 @@ abstract class Module extends Component implements Initable
require
(
$classFile
);
}
if
(
class_exists
(
$className
,
false
)
&&
is_subclass_of
(
$className
,
'\yii\base\Controller'
))
{
return
$className
::
newInstance
(
array
(),
$id
,
$this
);
return
array
(
$className
::
newInstance
(
array
(),
$id
,
$this
),
$route
,
);
}
}
return
null
;
if
((
$module
=
$this
->
getModule
(
$id
))
!==
null
)
{
return
$module
->
createController
(
$route
);
}
return
false
;
}
}
framework/console/Application.php
View file @
be8dd940
...
...
@@ -10,6 +10,7 @@
namespace
yii\console
;
use
yii\base\Exception
;
use
yii\util\ReflectionHelper
;
/**
* Application represents a console application.
...
...
@@ -71,19 +72,39 @@ class Application extends \yii\base\Application
}
/**
* Runs the application.
* This is the main entrance of an application.
* @return integer the exit status (0 means normal, non-zero values mean abnormal)
* Processes the request.
* The request is represented in terms of a controller route and action parameters.
* @return integer the exit status of the controller action (0 means normal, non-zero values mean abnormal)
* @throws Exception if the route cannot be resolved into a controller
*/
public
function
run
()
public
function
processRequest
()
{
if
(
!
isset
(
$_SERVER
[
'argv'
]))
{
die
(
'This script must be run from the command line.'
);
}
list
(
$route
,
$params
)
=
$this
->
resolveRequest
(
$_SERVER
[
'argv'
]);
$this
->
beforeRequest
();
$status
=
$this
->
processRequest
(
$route
,
$params
);
$this
->
afterRequest
();
return
$this
->
runController
(
$route
,
$params
);
}
/**
* 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 Exception if the route cannot be resolved into a controller
*/
public
function
runController
(
$route
,
$params
=
array
())
{
$result
=
$this
->
createController
(
$route
);
if
(
$result
===
false
)
{
throw
new
Exception
(
\Yii
::
t
(
'yii'
,
'Unable to resolve the request.'
));
}
list
(
$controller
,
$action
)
=
$result
;
$priorController
=
$this
->
controller
;
$this
->
controller
=
$controller
;
$params
=
ReflectionHelper
::
initObjectWithParams
(
$controller
,
$params
);
$status
=
$controller
->
run
(
$action
,
$params
);
$this
->
controller
=
$priorController
;
return
$status
;
}
...
...
framework/console/Controller.php
View file @
be8dd940
<?php
/**
* Co
mmand
class file.
* Co
ntroller
class file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2012 Yii Software LLC
...
...
@@ -9,6 +9,10 @@
namespace
yii\console
;
use
yii\base\InlineAction
;
use
yii\base\Exception
;
use
yii\util\ReflectionHelper
;
/**
* Command represents an executable console command.
*
...
...
@@ -47,105 +51,6 @@ namespace yii\console;
class
Controller
extends
\yii\base\Controller
{
/**
* Executes the command.
* The default implementation will parse the input parameters and
* dispatch the command request to an appropriate action with the corresponding
* option values
* @param array $args command line parameters for this command.
*/
public
function
run
(
$args
)
{
list
(
$action
,
$options
,
$args
)
=
$this
->
resolveRequest
(
$args
);
$methodName
=
'action'
.
$action
;
if
(
!
preg_match
(
'/^\w+$/'
,
$action
)
||
!
method_exists
(
$this
,
$methodName
))
{
$this
->
usageError
(
"Unknown action: "
.
$action
);
}
$method
=
new
\ReflectionMethod
(
$this
,
$methodName
);
$params
=
array
();
// named and unnamed options
foreach
(
$method
->
getParameters
()
as
$param
)
{
$name
=
$param
->
getName
();
if
(
isset
(
$options
[
$name
]))
{
if
(
$param
->
isArray
())
$params
[]
=
is_array
(
$options
[
$name
])
?
$options
[
$name
]
:
array
(
$options
[
$name
]);
else
if
(
!
is_array
(
$options
[
$name
]))
$params
[]
=
$options
[
$name
];
else
$this
->
usageError
(
"Option --
$name
requires a scalar. Array is given."
);
}
else
if
(
$name
===
'args'
)
$params
[]
=
$args
;
else
if
(
$param
->
isDefaultValueAvailable
())
$params
[]
=
$param
->
getDefaultValue
();
else
$this
->
usageError
(
"Missing required option --
$name
."
);
unset
(
$options
[
$name
]);
}
// try global options
if
(
!
empty
(
$options
))
{
$class
=
new
\ReflectionClass
(
get_class
(
$this
));
foreach
(
$options
as
$name
=>
$value
)
{
if
(
$class
->
hasProperty
(
$name
))
{
$property
=
$class
->
getProperty
(
$name
);
if
(
$property
->
isPublic
()
&&
!
$property
->
isStatic
())
{
$this
->
$name
=
$value
;
unset
(
$options
[
$name
]);
}
}
}
}
if
(
!
empty
(
$options
))
$this
->
usageError
(
"Unknown options: "
.
implode
(
', '
,
array_keys
(
$options
)));
if
(
$this
->
beforeAction
(
$action
,
$params
))
{
$method
->
invokeArgs
(
$this
,
$params
);
$this
->
afterAction
(
$action
,
$params
);
}
}
/**
* Parses the command line arguments and determines which action to perform.
* @param array $args command line arguments
* @return array the action name, named options (name=>value), and unnamed options
*/
protected
function
resolveRequest
(
$args
)
{
$options
=
array
();
// named parameters
$params
=
array
();
// unnamed parameters
foreach
(
$args
as
$arg
)
{
if
(
preg_match
(
'/^--(\w+)(=(.*))?$/'
,
$arg
,
$matches
))
// an option
{
$name
=
$matches
[
1
];
$value
=
isset
(
$matches
[
3
])
?
$matches
[
3
]
:
true
;
if
(
isset
(
$options
[
$name
]))
{
if
(
!
is_array
(
$options
[
$name
]))
$options
[
$name
]
=
array
(
$options
[
$name
]);
$options
[
$name
][]
=
$value
;
}
else
$options
[
$name
]
=
$value
;
}
else
if
(
isset
(
$action
))
$params
[]
=
$arg
;
else
$action
=
$arg
;
}
if
(
!
isset
(
$action
))
$action
=
$this
->
defaultAction
;
return
array
(
$action
,
$options
,
$params
);
}
/**
* @return string the command name.
*/
public
function
getName
()
{
return
$this
->
_name
;
}
/**
* Provides the command description.
* This method may be overridden to return the actual command description.
* @return string the command description. Defaults to 'Usage: php entry-script.php command-name'.
...
...
@@ -209,28 +114,6 @@ class Controller extends \yii\base\Controller
}
/**
* Renders a view file.
* @param string $_viewFile_ view file path
* @param array $_data_ optional data to be extracted as local view variables
* @param boolean $_return_ whether to return the rendering result instead of displaying it
* @return mixed the rendering result if required. Null otherwise.
*/
public
function
renderFile
(
$_viewFile_
,
$_data_
=
null
,
$_return_
=
false
)
{
if
(
is_array
(
$_data_
))
extract
(
$_data_
,
EXTR_PREFIX_SAME
,
'data'
);
else
$data
=
$_data_
;
if
(
$_return_
)
{
ob_start
();
ob_implicit_flush
(
false
);
require
(
$_viewFile_
);
return
ob_get_clean
();
}
else
require
(
$_viewFile_
);
}
/**
* Reads input via the readline PHP extension if that's available, or fgets() if readline is not installed.
*
* @param string $message to echo out before waiting for user input
...
...
framework/util/ReflectionHelper.php
View file @
be8dd940
...
...
@@ -9,6 +9,8 @@
namespace
yii\util
;
use
yii\base\Exception
;
/**
* ReflectionHelper
*
...
...
@@ -19,46 +21,83 @@ class ReflectionHelper
{
/**
* Prepares parameters so that they can be bound to the specified method.
* This method
mainly helps method parameter binding. It converts `$params`
*
into an array which can be passed to `call_user_func_array()` when calling
*
the specified method.
The conversion is based on the matching of method parameter names
* This method
converts the input parameters into an array that can later be
*
passed to `call_user_func_array()` when calling the specified method.
* The conversion is based on the matching of method parameter names
* and the input array keys. For example,
*
* ~~~
* class Foo {
* function bar($a, $b) { ... }
* }
*
* $method = new \ReflectionMethod('Foo', 'bar');
* $object = new Foo;
* $params = array('b' => 2, 'c' => 3, 'a' => 1);
* var_export(ReflectionHelper::
bindMethodParams($method
, $params));
* //
would output: array('a' => 1, 'b' => 2)
* var_export(ReflectionHelper::
extractMethodParams($object, 'bar'
, $params));
* //
output: array('a' => 1, 'b' => 2);
* ~~~
*
* @param \ReflectionMethod $method the method reflection
* @param object|string $object the object or class name that owns the specified method
* @param string $method the method name
* @param array $params the parameters in terms of name-value pairs
* @return array|boolean the parameters that can be passed to the method via `call_user_func_array()`.
* False is returned if the input parameters do not follow the method declaration.
* @return array parameters that are needed by the method only and
* can be passed to the method via `call_user_func_array()`.
* @throws Exception if any required method parameter is not found in the given parameters
*/
public
static
function
bindParams
(
$method
,
$params
)
public
static
function
extractMethodParams
(
$object
,
$method
,
$params
)
{
$m
=
new
\ReflectionMethod
(
$object
,
$method
);
$ps
=
array
();
foreach
(
$m
ethod
->
getParameters
()
as
$param
)
{
foreach
(
$m
->
getParameters
()
as
$param
)
{
$name
=
$param
->
getName
();
if
(
array_key_exists
(
$name
,
$params
))
{
if
(
$param
->
isArray
())
{
$ps
[
$name
]
=
is_array
(
$params
[
$name
])
?
$params
[
$name
]
:
array
(
$params
[
$name
]);
}
elseif
(
!
is_array
(
$params
[
$name
]))
{
$ps
[
$name
]
=
$params
[
$name
];
}
else
{
return
false
;
}
$ps
[
$name
]
=
$params
[
$name
];
}
elseif
(
$param
->
isDefaultValueAvailable
())
{
$ps
[
$name
]
=
$param
->
getDefaultValue
();
}
else
{
return
false
;
throw
new
Exception
(
\Yii
::
t
(
'yii'
,
'Missing required parameter "{name}".'
,
array
(
'{name'
=>
$name
)))
;
}
}
return
$ps
;
}
/**
* Initializes an object with the given parameters.
* Only the public non-static properties of the object will be initialized, and their names must
* match the given parameter names. For example,
*
* ~~~
* class Foo {
* public $a;
* protected $b;
* }
* $object = new Foo;
* $params = array('b' => 2, 'c' => 3, 'a' => 1);
* $remaining = ReflectionHelper::bindObjectParams($object, $params);
* var_export($object); // output: $object->a = 1; $object->b = null;
* var_export($remaining); // output: array('b' => 2, 'c' => 3);
* ~~~
*
* @param object $object the object whose properties are to be initialized
* @param array $params the input parameters to be used to initialize the object
* @return array the remaining unused input parameters
*/
public
static
function
initObjectWithParams
(
$object
,
$params
)
{
if
(
empty
(
$params
))
{
return
array
();
}
$class
=
new
\ReflectionClass
(
get_class
(
$object
));
foreach
(
$params
as
$name
=>
$value
)
{
if
(
$class
->
hasProperty
(
$name
))
{
$property
=
$class
->
getProperty
(
$name
);
if
(
$property
->
isPublic
()
&&
!
$property
->
isStatic
())
{
$object
->
$name
=
$value
;
unset
(
$params
[
$name
]);
}
}
}
return
$params
;
}
}
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