/ThinkPHP/Lib/Think/Core/Model/ViewModel.class.php

https://github.com/dzx0315/509 · PHP · 285 lines · 152 code · 10 blank · 123 comment · 28 complexity · c0677fdb4f811d5133ea276d19c1c0d3 MD5 · raw file

  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2010 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 视图模型类
  15. +------------------------------------------------------------------------------
  16. * @category Think
  17. * @package Think
  18. * @subpackage Core
  19. * @author liu21st <liu21st@gmail.com>
  20. * @version $Id$
  21. +------------------------------------------------------------------------------
  22. */
  23. class ViewModel extends Model {
  24. protected $viewFields = array();
  25. /**
  26. +----------------------------------------------------------
  27. * 自动检测数据表信息
  28. +----------------------------------------------------------
  29. * @access protected
  30. +----------------------------------------------------------
  31. * @return void
  32. +----------------------------------------------------------
  33. */
  34. protected function _checkTableInfo() {}
  35. /**
  36. +----------------------------------------------------------
  37. * 得到完整的数据表名
  38. +----------------------------------------------------------
  39. * @access public
  40. +----------------------------------------------------------
  41. * @return string
  42. +----------------------------------------------------------
  43. */
  44. public function getTableName()
  45. {
  46. if(empty($this->trueTableName)) {
  47. $tableName = '';
  48. foreach ($this->viewFields as $key=>$view){
  49. // 获取数据表名称
  50. $class = $key.'Model';
  51. $Model = class_exists($class)?new $class():M($key);
  52. $tableName .= $Model->getTableName();
  53. // 表别名定义
  54. $tableName .= !empty($view['_as'])?' '.$view['_as']:' '.$key;
  55. // 支持ON 条件定义
  56. $tableName .= !empty($view['_on'])?' ON '.$view['_on']:'';
  57. // 指定JOIN类型 例如 RIGHT INNER LEFT 下一个表有效
  58. $type = !empty($view['_type'])?$view['_type']:'';
  59. $tableName .= ' '.strtoupper($type).' JOIN ';
  60. $len = strlen($type.'_JOIN ');
  61. }
  62. $tableName = substr($tableName,0,-$len);
  63. $this->trueTableName = $tableName;
  64. }
  65. return $this->trueTableName;
  66. }
  67. /**
  68. +----------------------------------------------------------
  69. * 表达式过滤方法
  70. +----------------------------------------------------------
  71. * @access protected
  72. +----------------------------------------------------------
  73. * @param string $options 表达式
  74. +----------------------------------------------------------
  75. * @return void
  76. +----------------------------------------------------------
  77. */
  78. protected function _options_filter(&$options) {
  79. if(isset($options['field']))
  80. $options['field'] = $this->checkFields($options['field']);
  81. else
  82. $options['field'] = $this->checkFields();
  83. if(isset($options['group']))
  84. $options['group'] = $this->checkGroup($options['group']);
  85. if(isset($options['where']))
  86. $options['where'] = $this->checkCondition($options['where']);
  87. if(isset($options['order']))
  88. $options['order'] = $this->checkOrder($options['order']);
  89. }
  90. /**
  91. +----------------------------------------------------------
  92. * 检查是否定义了所有字段
  93. +----------------------------------------------------------
  94. * @access protected
  95. +----------------------------------------------------------
  96. * @param string $name 模型名称
  97. * @param array $fields 字段数组
  98. +----------------------------------------------------------
  99. * @return array
  100. +----------------------------------------------------------
  101. */
  102. private function _checkFields($name,$fields) {
  103. if(false !== $pos = array_search('*',$fields)) {// 定义所有字段
  104. $fields = array_merge($fields,M($name)->getDbFields());
  105. unset($fields[$pos]);
  106. }
  107. return $fields;
  108. }
  109. /**
  110. +----------------------------------------------------------
  111. * 检查条件中的视图字段
  112. +----------------------------------------------------------
  113. * @access protected
  114. +----------------------------------------------------------
  115. * @param mixed $data 条件表达式
  116. +----------------------------------------------------------
  117. * @return array
  118. +----------------------------------------------------------
  119. */
  120. protected function checkCondition($where) {
  121. if(is_array($where)) {
  122. $view = array();
  123. // 检查视图字段
  124. foreach ($this->viewFields as $key=>$val){
  125. $k = isset($val['_as'])?$val['_as']:$key;
  126. $val = $this->_checkFields($key,$val);
  127. foreach ($where as $name=>$value){
  128. if(false !== $field = array_search($name,$val,true)) {
  129. // 存在视图字段
  130. $_key = is_numeric($field)? $k.'.'.$name : $k.'.'.$field;
  131. $view[$_key] = $value;
  132. unset($where[$name]);
  133. }
  134. }
  135. }
  136. $where = array_merge($where,$view);
  137. }
  138. return $where;
  139. }
  140. /**
  141. +----------------------------------------------------------
  142. * 检查Order表达式中的视图字段
  143. +----------------------------------------------------------
  144. * @access protected
  145. +----------------------------------------------------------
  146. * @param string $order 字段
  147. +----------------------------------------------------------
  148. * @return string
  149. +----------------------------------------------------------
  150. */
  151. protected function checkOrder($order='') {
  152. if(!empty($order)) {
  153. $orders = explode(',',$order);
  154. $_order = array();
  155. foreach ($orders as $order){
  156. $array = explode(' ',$order);
  157. $field = $array[0];
  158. $sort = isset($array[1])?$array[1]:'ASC';
  159. // 解析成视图字段
  160. foreach ($this->viewFields as $name=>$val){
  161. $k = isset($val['_as'])?$val['_as']:$name;
  162. $val = $this->_checkFields($name,$val);
  163. if(false !== $_field = array_search($field,$val,true)) {
  164. // 存在视图字段
  165. $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field;
  166. break;
  167. }
  168. }
  169. $_order[] = $field.' '.$sort;
  170. }
  171. $order = implode(',',$_order);
  172. }
  173. return $order;
  174. }
  175. /**
  176. +----------------------------------------------------------
  177. * 检查Group表达式中的视图字段
  178. +----------------------------------------------------------
  179. * @access protected
  180. +----------------------------------------------------------
  181. * @param string $group 字段
  182. +----------------------------------------------------------
  183. * @return string
  184. +----------------------------------------------------------
  185. */
  186. protected function checkGroup($group='') {
  187. if(!empty($group)) {
  188. $groups = explode(',',$group);
  189. $_group = array();
  190. foreach ($groups as $field){
  191. // 解析成视图字段
  192. foreach ($this->viewFields as $name=>$val){
  193. $k = isset($val['_as'])?$val['_as']:$name;
  194. $val = $this->_checkFields($name,$val);
  195. if(false !== $_field = array_search($field,$val,true)) {
  196. // 存在视图字段
  197. $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field;
  198. break;
  199. }
  200. }
  201. $_group[] = $field;
  202. }
  203. $group = implode(',',$_group);
  204. }
  205. return $group;
  206. }
  207. /**
  208. +----------------------------------------------------------
  209. * 检查fields表达式中的视图字段
  210. +----------------------------------------------------------
  211. * @access protected
  212. +----------------------------------------------------------
  213. * @param string $fields 字段
  214. +----------------------------------------------------------
  215. * @return string
  216. +----------------------------------------------------------
  217. */
  218. protected function checkFields($fields='') {
  219. if(empty($fields) || '*'==$fields ) {
  220. // 获取全部视图字段
  221. $fields = array();
  222. foreach ($this->viewFields as $name=>$val){
  223. $k = isset($val['_as'])?$val['_as']:$name;
  224. $val = $this->_checkFields($name,$val);
  225. foreach ($val as $key=>$field){
  226. if(is_numeric($key)) {
  227. $fields[] = $k.'.'.$field.' AS '.$field;
  228. }elseif('_' != substr($key,0,1)) {
  229. // 以_开头的为特殊定义
  230. if( false !== strpos($key,'*') || false !== strpos($key,'(') || false !== strpos($key,'.')) {
  231. //如果包含* 或者 使用了sql方法 则不再添加前面的表名
  232. $fields[] = $key.' AS '.$field;
  233. }else{
  234. $fields[] = $k.'.'.$key.' AS '.$field;
  235. }
  236. }
  237. }
  238. }
  239. $fields = implode(',',$fields);
  240. }else{
  241. if(!is_array($fields))
  242. $fields = explode(',',$fields);
  243. // 解析成视图字段
  244. $array = array();
  245. foreach ($fields as $key=>$field){
  246. if(strpos($field,'(') || strpos(strtolower($field),' as ')){
  247. // 使用了函数或者别名
  248. $array[] = $field;
  249. unset($fields[$key]);
  250. }
  251. }
  252. foreach ($this->viewFields as $name=>$val){
  253. $k = isset($val['_as'])?$val['_as']:$name;
  254. $val = $this->_checkFields($name,$val);
  255. foreach ($fields as $key=>$field){
  256. if(false !== $_field = array_search($field,$val,true)) {
  257. // 存在视图字段
  258. if(is_numeric($_field)) {
  259. $array[] = $k.'.'.$field.' AS '.$field;
  260. }elseif('_' != substr($_field,0,1)){
  261. if( false !== strpos($_field,'*') || false !== strpos($_field,'(') || false !== strpos($_field,'.'))
  262. //如果包含* 或者 使用了sql方法 则不再添加前面的表名
  263. $array[] = $_field.' AS '.$field;
  264. else
  265. $array[] = $k.'.'.$_field.' AS '.$field;
  266. }
  267. }
  268. }
  269. }
  270. $fields = implode(',',$array);
  271. }
  272. return $fields;
  273. }
  274. }
  275. ?>