Action.class.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. // $Id$
  12. /**
  13. +------------------------------------------------------------------------------
  14. * ThinkPHP Action控制器基类 抽象类
  15. +------------------------------------------------------------------------------
  16. * @category Think
  17. * @package Think
  18. * @subpackage Core
  19. * @author liu21st <liu21st@gmail.com>
  20. * @version $Id$
  21. +------------------------------------------------------------------------------
  22. */
  23. abstract class Action extends Think
  24. {//类定义开始
  25. // 视图实例对象
  26. protected $view = null;
  27. // 当前Action名称
  28. private $name = '';
  29. /**
  30. +----------------------------------------------------------
  31. * 架构函数 取得模板对象实例
  32. +----------------------------------------------------------
  33. * @access public
  34. +----------------------------------------------------------
  35. */
  36. public function __construct()
  37. {
  38. //实例化视图类
  39. $this->view = Think::instance('View');
  40. //控制器初始化
  41. if(method_exists($this,'_initialize'))
  42. $this->_initialize();
  43. }
  44. /**
  45. +----------------------------------------------------------
  46. * 获取当前Action名称
  47. +----------------------------------------------------------
  48. * @access protected
  49. +----------------------------------------------------------
  50. */
  51. protected function getActionName() {
  52. if(empty($this->name)) {
  53. // 获取Action名称
  54. $this->name = substr(get_class($this),0,-6);
  55. }
  56. return $this->name;
  57. }
  58. /**
  59. +----------------------------------------------------------
  60. * 是否AJAX请求
  61. +----------------------------------------------------------
  62. * @access protected
  63. +----------------------------------------------------------
  64. * @return bool
  65. +----------------------------------------------------------
  66. */
  67. protected function isAjax() {
  68. if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) ) {
  69. if('xmlhttprequest' == strtolower($_SERVER['HTTP_X_REQUESTED_WITH']))
  70. return true;
  71. }
  72. if(!empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')]))
  73. // 判断Ajax方式提交
  74. return true;
  75. return false;
  76. }
  77. /**
  78. +----------------------------------------------------------
  79. * 模板显示
  80. * 调用内置的模板引擎显示方法,
  81. +----------------------------------------------------------
  82. * @access protected
  83. +----------------------------------------------------------
  84. * @param string $templateFile 指定要调用的模板文件
  85. * 默认为空 由系统自动定位模板文件
  86. * @param string $charset 输出编码
  87. * @param string $contentType 输出类型
  88. +----------------------------------------------------------
  89. * @return void
  90. +----------------------------------------------------------
  91. */
  92. protected function display($templateFile='',$charset='',$contentType='text/html')
  93. {
  94. $this->view->display($templateFile,$charset,$contentType);
  95. }
  96. /**
  97. +----------------------------------------------------------
  98. * 获取输出页面内容
  99. * 调用内置的模板引擎fetch方法,
  100. +----------------------------------------------------------
  101. * @access protected
  102. +----------------------------------------------------------
  103. * @param string $templateFile 指定要调用的模板文件
  104. * 默认为空 由系统自动定位模板文件
  105. * @param string $charset 输出编码
  106. * @param string $contentType 输出类型
  107. +----------------------------------------------------------
  108. * @return string
  109. +----------------------------------------------------------
  110. */
  111. protected function fetch($templateFile='',$charset='',$contentType='text/html')
  112. {
  113. return $this->view->fetch($templateFile,$charset,$contentType);
  114. }
  115. /**
  116. +----------------------------------------------------------
  117. * 创建静态页面
  118. +----------------------------------------------------------
  119. * @access protected
  120. +----------------------------------------------------------
  121. * @htmlfile 生成的静态文件名称
  122. * @htmlpath 生成的静态文件路径
  123. * @param string $templateFile 指定要调用的模板文件
  124. * 默认为空 由系统自动定位模板文件
  125. * @param string $charset 输出编码
  126. * @param string $contentType 输出类型
  127. +----------------------------------------------------------
  128. * @return string
  129. +----------------------------------------------------------
  130. */
  131. protected function buildHtml($htmlfile='',$htmlpath='',$templateFile='',$charset='',$contentType='text/html') {
  132. return $this->view->buildHtml($htmlfile,$htmlpath,$templateFile,$charset,$contentType);
  133. }
  134. /**
  135. +----------------------------------------------------------
  136. * 模板变量赋值
  137. +----------------------------------------------------------
  138. * @access protected
  139. +----------------------------------------------------------
  140. * @param mixed $name 要显示的模板变量
  141. * @param mixed $value 变量的值
  142. +----------------------------------------------------------
  143. * @return void
  144. +----------------------------------------------------------
  145. */
  146. protected function assign($name,$value='')
  147. {
  148. $this->view->assign($name,$value);
  149. }
  150. public function __set($name,$value) {
  151. $this->view->assign($name,$value);
  152. }
  153. /**
  154. +----------------------------------------------------------
  155. * 取得模板显示变量的值
  156. +----------------------------------------------------------
  157. * @access protected
  158. +----------------------------------------------------------
  159. * @param string $name 模板显示变量
  160. +----------------------------------------------------------
  161. * @return mixed
  162. +----------------------------------------------------------
  163. */
  164. protected function get($name)
  165. {
  166. return $this->view->get($name);
  167. }
  168. /**
  169. +----------------------------------------------------------
  170. * Trace变量赋值
  171. +----------------------------------------------------------
  172. * @access protected
  173. +----------------------------------------------------------
  174. * @param mixed $name 要显示的模板变量
  175. * @param mixed $value 变量的值
  176. +----------------------------------------------------------
  177. * @return void
  178. +----------------------------------------------------------
  179. */
  180. protected function trace($name,$value='')
  181. {
  182. $this->view->trace($name,$value);
  183. }
  184. /**
  185. +----------------------------------------------------------
  186. * 魔术方法 有不存在的操作的时候执行
  187. +----------------------------------------------------------
  188. * @access public
  189. +----------------------------------------------------------
  190. * @param string $method 方法名
  191. * @param array $parms 参数
  192. +----------------------------------------------------------
  193. * @return mixed
  194. +----------------------------------------------------------
  195. */
  196. public function __call($method,$parms) {
  197. if( 0 === strcasecmp($method,ACTION_NAME)) {
  198. // 检查扩展操作方法
  199. $_action = C('_actions_');
  200. if($_action) {
  201. // 'module:action'=>'callback'
  202. if(isset($_action[MODULE_NAME.':'.ACTION_NAME])) {
  203. $action = $_action[MODULE_NAME.':'.ACTION_NAME];
  204. }elseif(isset($_action[ACTION_NAME])){
  205. // 'action'=>'callback'
  206. $action = $_action[ACTION_NAME];
  207. }
  208. if(!empty($action)) {
  209. call_user_func($action);
  210. return ;
  211. }
  212. }
  213. // 如果定义了_empty操作 则调用
  214. if(method_exists($this,'_empty')) {
  215. $this->_empty($method,$parms);
  216. }else {
  217. // 检查是否存在默认模版 如果有直接输出模版
  218. if(file_exists_case(C('TMPL_FILE_NAME')))
  219. $this->display();
  220. else
  221. // 抛出异常
  222. throw_exception(L('_ERROR_ACTION_').ACTION_NAME);
  223. }
  224. }elseif(in_array(strtolower($method),array('ispost','isget','ishead','isdelete','isput'))){
  225. return strtolower($_SERVER['REQUEST_METHOD']) == strtolower(substr($method,2));
  226. }else{
  227. throw_exception(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_'));
  228. }
  229. }
  230. /**
  231. +----------------------------------------------------------
  232. * 操作错误跳转的快捷方法
  233. +----------------------------------------------------------
  234. * @access protected
  235. +----------------------------------------------------------
  236. * @param string $message 错误信息
  237. * @param Boolean $ajax 是否为Ajax方式
  238. +----------------------------------------------------------
  239. * @return void
  240. +----------------------------------------------------------
  241. */
  242. protected function error($message,$ajax=false)
  243. {
  244. $this->_dispatch_jump($message,0,$ajax);
  245. }
  246. /**
  247. +----------------------------------------------------------
  248. * 操作成功跳转的快捷方法
  249. +----------------------------------------------------------
  250. * @access protected
  251. +----------------------------------------------------------
  252. * @param string $message 提示信息
  253. * @param Boolean $ajax 是否为Ajax方式
  254. +----------------------------------------------------------
  255. * @return void
  256. +----------------------------------------------------------
  257. */
  258. protected function success($message,$ajax=false)
  259. {
  260. $this->_dispatch_jump($message,1,$ajax);
  261. }
  262. /**
  263. +----------------------------------------------------------
  264. * Ajax方式返回数据到客户端
  265. +----------------------------------------------------------
  266. * @access protected
  267. +----------------------------------------------------------
  268. * @param mixed $data 要返回的数据
  269. * @param String $info 提示信息
  270. * @param boolean $status 返回状态
  271. * @param String $status ajax返回类型 JSON XML
  272. +----------------------------------------------------------
  273. * @return void
  274. +----------------------------------------------------------
  275. */
  276. protected function ajaxReturn($data,$info='',$status=1,$type='')
  277. {
  278. // 保证AJAX返回后也能保存日志
  279. if(C('LOG_RECORD')) Log::save();
  280. $result = array();
  281. $result['status'] = $status;
  282. $result['info'] = $info;
  283. $result['data'] = $data;
  284. if(empty($type)) $type = C('DEFAULT_AJAX_RETURN');
  285. if(strtoupper($type)=='JSON') {
  286. // 返回JSON数据格式到客户端 包含状态信息
  287. header("Content-Type:text/html; charset=utf-8");
  288. exit(json_encode($result));
  289. }elseif(strtoupper($type)=='XML'){
  290. // 返回xml格式数据
  291. header("Content-Type:text/xml; charset=utf-8");
  292. exit(xml_encode($result));
  293. }elseif(strtoupper($type)=='EVAL'){
  294. // 返回可执行的js脚本
  295. header("Content-Type:text/html; charset=utf-8");
  296. exit($data);
  297. }else{
  298. // TODO 增加其它格式
  299. }
  300. }
  301. /**
  302. +----------------------------------------------------------
  303. * Action跳转(URL重定向) 支持指定模块和延时跳转
  304. +----------------------------------------------------------
  305. * @access protected
  306. +----------------------------------------------------------
  307. * @param string $url 跳转的URL表达式
  308. * @param array $params 其它URL参数
  309. * @param integer $delay 延时跳转的时间 单位为秒
  310. * @param string $msg 跳转提示信息
  311. +----------------------------------------------------------
  312. * @return void
  313. +----------------------------------------------------------
  314. */
  315. protected function redirect($url,$params=array(),$delay=0,$msg='') {
  316. if(C('LOG_RECORD')) Log::save();
  317. $url = U($url,$params);
  318. redirect($url,$delay,$msg);
  319. }
  320. /**
  321. +----------------------------------------------------------
  322. * 默认跳转操作 支持错误导向和正确跳转
  323. * 调用模板显示 默认为public目录下面的success页面
  324. * 提示页面为可配置 支持模板标签
  325. +----------------------------------------------------------
  326. * @param string $message 提示信息
  327. * @param Boolean $status 状态
  328. * @param Boolean $ajax 是否为Ajax方式
  329. +----------------------------------------------------------
  330. * @access private
  331. +----------------------------------------------------------
  332. * @return void
  333. +----------------------------------------------------------
  334. */
  335. private function _dispatch_jump($message,$status=1,$ajax=false)
  336. {
  337. // 判断是否为AJAX返回
  338. if($ajax || $this->isAjax()) $this->ajaxReturn('',$message,$status);
  339. // 提示标题
  340. $this->assign('msgTitle',$status? L('_OPERATION_SUCCESS_') : L('_OPERATION_FAIL_'));
  341. //如果设置了关闭窗口,则提示完毕后自动关闭窗口
  342. if($this->get('closeWin')) $this->assign('jumpUrl','javascript:window.close();');
  343. $this->assign('status',$status); // 状态
  344. $this->assign('message',$message);// 提示信息
  345. //保证输出不受静态缓存影响
  346. C('HTML_CACHE_ON',false);
  347. if($status) { //发送成功信息
  348. // 成功操作后默认停留1秒
  349. if(!$this->get('waitSecond')) $this->assign('waitSecond',"1");
  350. // 默认操作成功自动返回操作前页面
  351. if(!$this->get('jumpUrl')) $this->assign("jumpUrl",$_SERVER["HTTP_REFERER"]);
  352. $this->display(C('TMPL_ACTION_SUCCESS'));
  353. }else{
  354. //发生错误时候默认停留3秒
  355. if(!$this->get('waitSecond')) $this->assign('waitSecond',"3");
  356. // 默认发生错误的话自动返回上页
  357. if(!$this->get('jumpUrl')) $this->assign('jumpUrl',"javascript:history.back(-1);");
  358. $this->display(C('TMPL_ACTION_ERROR'));
  359. }
  360. if(C('LOG_RECORD')) Log::save();
  361. // 中止执行 避免出错后继续执行
  362. exit ;
  363. }
  364. }//类定义结束
  365. ?>