PageRenderTime 29ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/ThinkPHP/Extend/Mode/Lite/Action.class.php

https://gitlab.com/llwhois/woaimm
PHP | 344 lines | 169 code | 18 blank | 157 comment | 32 complexity | 07c05a642ea2c5be8cf05967cdbd3713 MD5 | raw file
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2012 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. /**
  12. * ThinkPHP Action控制器基类 精简模式
  13. * @category Think
  14. * @package Think
  15. * @subpackage Core
  16. * @author liu21st <liu21st@gmail.com>
  17. */
  18. abstract class Action {
  19. // 当前Action名称
  20. private $name = '';
  21. protected $tVar = array(); // 模板输出变量
  22. /**
  23. * 架构函数 取得模板对象实例
  24. * @access public
  25. */
  26. public function __construct() {
  27. tag('action_begin');
  28. //控制器初始化
  29. if(method_exists($this,'_initialize'))
  30. $this->_initialize();
  31. }
  32. /**
  33. * 获取当前Action名称
  34. * @access protected
  35. */
  36. protected function getActionName() {
  37. if(empty($this->name)) {
  38. // 获取Action名称
  39. $this->name = substr(get_class($this),0,-6);
  40. }
  41. return $this->name;
  42. }
  43. /**
  44. * 是否AJAX请求
  45. * @access protected
  46. * @return bool
  47. */
  48. protected function isAjax() {
  49. if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) ) {
  50. if('xmlhttprequest' == strtolower($_SERVER['HTTP_X_REQUESTED_WITH']))
  51. return true;
  52. }
  53. if(!empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')]))
  54. // 判断Ajax方式提交
  55. return true;
  56. return false;
  57. }
  58. /**
  59. * 模板变量赋值
  60. * @access public
  61. * @param mixed $name
  62. * @param mixed $value
  63. */
  64. public function assign($name,$value=''){
  65. if(is_array($name)) {
  66. $this->tVar = array_merge($this->tVar,$name);
  67. }elseif(is_object($name)){
  68. foreach($name as $key =>$val)
  69. $this->tVar[$key] = $val;
  70. }else {
  71. $this->tVar[$name] = $value;
  72. }
  73. }
  74. public function __set($name,$value) {
  75. $this->assign($name,$value);
  76. }
  77. /**
  78. * 取得模板变量的值
  79. * @access public
  80. * @param string $name
  81. * @return mixed
  82. */
  83. public function get($name){
  84. if(isset($this->tVar[$name]))
  85. return $this->tVar[$name];
  86. else
  87. return false;
  88. }
  89. /**
  90. * 魔术方法 有不存在的操作的时候执行
  91. * @access public
  92. * @param string $method 方法名
  93. * @param array $args 参数
  94. * @return mixed
  95. */
  96. public function __call($method,$args) {
  97. if( 0 === strcasecmp($method,ACTION_NAME)) {
  98. if(method_exists($this,'_empty')) {
  99. // 如果定义了_empty操作 则调用
  100. $this->_empty($method,$args);
  101. }elseif(file_exists_case(C('TEMPLATE_NAME'))){
  102. // 检查是否存在默认模版 如果有直接输出模版
  103. $this->display();
  104. }else{
  105. // 抛出异常
  106. throw_exception(L('_ERROR_ACTION_').ACTION_NAME);
  107. }
  108. }else{
  109. switch(strtolower($method)) {
  110. // 判断提交方式
  111. case 'ispost':
  112. case 'isget':
  113. case 'ishead':
  114. case 'isdelete':
  115. case 'isput':
  116. return strtolower($_SERVER['REQUEST_METHOD']) == strtolower(substr($method,2));
  117. // 获取变量 支持过滤和默认值 调用方式 $this->_post($key,$filter,$default);
  118. case '_get': $input =& $_GET;break;
  119. case '_post':$input =& $_POST;break;
  120. case '_put': parse_str(file_get_contents('php://input'), $input);break;
  121. case '_request': $input =& $_REQUEST;break;
  122. case '_session': $input =& $_SESSION;break;
  123. case '_cookie': $input =& $_COOKIE;break;
  124. case '_server': $input =& $_SERVER;break;
  125. case '_globals': $input =& $GLOBALS;break;
  126. default:
  127. throw_exception(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_'));
  128. }
  129. if(isset($input[$args[0]])) { // 取值操作
  130. $data = $input[$args[0]];
  131. $filters = isset($args[1])?$args[1]:C('DEFAULT_FILTER');
  132. if($filters) {// 2012/3/23 增加多方法过滤支持
  133. $filters = explode(',',$filters);
  134. foreach($filters as $filter){
  135. if(function_exists($filter)) {
  136. $data = is_array($data)?array_map($filter,$data):$filter($data); // 参数过滤
  137. }
  138. }
  139. }
  140. }else{ // 变量默认值
  141. $data = isset($args[2])?$args[2]:NULL;
  142. }
  143. return $data;
  144. }
  145. }
  146. /**
  147. * 操作错误跳转的快捷方法
  148. * @access protected
  149. * @param string $message 错误信息
  150. * @param string $jumpUrl 页面跳转地址
  151. * @param Boolean $ajax 是否为Ajax方式
  152. * @return void
  153. */
  154. protected function error($message,$jumpUrl='',$ajax=false) {
  155. $this->dispatchJump($message,0,$jumpUrl,$ajax);
  156. }
  157. /**
  158. * 操作成功跳转的快捷方法
  159. * @access protected
  160. * @param string $message 提示信息
  161. * @param string $jumpUrl 页面跳转地址
  162. * @param Boolean $ajax 是否为Ajax方式
  163. * @return void
  164. */
  165. protected function success($message,$jumpUrl='',$ajax=false) {
  166. $this->dispatchJump($message,1,$jumpUrl,$ajax);
  167. }
  168. /**
  169. * Ajax方式返回数据到客户端
  170. * @access protected
  171. * @param mixed $data 要返回的数据
  172. * @param String $info 提示信息
  173. * @param boolean $status 返回状态
  174. * @param String $status ajax返回类型 JSON XML
  175. * @return void
  176. */
  177. protected function ajaxReturn($data,$info='',$status=1,$type='') {
  178. $result = array();
  179. $result['status'] = $status;
  180. $result['info'] = $info;
  181. $result['data'] = $data;
  182. //扩展ajax返回数据, 在Action中定义function ajaxAssign(&$result){} 方法 扩展ajax返回数据。
  183. if(method_exists($this,"ajaxAssign"))
  184. $this->ajaxAssign($result);
  185. if(empty($type)) $type = C('DEFAULT_AJAX_RETURN');
  186. if(strtoupper($type)=='JSON') {
  187. // 返回JSON数据格式到客户端 包含状态信息
  188. header("Content-Type:text/html; charset=utf-8");
  189. exit(json_encode($result));
  190. }elseif(strtoupper($type)=='XML'){
  191. // 返回xml格式数据
  192. header("Content-Type:text/xml; charset=utf-8");
  193. exit(xml_encode($result));
  194. }
  195. }
  196. /**
  197. * Action跳转(URL重定向) 支持指定模块和延时跳转
  198. * @access protected
  199. * @param string $url 跳转的URL表达式
  200. * @param array $params 其它URL参数
  201. * @param integer $delay 延时跳转的时间 单位为秒
  202. * @param string $msg 跳转提示信息
  203. * @return void
  204. */
  205. protected function redirect($url,$params=array(),$delay=0,$msg='') {
  206. $url = U($url,$params);
  207. redirect($url,$delay,$msg);
  208. }
  209. /**
  210. * 默认跳转操作 支持错误导向和正确跳转
  211. * 调用模板显示 默认为public目录下面的success页面
  212. * 提示页面为可配置 支持模板标签
  213. * @param string $message 提示信息
  214. * @param Boolean $status 状态
  215. * @param string $jumpUrl 页面跳转地址
  216. * @param Boolean $ajax 是否为Ajax方式
  217. * @access private
  218. * @return void
  219. */
  220. private function dispatchJump($message,$status=1,$jumpUrl='',$ajax=false) {
  221. // 判断是否为AJAX返回
  222. if($ajax || $this->isAjax()) $this->ajaxReturn($ajax,$message,$status);
  223. if(!empty($jumpUrl)) $this->assign('jumpUrl',$jumpUrl);
  224. // 提示标题
  225. $this->assign('msgTitle',$status? L('_OPERATION_SUCCESS_') : L('_OPERATION_FAIL_'));
  226. //如果设置了关闭窗口,则提示完毕后自动关闭窗口
  227. if($this->get('closeWin')) $this->assign('jumpUrl','javascript:window.close();');
  228. $this->assign('status',$status); // 状态
  229. //保证输出不受静态缓存影响
  230. C('HTML_CACHE_ON',false);
  231. if($status) { //发送成功信息
  232. $this->assign('message',$message);// 提示信息
  233. // 成功操作后默认停留1秒
  234. if(!$this->get('waitSecond')) $this->assign('waitSecond',"1");
  235. // 默认操作成功自动返回操作前页面
  236. if(!$this->get('jumpUrl')) $this->assign("jumpUrl",$_SERVER["HTTP_REFERER"]);
  237. $this->display(C('TMPL_ACTION_SUCCESS'));
  238. }else{
  239. $this->assign('error',$message);// 提示信息
  240. //发生错误时候默认停留3秒
  241. if(!$this->get('waitSecond')) $this->assign('waitSecond',"3");
  242. // 默认发生错误的话自动返回上页
  243. if(!$this->get('jumpUrl')) $this->assign('jumpUrl',"javascript:history.back(-1);");
  244. $this->display(C('TMPL_ACTION_ERROR'));
  245. // 中止执行 避免出错后继续执行
  246. exit ;
  247. }
  248. }
  249. /**
  250. * 加载模板和页面输出 可以返回输出内容
  251. * @access public
  252. * @param string $templateFile 模板文件名
  253. * @param string $charset 模板输出字符集
  254. * @param string $contentType 输出类型
  255. * @return mixed
  256. */
  257. public function display($templateFile='',$charset='',$contentType='') {
  258. G('viewStartTime');
  259. // 视图开始标签
  260. tag('view_begin',$templateFile);
  261. // 解析并获取模板内容
  262. $content = $this->fetch($templateFile);
  263. // 输出模板内容
  264. $this->show($content,$charset,$contentType);
  265. // 视图结束标签
  266. tag('view_end');
  267. }
  268. /**
  269. * 输出内容文本可以包括Html
  270. * @access public
  271. * @param string $content 输出内容
  272. * @param string $charset 模板输出字符集
  273. * @param string $contentType 输出类型
  274. * @return mixed
  275. */
  276. public function show($content,$charset='',$contentType=''){
  277. if(empty($charset)) $charset = C('DEFAULT_CHARSET');
  278. if(empty($contentType)) $contentType = C('TMPL_CONTENT_TYPE');
  279. // 网页字符编码
  280. header("Content-Type:".$contentType."; charset=".$charset);
  281. header("Cache-control: private"); //支持页面回跳
  282. header("X-Powered-By:TOPThink/".THINK_VERSION);
  283. // 输出模板文件
  284. echo $content;
  285. }
  286. /**
  287. * 解析和获取模板内容 用于输出
  288. * @access public
  289. * @param string $templateFile 模板文件名
  290. * @return string
  291. */
  292. public function fetch($templateFile='') {
  293. // 模板文件解析标签
  294. tag('view_template',$templateFile);
  295. // 模板文件不存在直接返回
  296. if(!is_file($templateFile)) return NULL;
  297. // 页面缓存
  298. ob_start();
  299. ob_implicit_flush(0);
  300. // 视图解析标签
  301. $params = array('var'=>$this->tVar,'file'=>$templateFile);
  302. $result = tag('view_parse',$params);
  303. if(false === $result) { // 未定义行为 则采用PHP原生模板
  304. // 模板阵列变量分解成为独立变量
  305. extract($this->tVar, EXTR_OVERWRITE);
  306. // 直接载入PHP模板
  307. include $templateFile;
  308. }
  309. // 获取并清空缓存
  310. $content = ob_get_clean();
  311. // 内容过滤标签
  312. tag('view_filter',$content);
  313. // 输出模板文件
  314. return $content;
  315. }
  316. /**
  317. * 析构方法
  318. * @access public
  319. */
  320. public function __destruct() {
  321. // 保存日志
  322. if(C('LOG_RECORD')) Log::save();
  323. // 执行后续操作
  324. tag('action_end');
  325. }
  326. }