ViewModel.class.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. /**
  3. * 洛阳赤炎鹰网络科技有限公司
  4. * https://www.cyyvip.com
  5. * Copyright (c) 2022 赤店商城 All rights reserved.
  6. */
  7. // +----------------------------------------------------------------------
  8. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  9. // +----------------------------------------------------------------------
  10. // | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
  11. // +----------------------------------------------------------------------
  12. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  13. // +----------------------------------------------------------------------
  14. // | Author: liu21st <liu21st@gmail.com>
  15. // +----------------------------------------------------------------------
  16. namespace Think\Model;
  17. use Think\Model;
  18. /**
  19. * ThinkPHP视图模型扩展
  20. */
  21. class ViewModel extends Model {
  22. protected $viewFields = array();
  23. /**
  24. * 自动检测数据表信息
  25. * @access protected
  26. * @return void
  27. */
  28. protected function _checkTableInfo() {}
  29. /**
  30. * 得到完整的数据表名
  31. * @access public
  32. * @return string
  33. */
  34. public function getTableName() {
  35. if(empty($this->trueTableName)) {
  36. $tableName = '';
  37. foreach ($this->viewFields as $key=>$view){
  38. // 获取数据表名称
  39. if(isset($view['_table'])) { // 2011/10/17 添加实际表名定义支持 可以实现同一个表的视图
  40. $tableName .= $view['_table'];
  41. $prefix = $this->tablePrefix;
  42. $tableName = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $tableName);
  43. }else{
  44. $class = $key.'Model';
  45. $Model = class_exists($class)?new $class():M($key);
  46. $tableName .= $Model->getTableName();
  47. }
  48. // 表别名定义
  49. $tableName .= !empty($view['_as'])?' '.$view['_as']:' '.$key;
  50. // 支持ON 条件定义
  51. $tableName .= !empty($view['_on'])?' ON '.$view['_on']:'';
  52. // 指定JOIN类型 例如 RIGHT INNER LEFT 下一个表有效
  53. $type = !empty($view['_type'])?$view['_type']:'';
  54. $tableName .= ' '.strtoupper($type).' JOIN ';
  55. $len = strlen($type.'_JOIN ');
  56. }
  57. $tableName = substr($tableName,0,-$len);
  58. $this->trueTableName = $tableName;
  59. }
  60. return $this->trueTableName;
  61. }
  62. /**
  63. * 表达式过滤方法
  64. * @access protected
  65. * @param string $options 表达式
  66. * @return void
  67. */
  68. protected function _options_filter(&$options) {
  69. if(isset($options['field']))
  70. $options['field'] = $this->checkFields($options['field']);
  71. else
  72. $options['field'] = $this->checkFields();
  73. if(isset($options['group']))
  74. $options['group'] = $this->checkGroup($options['group']);
  75. if(isset($options['where']))
  76. $options['where'] = $this->checkCondition($options['where']);
  77. if(isset($options['order']))
  78. $options['order'] = $this->checkOrder($options['order']);
  79. }
  80. /**
  81. * 检查是否定义了所有字段
  82. * @access protected
  83. * @param string $name 模型名称
  84. * @param array $fields 字段数组
  85. * @return array
  86. */
  87. private function _checkFields($name,$fields) {
  88. if(false !== $pos = array_search('*',$fields)) {// 定义所有字段
  89. $fields = array_merge($fields,M($name)->getDbFields());
  90. unset($fields[$pos]);
  91. }
  92. return $fields;
  93. }
  94. /**
  95. * 检查条件中的视图字段
  96. * @access protected
  97. * @param mixed $data 条件表达式
  98. * @return array
  99. */
  100. protected function checkCondition($where) {
  101. if(is_array($where)) {
  102. $view = array();
  103. // 检查视图字段
  104. foreach ($this->viewFields as $key=>$val){
  105. $k = isset($val['_as'])?$val['_as']:$key;
  106. $val = $this->_checkFields($key,$val);
  107. foreach ($where as $name=>$value){
  108. if(false !== $field = array_search($name,$val,true)) {
  109. // 存在视图字段
  110. $_key = is_numeric($field)? $k.'.'.$name : $k.'.'.$field;
  111. $view[$_key] = $value;
  112. unset($where[$name]);
  113. }
  114. }
  115. }
  116. $where = array_merge($where,$view);
  117. }
  118. return $where;
  119. }
  120. /**
  121. * 检查Order表达式中的视图字段
  122. * @access protected
  123. * @param string $order 字段
  124. * @return string
  125. */
  126. protected function checkOrder($order='') {
  127. if(is_string($order) && !empty($order)) {
  128. $orders = explode(',',$order);
  129. $_order = array();
  130. foreach ($orders as $order){
  131. $array = explode(' ',trim($order));
  132. $field = $array[0];
  133. $sort = isset($array[1])?$array[1]:'ASC';
  134. // 解析成视图字段
  135. foreach ($this->viewFields as $name=>$val){
  136. $k = isset($val['_as'])?$val['_as']:$name;
  137. $val = $this->_checkFields($name,$val);
  138. if(false !== $_field = array_search($field,$val,true)) {
  139. // 存在视图字段
  140. $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field;
  141. break;
  142. }
  143. }
  144. $_order[] = $field.' '.$sort;
  145. }
  146. $order = implode(',',$_order);
  147. }
  148. return $order;
  149. }
  150. /**
  151. * 检查Group表达式中的视图字段
  152. * @access protected
  153. * @param string $group 字段
  154. * @return string
  155. */
  156. protected function checkGroup($group='') {
  157. if(!empty($group)) {
  158. $groups = explode(',',$group);
  159. $_group = array();
  160. foreach ($groups as $field){
  161. // 解析成视图字段
  162. foreach ($this->viewFields as $name=>$val){
  163. $k = isset($val['_as'])?$val['_as']:$name;
  164. $val = $this->_checkFields($name,$val);
  165. if(false !== $_field = array_search($field,$val,true)) {
  166. // 存在视图字段
  167. $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field;
  168. break;
  169. }
  170. }
  171. $_group[] = $field;
  172. }
  173. $group = implode(',',$_group);
  174. }
  175. return $group;
  176. }
  177. /**
  178. * 检查fields表达式中的视图字段
  179. * @access protected
  180. * @param string $fields 字段
  181. * @return string
  182. */
  183. protected function checkFields($fields='') {
  184. if(empty($fields) || '*'==$fields ) {
  185. // 获取全部视图字段
  186. $fields = array();
  187. foreach ($this->viewFields as $name=>$val){
  188. $k = isset($val['_as'])?$val['_as']:$name;
  189. $val = $this->_checkFields($name,$val);
  190. foreach ($val as $key=>$field){
  191. if(is_numeric($key)) {
  192. $fields[] = $k.'.'.$field.' AS '.$field;
  193. }elseif('_' != substr($key,0,1)) {
  194. // 以_开头的为特殊定义
  195. if( false !== strpos($key,'*') || false !== strpos($key,'(') || false !== strpos($key,'.')) {
  196. //如果包含* 或者 使用了sql方法 则不再添加前面的表名
  197. $fields[] = $key.' AS '.$field;
  198. }else{
  199. $fields[] = $k.'.'.$key.' AS '.$field;
  200. }
  201. }
  202. }
  203. }
  204. $fields = implode(',',$fields);
  205. }else{
  206. if(!is_array($fields))
  207. $fields = explode(',',$fields);
  208. // 解析成视图字段
  209. $array = array();
  210. foreach ($fields as $key=>$field){
  211. if(strpos($field,'(') || strpos(strtolower($field),' as ')){
  212. // 使用了函数或者别名
  213. $array[] = $field;
  214. unset($fields[$key]);
  215. }
  216. }
  217. foreach ($this->viewFields as $name=>$val){
  218. $k = isset($val['_as'])?$val['_as']:$name;
  219. $val = $this->_checkFields($name,$val);
  220. foreach ($fields as $key=>$field){
  221. if(false !== $_field = array_search($field,$val,true)) {
  222. // 存在视图字段
  223. if(is_numeric($_field)) {
  224. $array[] = $k.'.'.$field.' AS '.$field;
  225. }elseif('_' != substr($_field,0,1)){
  226. if( false !== strpos($_field,'*') || false !== strpos($_field,'(') || false !== strpos($_field,'.'))
  227. //如果包含* 或者 使用了sql方法 则不再添加前面的表名
  228. $array[] = $_field.' AS '.$field;
  229. else
  230. $array[] = $k.'.'.$_field.' AS '.$field;
  231. }
  232. }
  233. }
  234. }
  235. $fields = implode(',',$array);
  236. }
  237. return $fields;
  238. }
  239. }