Browse Source

MVC WIP

tags/2.0.0-beta
Qiang Xue 12 years ago
parent
commit
ceac41b250
  1. 40
      framework/base/Application.php
  2. 91
      framework/base/Module.php

40
framework/base/Application.php

@ -9,6 +9,7 @@
namespace yii\base; namespace yii\base;
use Yii;
use yii\base\InvalidCallException; use yii\base\InvalidCallException;
use yii\util\StringHelper; use yii\util\StringHelper;
@ -128,7 +129,7 @@ class Application extends Module
*/ */
public function __construct($id, $basePath, $config = array()) public function __construct($id, $basePath, $config = array())
{ {
\Yii::$application = $this; Yii::$application = $this;
$this->id = $id; $this->id = $id;
$this->setBasePath($basePath); $this->setBasePath($basePath);
$this->registerDefaultAliases(); $this->registerDefaultAliases();
@ -213,7 +214,7 @@ class Application extends Module
{ {
$result = $this->createController($route); $result = $this->createController($route);
if ($result === false) { if ($result === false) {
throw new InvalidRequestException(\Yii::t('yii', 'Unable to resolve the request.')); throw new InvalidRequestException(Yii::t('yii', 'Unable to resolve the request.'));
} }
/** @var $controller Controller */ /** @var $controller Controller */
list($controller, $action) = $result; list($controller, $action) = $result;
@ -243,7 +244,7 @@ class Application extends Module
*/ */
public function setRuntimePath($path) public function setRuntimePath($path)
{ {
$p = \Yii::getAlias($path); $p = Yii::getAlias($path);
if ($p === false || !is_dir($p) || !is_writable($path)) { if ($p === false || !is_dir($p) || !is_writable($path)) {
throw new InvalidCallException("Application runtime path \"$path\" is invalid. Please make sure it is a directory writable by the Web server process."); throw new InvalidCallException("Application runtime path \"$path\" is invalid. Please make sure it is a directory writable by the Web server process.");
} else { } else {
@ -402,9 +403,9 @@ class Application extends Module
*/ */
public function registerDefaultAliases() public function registerDefaultAliases()
{ {
\Yii::$aliases['@application'] = $this->getBasePath(); Yii::$aliases['@application'] = $this->getBasePath();
\Yii::$aliases['@entry'] = dirname($_SERVER['SCRIPT_FILENAME']); Yii::$aliases['@entry'] = dirname($_SERVER['SCRIPT_FILENAME']);
\Yii::$aliases['@www'] = ''; Yii::$aliases['@www'] = '';
} }
/** /**
@ -480,17 +481,15 @@ class Application extends Module
return $this->runAction($route, $params, $childModule); return $this->runAction($route, $params, $childModule);
} }
/** @var $controller Controller */ $controller = $this->createController($id, $module);
if (isset($module->controllerMap[$id])) { if ($controller !== null) {
$controller = \Yii::createObject($module->controllerMap[$id], $id, $module); if ($route === '') {
} else { $route = $controller->defaultAction;
$controller = $this->createController($id, $module); if ($route == '') {
if ($controller === null) { throw new InvalidConfigException(get_class($controller) . '::defaultAction cannot be empty.');
throw new InvalidRequestException("Unable to resolve the request: $route"); }
} }
}
if (isset($controller)) {
$action = $this->createAction($route, $controller); $action = $this->createAction($route, $controller);
if ($action !== null) { if ($action !== null) {
return $action->runWithParams($params); return $action->runWithParams($params);
@ -516,7 +515,7 @@ class Application extends Module
public function createController($id, $module) public function createController($id, $module)
{ {
if (isset($module->controllerMap[$id])) { if (isset($module->controllerMap[$id])) {
return \Yii::createObject($module->controllerMap[$id], $id, $module); return Yii::createObject($module->controllerMap[$id], $id, $module);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id)) { } elseif (preg_match('/^[a-z0-9\\-_]+$/', $id)) {
$className = StringHelper::id2camel($id) . 'Controller'; $className = StringHelper::id2camel($id) . 'Controller';
$classFile = $module->controllerPath . DIRECTORY_SEPARATOR . $className . '.php'; $classFile = $module->controllerPath . DIRECTORY_SEPARATOR . $className . '.php';
@ -541,18 +540,11 @@ class Application extends Module
* @param string $id the action ID * @param string $id the action ID
* @param Controller $controller the controller that owns the action * @param Controller $controller the controller that owns the action
* @return Action the newly created action instance * @return Action the newly created action instance
* @throws InvalidConfigException if [[Controller::defaultAction]] is empty.
*/ */
public function createAction($id, $controller) public function createAction($id, $controller)
{ {
if ($id === '') {
$id = $controller->defaultAction;
if ($id == '') {
throw new InvalidConfigException(get_class($controller) . '::defaultAction cannot be empty.');
}
}
if (isset($controller->actionMap[$id])) { if (isset($controller->actionMap[$id])) {
return \Yii::createObject($controller->actionMap[$id], $id, $controller); return Yii::createObject($controller->actionMap[$id], $id, $controller);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id)) { } elseif (preg_match('/^[a-z0-9\\-_]+$/', $id)) {
$methodName = 'action' . StringHelper::id2camel($id); $methodName = 'action' . StringHelper::id2camel($id);
if (method_exists($controller, $methodName)) { if (method_exists($controller, $methodName)) {

91
framework/base/Module.php

@ -9,6 +9,8 @@
namespace yii\base; namespace yii\base;
use Yii;
use yii\util\StringHelper;
use yii\util\FileHelper; use yii\util\FileHelper;
/** /**
@ -167,12 +169,15 @@ abstract class Module extends Component
/** /**
* Returns an ID that uniquely identifies this module among all modules within the current application. * Returns an ID that uniquely identifies this module among all modules within the current application.
* Note that if the module is an application, an empty string will be returned.
* @return string the unique ID of the module. * @return string the unique ID of the module.
*/ */
public function getUniqueId() public function getUniqueId()
{ {
if ($this->module && !$this->module instanceof Application) { if ($this instanceof Application) {
return $this->module->getUniqueId() . "/{$this->id}"; return '';
} elseif ($this->module) {
return $this->module->getUniqueId() . '/' . $this->id;
} else { } else {
return $this->id; return $this->id;
} }
@ -533,4 +538,86 @@ abstract class Module extends Component
$this->getComponent($id); $this->getComponent($id);
} }
} }
/**
* Performs a controller action specified by a route.
* This method parses the specified route and creates the corresponding controller and action
* instances under the context of the specified module. It then runs the created action
* with the given parameters.
* @param string $route the route that specifies the action.
* @param array $params the parameters to be passed to the action
* @return integer the action
* @throws InvalidConfigException if the module's defaultRoute is empty or the controller's defaultAction is empty
* @throws InvalidRequestException if the requested route cannot be resolved into an action successfully
*/
public function runAction($route, $params = array())
{
$route = trim($route, '/');
if ($route === '') {
$route = trim($this->defaultRoute, '/');
if ($route == '') {
throw new InvalidConfigException(get_class($this) . '::defaultRoute cannot be empty.');
}
}
if (($pos = strpos($route, '/')) !== false) {
$id = substr($route, 0, $pos);
$route = substr($route, $pos + 1);
} else {
$id = $route;
$route = '';
}
$module = $this->getModule($id);
if ($module !== null) {
return $module->runAction($route, $params);
}
$controller = $this->createController($id);
if ($controller !== null) {
if ($route === '') {
$route = $controller->defaultAction;
if ($route == '') {
throw new InvalidConfigException(get_class($controller) . '::defaultAction cannot be empty.');
}
}
$action = $controller->createAction($route);
if ($action !== null) {
return $action->runWithParams($params);
}
}
throw new InvalidRequestException('Unable to resolve the request: ' . ltrim($this->getUniqueId() . '/' . $route, '/'));
}
/**
* Creates a controller instance based on the controller ID.
*
* The controller is created within the given 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.
*
* @param string $id the controller ID
* @return Controller the newly created controller instance
*/
public function createController($id)
{
if (isset($this->controllerMap[$id])) {
return Yii::createObject($this->controllerMap[$id], $id, $this);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id)) {
$className = StringHelper::id2camel($id) . 'Controller';
$classFile = $this->controllerPath . DIRECTORY_SEPARATOR . $className . '.php';
if (is_file($classFile)) {
$className = $this->controllerNamespace . '\\' . $className;
if (!class_exists($className, false)) {
require($classFile);
}
if (class_exists($className, false) && is_subclass_of($className, '\yii\base\Controller')) {
return new $className($id, $this);
}
}
}
return null;
}
} }

Loading…
Cancel
Save