PageRenderTime 54ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/wind/base/AbstractWindApplication.php

https://github.com/cuijinquan/nextwind
PHP | 262 lines | 130 code | 17 blank | 115 comment | 27 complexity | 0305ccf4707bd23b510b87dbfa0d4757 MD5 | raw file
  1. <?php
  2. /**
  3. * 应用基础接口
  4. *
  5. * 应用基础接口,该接口包含4个接口<i>run,getRequest,getResponse,getWindFactory</i>,自定义应用类型需要实现该接口.
  6. * 基础实现有<i>WindWebApplication</i>
  7. * @author Qiong Wu <papa0924@gmail.com>
  8. * @copyright ©2003-2103 phpwind.com
  9. * @license http://www.windframework.com
  10. * @version $Id: AbstractWindApplication.php 3919 2013-01-25 03:09:56Z yishuo $
  11. * @package base
  12. */
  13. abstract class AbstractWindApplication extends WindModule {
  14. /**
  15. * 请求对象
  16. *
  17. * @var WindHttpRequest
  18. */
  19. protected $request;
  20. /**
  21. * 响应对象
  22. *
  23. * @var WindHttpResponse
  24. */
  25. protected $response;
  26. /**
  27. * 组建工厂对象
  28. *
  29. * @var WindFactory
  30. */
  31. protected $factory = null;
  32. /**
  33. * 路由对象
  34. *
  35. * @var WindRouter
  36. */
  37. protected $handlerAdapter = null;
  38. /**
  39. * 应用初始化操作
  40. *
  41. * @param WindHttpRequest $request
  42. * @param WindHttpResponse $response
  43. * @param WindFactory $factory
  44. */
  45. public function __construct($request, $response, $factory) {
  46. $this->response = $response;
  47. $this->request = $request;
  48. $this->factory = $factory;
  49. }
  50. /**
  51. * 请求处理完毕后,进一步分发
  52. *
  53. * @param WindForward $forward
  54. * @param boolean $display
  55. */
  56. abstract public function doDispatch($forward);
  57. /**
  58. * 处理错误请求
  59. * 根据错误请求的相关信息,将程序转向到错误处理句柄进行错误处理
  60. *
  61. * @param WindErrorMessage $errorMessage
  62. * @param int $errorcode
  63. * @return void
  64. */
  65. abstract protected function sendErrorMessage($errorMessage, $errorcode);
  66. /*
  67. * (non-PHPdoc) @see IWindApplication::run()
  68. */
  69. public function run($handlerAdapter = null) {
  70. $handlerAdapter !== null && $this->handlerAdapter = $handlerAdapter;
  71. $module = $this->getModules();
  72. $handlerPath = $module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . $module['controller-suffix'];
  73. $className = Wind::import($handlerPath);
  74. if (!class_exists($className)) throw new WindException(
  75. 'Your requested \'' . $handlerPath . '\' was not found on this server.', 404);
  76. $handler = new $className();
  77. $handler->setDelayAttributes(
  78. array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward')));
  79. $handlerAdapter !== null && $this->resolveActionFilters($handler);
  80. try {
  81. $forward = $handler->doAction($this->handlerAdapter);
  82. $this->doDispatch($forward);
  83. } catch (WindForwardException $e) {
  84. $this->doDispatch($e->getForward());
  85. } catch (WindActionException $e) {
  86. $this->sendErrorMessage(($e->getError() ? $e->getError() : $e->getMessage()), $e->getCode());
  87. } catch (WindException $e) {
  88. $this->sendErrorMessage($e->getMessage(), $e->getCode());
  89. }
  90. }
  91. /**
  92. * 添加module配置
  93. * <code>
  94. * <controller-path>controller</controller-path>
  95. * <!-- 指定该模块下的controller的后缀格式 -->
  96. * <controller-suffix>Controller</controller-suffix>
  97. * <!-- 配置该模块的error处理的action controller类 -->
  98. * <error-handler>WIND:web.WindErrorHandler</error-handler>
  99. * <!-- 试图相关配置,config中配置可以根据自己的需要进行配置或是使用缺省 -->
  100. * <!-- 可以在这里进行view的配置,该配置只会影响该module下的view行为,该配置可以设置也可以不设置 -->
  101. * <!-- 指定模板路径 -->
  102. * <template-dir>template</template-dir>
  103. * <!-- 指定模板后缀 -->
  104. * <template-ext>htm</template-ext></code>
  105. *
  106. * @param string $name
  107. * module名称
  108. * @param array $config
  109. * 配置数组
  110. * @param boolean $replace
  111. * 如果module已经存在是否覆盖他 默认值为false不进行覆盖
  112. * @return array
  113. */
  114. public function setModules($name, $config, $replace = false) {
  115. if ($replace || !isset($this->_config['modules'][$name])) {
  116. $this->_config['modules'][$name] = (array) $config;
  117. }
  118. return $this->_config['modules'][$name];
  119. }
  120. /**
  121. * 获得module配置,$name为空时返回当前module配置
  122. *
  123. * @param string $name
  124. * module名称 默认为空
  125. * @param boolean $merge
  126. * 合并默认值
  127. * @return array
  128. * @throws WindActionException
  129. * @throws WindException
  130. */
  131. public function getModules($name = '') {
  132. if ($name === '') $name = $this->handlerAdapter->getModule();
  133. if ($name === 'pattern') $name = $this->handlerAdapter->getDefaultModule();
  134. $_module = $this->getConfig('modules', $name, array());
  135. if (!isset($_module['_verified']) || $_module['_verified'] !== true) {
  136. if (empty($_module) && !empty($this->_config['modules']['pattern'])) {
  137. $_module = $this->_config['modules']['pattern'];
  138. }
  139. $_flag = empty($_module);
  140. $_module = WindUtility::mergeArray($this->_config['modules']['default'], $_module);
  141. $_module_str = implode('#', $_module);
  142. if (strpos($_module_str, '{') !== false) {
  143. preg_match_all('/{(\w+)}/i', $_module_str, $matches);
  144. if (!empty($matches[1])) {
  145. $_replace = array();
  146. foreach ($matches[1] as $key => $value) {
  147. if ($value === $this->handlerAdapter->getModuleKey())
  148. $_replace['{' . $value . '}'] = $this->handlerAdapter->getModule();
  149. elseif ($value === $this->handlerAdapter->getControllerKey())
  150. $_replace['{' . $value . '}'] = $this->handlerAdapter->getController();
  151. elseif ($value === $this->handlerAdapter->getActionKey())
  152. $_replace['{' . $value . '}'] = $this->handlerAdapter->getAction();
  153. else
  154. $_replace['{' . $value . '}'] = $this->request->getGet($value);
  155. }
  156. $_module_str = strtr($_module_str, $_replace);
  157. $_module = array_combine(array_keys($_module), explode('#', $_module_str));
  158. }
  159. } elseif ($_flag)
  160. throw new WindException('Your request was not found on this server.', 404);
  161. $_module['_verified'] = true;
  162. $this->_config['modules'][$name] = $_module;
  163. }
  164. return $_module;
  165. }
  166. /**
  167. * 手动注册actionFilter
  168. * 参数为数组格式:
  169. *
  170. * @param array $filters
  171. */
  172. public function registeActionFilter($filters) {
  173. if (!$filters) return;
  174. if (empty($this->_config['filters']))
  175. $this->_config['filters'] = $filters;
  176. else
  177. $this->_config['filters'] += $filters;
  178. }
  179. /**
  180. * 解析action过滤链的配置信息
  181. *
  182. * @param WindSimpleController $handler
  183. * @return void
  184. */
  185. protected function resolveActionFilters(&$handler) {
  186. if (!$filters = $this->getConfig('filters')) return;
  187. /* @var $cache AbstractWindCache */
  188. $_filters = array();
  189. if ($cache = Wind::getComponent('windCache')) {
  190. $_filters = $cache->get('filters');
  191. }
  192. $_token = $this->handlerAdapter->getModule() . '/' . $this->handlerAdapter->getController() . '/' . $this->handlerAdapter->getAction();
  193. if (!isset($_filters[$_token])) {
  194. foreach ($filters as $_filter) {
  195. if (empty($_filter['class'])) continue;
  196. $_pattern = empty($_filter['pattern']) ? '' : $_filter['pattern'];
  197. unset($_filter['pattern']);
  198. if ($_pattern) {
  199. $_pattern = str_replace(array('*', '/'), array('\w*', '\/'), $_pattern);
  200. if (in_array($_pattern[0], array('~', '!'))) {
  201. $_pattern = substr($_pattern, 1);
  202. if (preg_match('/^' . $_pattern . '$/i', $_token)) continue;
  203. } else {
  204. if (!preg_match('/^' . $_pattern . '$/i', $_token)) continue;
  205. }
  206. }
  207. $_filters[$_token][] = $_filter;
  208. }
  209. $cache && $cache->set('filters', $_filters);
  210. }
  211. if (empty($_filters[$_token])) return;
  212. /* @var $proxy WindClassProxy */
  213. $proxy = WindFactory::createInstance(Wind::import('WIND:filter.proxy.WindClassProxy'));
  214. $proxy->registerTargetObject($handler);
  215. foreach ($_filters[$_token] as $value) {
  216. $proxy->registerEventListener(
  217. $this->factory->createInstance(Wind::import($value['class']),
  218. array($handler->getForward(), $handler->getErrorMessage(), $this->handlerAdapter, $value)),
  219. 'doAction');
  220. }
  221. $handler = $proxy;
  222. }
  223. /**
  224. *
  225. * @return WindHttpRequest
  226. */
  227. public function getRequest() {
  228. return $this->request;
  229. }
  230. /**
  231. *
  232. * @return WindHttpResponse
  233. */
  234. public function getResponse() {
  235. return $this->response;
  236. }
  237. /**
  238. *
  239. * @return WindFactory
  240. */
  241. public function getFactory() {
  242. return $this->factory;
  243. }
  244. }
  245. ?>