ViewModel.class.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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 视图模型类
  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['order']))
  86. $options['order'] = $this->checkOrder($options['order']);
  87. }
  88. /**
  89. +----------------------------------------------------------
  90. * 检查是否定义了所有字段
  91. +----------------------------------------------------------
  92. * @access protected
  93. +----------------------------------------------------------
  94. * @param string $name 模型名称
  95. * @param array $fields 字段数组
  96. +----------------------------------------------------------
  97. * @return array
  98. +----------------------------------------------------------
  99. */
  100. private function _checkFields($name,$fields) {
  101. if(false !== $pos = array_search('*',$fields)) {// 定义所有字段
  102. $fields = array_merge($fields,M($name)->getDbFields());
  103. unset($fields[$pos]);
  104. }
  105. return $fields;
  106. }
  107. /**
  108. +----------------------------------------------------------
  109. * 检查条件中的视图字段
  110. +----------------------------------------------------------
  111. * @access protected
  112. +----------------------------------------------------------
  113. * @param mixed $data 条件表达式
  114. +----------------------------------------------------------
  115. * @return array
  116. +----------------------------------------------------------
  117. */
  118. protected function checkCondition($where) {
  119. if(is_array($where)) {
  120. $view = array();
  121. // 检查视图字段
  122. foreach ($this->viewFields as $key=>$val){
  123. $k = isset($val['_as'])?$val['_as']:$key;
  124. $val = $this->_checkFields($key,$val);
  125. foreach ($where as $name=>$value){
  126. if(false !== $field = array_search($name,$val)) {
  127. // 存在视图字段
  128. $_key = is_numeric($field)? $k.'.'.$name : $k.'.'.$field;
  129. $view[$_key] = $value;
  130. unset($where[$name]);
  131. }
  132. }
  133. }
  134. $where = array_merge($where,$view);
  135. }
  136. return $where;
  137. }
  138. /**
  139. +----------------------------------------------------------
  140. * 检查Order表达式中的视图字段
  141. +----------------------------------------------------------
  142. * @access protected
  143. +----------------------------------------------------------
  144. * @param string $order 字段
  145. +----------------------------------------------------------
  146. * @return string
  147. +----------------------------------------------------------
  148. */
  149. protected function checkOrder($order='') {
  150. if(!empty($order)) {
  151. $orders = explode(',',$order);
  152. $_order = array();
  153. foreach ($orders as $order){
  154. $array = explode(' ',$order);
  155. $field = $array[0];
  156. $sort = isset($array[1])?$array[1]:'ASC';
  157. // 解析成视图字段
  158. foreach ($this->viewFields as $name=>$val){
  159. $k = isset($val['_as'])?$val['_as']:$name;
  160. $val = $this->_checkFields($name,$val);
  161. if(false !== $_field = array_search($field,$val)) {
  162. // 存在视图字段
  163. $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field;
  164. break;
  165. }
  166. }
  167. $_order[] = $field.' '.$sort;
  168. }
  169. $order = implode(',',$_order);
  170. }
  171. return $order;
  172. }
  173. /**
  174. +----------------------------------------------------------
  175. * 检查Group表达式中的视图字段
  176. +----------------------------------------------------------
  177. * @access protected
  178. +----------------------------------------------------------
  179. * @param string $group 字段
  180. +----------------------------------------------------------
  181. * @return string
  182. +----------------------------------------------------------
  183. */
  184. protected function checkGroup($group='') {
  185. if(!empty($group)) {
  186. $groups = explode(',',$group);
  187. $_group = array();
  188. foreach ($groups as $field){
  189. // 解析成视图字段
  190. foreach ($this->viewFields as $name=>$val){
  191. $k = isset($val['_as'])?$val['_as']:$name;
  192. $val = $this->_checkFields($name,$val);
  193. if(false !== $_field = array_search($field,$val)) {
  194. // 存在视图字段
  195. $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field;
  196. break;
  197. }
  198. }
  199. $_group[] = $field;
  200. }
  201. $group = implode(',',$_group);
  202. }
  203. return $group;
  204. }
  205. /**
  206. +----------------------------------------------------------
  207. * 检查fields表达式中的视图字段
  208. +----------------------------------------------------------
  209. * @access protected
  210. +----------------------------------------------------------
  211. * @param string $fields 字段
  212. +----------------------------------------------------------
  213. * @return string
  214. +----------------------------------------------------------
  215. */
  216. protected function checkFields($fields='') {
  217. if(empty($fields) || '*'==$fields ) {
  218. // 获取全部视图字段
  219. $fields = array();
  220. foreach ($this->viewFields as $name=>$val){
  221. $k = isset($val['_as'])?$val['_as']:$name;
  222. $val = $this->_checkFields($name,$val);
  223. foreach ($val as $key=>$field){
  224. if(is_numeric($key)) {
  225. $fields[] = $k.'.'.$field.' AS '.$field;
  226. }elseif('_' != substr($key,0,1)) {
  227. // 以_开头的为特殊定义
  228. if( false !== strpos($key,'*') || false !== strpos($key,'(') || false !== strpos($key,'.')) {
  229. //如果包含* 或者 使用了sql方法 则不再添加前面的表名
  230. $fields[] = $key.' AS '.$field;
  231. }else{
  232. $fields[] = $k.'.'.$key.' AS '.$field;
  233. }
  234. }
  235. }
  236. }
  237. $fields = implode(',',$fields);
  238. }else{
  239. if(!is_array($fields))
  240. $fields = explode(',',$fields);
  241. // 解析成视图字段
  242. $array = array();
  243. foreach ($fields as $key=>$field){
  244. if(strpos($field,'(') || strpos(strtolower($field),' as ')){
  245. // 使用了函数或者别名
  246. $array[] = $field;
  247. unset($fields[$key]);
  248. }
  249. }
  250. foreach ($this->viewFields as $name=>$val){
  251. $k = isset($val['_as'])?$val['_as']:$name;
  252. $val = $this->_checkFields($name,$val);
  253. foreach ($fields as $key=>$field){
  254. if(false !== $_field = array_search($field,$val)) {
  255. // 存在视图字段
  256. if(is_numeric($_field)) {
  257. $array[] = $k.'.'.$field.' AS '.$field;
  258. }elseif('_' != substr($_field,0,1)){
  259. if( false !== strpos($_field,'*') || false !== strpos($_field,'(') || false !== strpos($_field,'.'))
  260. //如果包含* 或者 使用了sql方法 则不再添加前面的表名
  261. $array[] = $_field.' AS '.$field;
  262. else
  263. $array[] = $k.'.'.$_field.' AS '.$field;
  264. }
  265. }
  266. }
  267. }
  268. $fields = implode(',',$array);
  269. }
  270. return $fields;
  271. }
  272. }
  273. ?>