PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/qeephp/library/web/view_render_php.php

http://enaj.googlecode.com/
PHP | 478 lines | 221 code | 47 blank | 210 comment | 15 complexity | b7b37590981f0fa871f714d3c506870e MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. // $Id: view_render_php.php 2445 2009-04-27 08:12:19Z dualface $
  3. /**
  4. * ?? QView_Render_PHP ?
  5. *
  6. * @link http://qeephp.com/
  7. * @copyright Copyright (c) 2006-2009 Qeeyuan Inc. {@link http://www.qeeyuan.com}
  8. * @license New BSD License {@link http://qeephp.com/license/}
  9. * @version $Id: view_render_php.php 2445 2009-04-27 08:12:19Z dualface $
  10. * @package mvc
  11. */
  12. /**
  13. * QView_Render_PHP ???????????
  14. *
  15. * @author YuLei Liao <liaoyulei@qeeyuan.com>
  16. * @version $Id: view_render_php.php 2445 2009-04-27 08:12:19Z dualface $
  17. * @package mvc
  18. */
  19. class QView_Render_PHP
  20. {
  21. /**
  22. * ????????
  23. *
  24. * @var string
  25. */
  26. public $view_dir;
  27. /**
  28. * ???????
  29. *
  30. * @var array
  31. */
  32. public $headers;
  33. /**
  34. * ????????
  35. *
  36. * @var string
  37. */
  38. public $file_extname = 'php';
  39. /**
  40. * ????
  41. *
  42. * @var array
  43. */
  44. protected $_vars;
  45. /**
  46. * ??
  47. *
  48. * @var string
  49. */
  50. protected $_viewname;
  51. /**
  52. * ????????
  53. *
  54. * @var string
  55. */
  56. protected $_view_layouts;
  57. /**
  58. * ????????
  59. *
  60. * @var QView_Render_PHP_Parser
  61. */
  62. protected $_parser;
  63. /**
  64. * ????
  65. *
  66. * @param array $config
  67. */
  68. function __construct(array $config = null)
  69. {
  70. if (is_array($config))
  71. {
  72. foreach ($config as $key => $value)
  73. {
  74. $this->{$key} = $value;
  75. }
  76. }
  77. $this->cleanVars();
  78. }
  79. /**
  80. * ??????
  81. *
  82. * @param string $viewname
  83. *
  84. * @return QView_Render_PHP
  85. */
  86. function setViewname($viewname)
  87. {
  88. $this->_viewname = $viewname;
  89. return $this;
  90. }
  91. /**
  92. * ??????
  93. *
  94. * @param string|array $key
  95. * @param mixed $data
  96. *
  97. * @return QView_Render_PHP
  98. */
  99. function assign($key, $data = null)
  100. {
  101. if (is_array($key))
  102. {
  103. $this->_vars = array_merge($this->_vars, $key);
  104. }
  105. else
  106. {
  107. $this->_vars[$key] = $data;
  108. }
  109. return $this;
  110. }
  111. /**
  112. * ????????
  113. *
  114. * @return QView_Render_PHP
  115. */
  116. function cleanVars()
  117. {
  118. $context = QContext::instance();
  119. $this->_vars = array(
  120. '_ctx' => $context,
  121. '_BASE_DIR' => $context->baseDir(),
  122. '_BASE_URI' => $context->baseUri(),
  123. '_REQUEST_URI' => $context->requestUri(),
  124. );
  125. return $this;
  126. }
  127. /**
  128. * ????
  129. *
  130. * @param string $viewname
  131. * @param array $vars
  132. * @param array $config
  133. */
  134. function display($viewname = null, array $vars = null, array $config = null)
  135. {
  136. if (empty($viewname))
  137. {
  138. $viewname = $this->_viewname;
  139. }
  140. if (Q::ini('runtime_response_header'))
  141. {
  142. header('Content-Type: text/html; charset=' . Q::ini('i18n_response_charset'));
  143. }
  144. echo $this->fetch($viewname, $vars, $config);
  145. }
  146. /**
  147. * ??
  148. */
  149. function execute()
  150. {
  151. $this->display($this->_viewname);
  152. }
  153. /**
  154. * ???????????
  155. *
  156. * @param string $viewname
  157. * @param array $vars
  158. * @param array $config
  159. *
  160. * @return string
  161. */
  162. function fetch($viewname, array $vars = null, array $config = null)
  163. {
  164. $this->_before_render();
  165. $view_dir = isset($config['view_dir']) ? $config['view_dir'] : $this->view_dir;
  166. $extname = isset($config['file_extname']) ? $config['file_extname'] : $this->file_extname;
  167. $filename = "{$view_dir}/{$viewname}.{$extname}";
  168. if (file_exists($filename))
  169. {
  170. if (!is_array($vars))
  171. {
  172. $vars = $this->_vars;
  173. }
  174. if (is_null($this->_parser))
  175. {
  176. $this->_parser = new QView_Render_PHP_Parser($view_dir);
  177. }
  178. $output = $this->_parser->assign($vars)->parse($filename);
  179. }
  180. else
  181. {
  182. $output = '';
  183. }
  184. $this->_after_render($output);
  185. return $output;
  186. }
  187. /**
  188. * ??????
  189. *
  190. * ???????????
  191. */
  192. protected function _before_render()
  193. {
  194. }
  195. /**
  196. * ??????
  197. *
  198. * ???????????
  199. *
  200. * @param string $output
  201. */
  202. protected function _after_render(& $output)
  203. {
  204. }
  205. }
  206. /**
  207. * QView_Render_PHP_Parser ?????????
  208. *
  209. * @author YuLei Liao <liaoyulei@qeeyuan.com>
  210. * @version $Id: view_render_php.php 2445 2009-04-27 08:12:19Z dualface $
  211. * @package mvc
  212. */
  213. class QView_Render_PHP_Parser
  214. {
  215. /**
  216. * ???????
  217. *
  218. * @var string
  219. */
  220. private $_extname;
  221. /**
  222. * ????
  223. *
  224. * @var array
  225. */
  226. private $_stacks = array();
  227. /**
  228. * ???????
  229. *
  230. * @var int
  231. */
  232. private $_current;
  233. /**
  234. * ????
  235. *
  236. * @var array
  237. */
  238. private $_vars;
  239. /**
  240. * ????????
  241. *
  242. * @var string
  243. */
  244. private $_view_dir;
  245. /**
  246. * ????
  247. */
  248. function __construct($view_dir)
  249. {
  250. $this->_view_dir = $view_dir;
  251. }
  252. /**
  253. * ????????????
  254. *
  255. * @param array $vars
  256. *
  257. * @return QView_Render_PHP_Parser
  258. */
  259. function assign(array $vars)
  260. {
  261. $this->_vars = $vars;
  262. return $this;
  263. }
  264. /**
  265. * ????????????????
  266. *
  267. * @return string
  268. */
  269. function extname()
  270. {
  271. return $this->_extname;
  272. }
  273. /**
  274. * ?????????????
  275. *
  276. * @param string $filename
  277. * @param string $view_id
  278. * @param array $inherited_stack
  279. *
  280. * @return string
  281. */
  282. function parse($filename, $view_id = null, array $inherited_stack = null)
  283. {
  284. if (!$view_id) $view_id = mt_rand();
  285. $stack = array(
  286. 'id' => $view_id,
  287. 'contents' => '',
  288. 'extends' => '',
  289. 'blocks_stacks' => array(),
  290. 'blocks' => array(),
  291. 'blocks_config' => array(),
  292. 'nested_blocks' => array(),
  293. );
  294. array_push($this->_stacks, $stack);
  295. $this->_current = count($this->_stacks) - 1;
  296. unset($stack);
  297. ob_start();
  298. $this->_include($filename);
  299. $stack = $this->_stacks[$this->_current];
  300. $stack['contents'] = ob_get_clean(); //????????extends)??????contents?????????????contents??????
  301. // ???????????????????????????????
  302. if (is_array($inherited_stack))
  303. {
  304. foreach ($inherited_stack['blocks'] as $block_name => $contents)
  305. {
  306. if (isset($stack['blocks_config'][$block_name]))
  307. {
  308. switch (strtolower($stack['blocks_config'][$block_name]))
  309. {
  310. case 'append':
  311. $stack['blocks'][$block_name] .= $contents;
  312. break;
  313. case 'replace':
  314. default:
  315. $stack['blocks'][$block_name] = $contents;
  316. }
  317. }
  318. else
  319. {
  320. $stack['blocks'][$block_name] = $contents;
  321. }
  322. }
  323. }
  324. // ????? block??????
  325. while (list($child, $parent) = array_pop($stack['nested_blocks']))
  326. {
  327. $stack['blocks'][$parent] = str_replace("%block_contents_placeholder_{$child}_{$view_id}%",
  328. $stack['blocks'][$child], $stack['blocks'][$parent]);
  329. unset($stack['blocks'][$child]);
  330. }
  331. // ????????????
  332. $this->_stacks[$this->_current] = $stack;
  333. if ($stack['extends'])
  334. {
  335. // ????????????????????????
  336. $filename = "{$this->_view_dir}/{$stack['extends']}.{$this->_extname}";
  337. return $this->parse($filename, $view_id, $this->_stacks[$this->_current]);
  338. }
  339. else
  340. {
  341. // ??????????? extends ?
  342. $last = array_pop($this->_stacks);
  343. foreach ($last['blocks'] as $block_name => $contents)
  344. {
  345. $last['contents'] = str_replace("%block_contents_placeholder_{$block_name}_{$last['id']}%",
  346. $contents, $last['contents']);
  347. }
  348. $this->_stacks = array();
  349. return $last['contents'];
  350. }
  351. }
  352. /**
  353. * ?????
  354. *
  355. * @param string $tplname
  356. *
  357. * @access public
  358. */
  359. protected function _extends($tplname)
  360. {
  361. $this->_stacks[$this->_current]['extends'] = $tplname;
  362. }
  363. /**
  364. * ????????
  365. *
  366. * @param string $block_name
  367. * @param mixed $config
  368. *
  369. * @access public
  370. */
  371. protected function _block($block_name, $config = null)
  372. {
  373. $stack =& $this->_stacks[$this->_current];
  374. if (!empty($stack['blocks_stacks']))
  375. {
  376. // ??????? block????????????
  377. $last = $stack['blocks_stacks'][count($stack['blocks_stacks']) - 1];
  378. $stack['nested_blocks'][] = array($block_name, $last);
  379. }
  380. $this->_stacks[$this->_current]['blocks_config'][$block_name] = $config;
  381. array_push($stack['blocks_stacks'], $block_name);
  382. ob_start();
  383. }
  384. /**
  385. * ??????
  386. *
  387. * @access public
  388. */
  389. protected function _endblock()
  390. {
  391. $block_name = array_pop($this->_stacks[$this->_current]['blocks_stacks']);
  392. $this->_stacks[$this->_current]['blocks'][$block_name] = ob_get_clean();
  393. echo "%block_contents_placeholder_{$block_name}_{$this->_stacks[$this->_current]['id']}%";
  394. }
  395. /**
  396. * ??????
  397. *
  398. * @param string $control_type
  399. * @param string $id
  400. * @param array $args
  401. *
  402. * @access public
  403. */
  404. protected function _control($control_type, $id = null, array $args = array())
  405. {
  406. Q::control($control_type, $id, $args)->display($this);
  407. }
  408. /**
  409. * ????????
  410. *
  411. * @param string $element_name
  412. * @param array $vars
  413. *
  414. * @access public
  415. */
  416. protected function _element($element_name, array $vars = null)
  417. {
  418. $filename = "{$this->_view_dir}/_elements/{$element_name}_element.{$this->_extname}";
  419. $this->_include($filename, $vars);
  420. }
  421. /**
  422. * ??????
  423. */
  424. private function _include($___filename, array $___vars = null)
  425. {
  426. $this->_extname = pathinfo($___filename, PATHINFO_EXTENSION);
  427. extract($this->_vars);
  428. if (is_array($___vars)) extract($___vars);
  429. include $___filename;
  430. }
  431. }