PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/addons/model/AtmeModel.class.php

https://github.com/cxc222/weibo
PHP | 389 lines | 246 code | 24 blank | 119 comment | 40 complexity | d4c0cc58cc084ecc29fff64d2f0cc926 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * @Me模型 - 数据对象模型
  4. * @author jason <yangjs17@yeah.net>
  5. * @version TS3.0
  6. */
  7. class AtmeModel extends Model {
  8. protected $tableNmae = 'atme';
  9. protected $fields = array(0=>'atme_id',1=>'app',2=>'table',3=>'row_id',4=>'uid','_pk'=>'atme_id');
  10. private $_app = null; // 所属应用
  11. private $_app_table = null; // 所属资源表
  12. private $_app_pk_field = null; // 应用主键字段
  13. private $_at_regex = "/@(.+?)([\s|:]|$)/is";//"/@{uid=([^}]*)}/"; // @正则规则
  14. private $_at_field = 'uid'; // @的资源字段
  15. /**
  16. * 设置所属应用
  17. * @param string $app 应用名称
  18. * @return object @对象
  19. */
  20. public function setAppName($app) {
  21. $this->_app = $app;
  22. return $this;
  23. }
  24. /**
  25. * 设置相关内容所存储的资源表
  26. * @param string $app_table 数据表名
  27. * @return object @对象
  28. */
  29. public function setAppTable($app_table) {
  30. $this->_app_table = $app_table;
  31. return $this;
  32. }
  33. /**
  34. * 设置@的相关正则规则
  35. * @param string $regex 正则规则
  36. * @return object @对象
  37. */
  38. public function setAtRegex($regex) {
  39. $this->_at_regex = $regex;
  40. return $this;
  41. }
  42. /**
  43. * 设置@的资源字段
  44. * @param string $field @的资源字段
  45. * @return object @对象
  46. */
  47. public function setAtField($field) {
  48. $this->_at_field = $field;
  49. return $this;
  50. }
  51. /**
  52. * 获取@Me列表 - 分页型
  53. * @param array $map 查询条件
  54. * @param string $order 排序条件,默认为atme_id DESC
  55. * @param integer $limit 结果集显示个数,默认为20
  56. * @return array @Me列表信息
  57. */
  58. public function getAtmeList($map = null, $order = 'atme_id DESC', $limit = 20) {
  59. !$map['app'] && $this->_app && ($map['app'] = $this->_app);
  60. !$map['table'] && $this->_app_table && ($map['table'] = $this->_app_table);
  61. $data = $this->where($map)->order($order)->findPage($limit);
  62. // 格式化数据
  63. foreach($data['data'] as &$v) {
  64. $v = model('Source')->getSourceInfo($v['table'], $v['row_id'], false, $v['app']);
  65. }
  66. // 重置@Me的未读数
  67. $map['uid'] && model('UserCount')->resetUserCount($map['uid'], 'unread_atme', 0);
  68. return $data;
  69. }
  70. /**
  71. * 添加@Me数据
  72. * @param string $content @Me的相关内容
  73. * @param integer $row_id 资源ID
  74. * @param array $extra_uids 额外@用户ID
  75. * @param array $less_uids 去除@用户ID
  76. * @return integer 添加成功后的@ID
  77. */
  78. public function addAtme($content, $row_id, $extra_uids = null, $less_uids = null) {
  79. // 去除重复,空值与自己
  80. $extra_uids = array_diff($extra_uids, array($GLOBALS['ts']['mid']));
  81. $extra_uids = array_unique($extra_uids);
  82. $extra_uids = array_filter($extra_uids);
  83. $less_uids[] = $GLOBALS['ts']['mid'];
  84. $less_uids = array_unique($less_uids);
  85. $less_uids = array_filter($less_uids);
  86. // 获取@用户的UID数组
  87. $uids = $this->getUids($content, $extra_uids, $row_id, $less_uids);
  88. // 添加@信息
  89. $result = $this->_saveAtme($uids, $row_id);
  90. return $result;
  91. }
  92. /**
  93. * 更新最近@的人
  94. * @param string $content 原创微博内容
  95. */
  96. public function updateRecentAt( $content ){
  97. // 获取@用户的UID数组
  98. preg_match_all($this->_at_regex, $content, $matches);
  99. $unames = $matches[1];
  100. if ( $unames[0] ){
  101. $map = "uname in ('".implode("','",$unames)."') AND uid!=".$GLOBALS['ts']['mid'].' AND `is_audit`=1 AND `is_init`=1 AND `is_active`=1';
  102. $ulist = model('User')->where($map)->field('uid')->findall();
  103. $matchuids = getSubByKey($ulist,'uid');
  104. $userdata = model( 'UserData' );
  105. $value = $userdata->where('uid='.$GLOBALS['ts']['mid']." and `key`='user_recentat'")->field('value')->find();
  106. if ( $value ){
  107. $atdata = getSubByKey( unserialize( $value['value'] ) , 'uid');
  108. $atdata && $matchuids = array_merge( $matchuids , $atdata);
  109. $matchuids = array_unique( $matchuids );
  110. $matchuids = array_slice( $matchuids , 0 , 10 );
  111. $users = model( 'User' )->getUserInfoByUids( $matchuids );
  112. foreach ( $users as $v){
  113. if ( !$v['uid'] ){
  114. continue;
  115. }
  116. $udata[] = array('uid'=>$v['uid'],'uname'=>$v['uname'],'avatar_small'=>$v['avatar_small'],'search_key'=>$v['search_key']);
  117. }
  118. //更新userdata表里面的最近@的人的信息
  119. $userdata->setField('value' , serialize( $udata ) , "`key`='user_recentat' AND uid=".$GLOBALS['ts']['mid']);
  120. } else {
  121. $matchuids = array_slice( $matchuids , 0 , 10 );
  122. $users = model( 'User' )->getUserInfoByUids( $matchuids );
  123. foreach ( $users as $v){
  124. if ( !$v['uid'] ){
  125. continue;
  126. }
  127. $udata[] = array('uid'=>$v['uid'],'uname'=>$v['uname'],'avatar_small'=>$v['avatar_small'],'search_key'=>$v['search_key']);
  128. }
  129. $data['uid'] = $GLOBALS['ts']['mid'];
  130. $data['key'] = 'user_recentat';
  131. $data['value'] = serialize( $udata );
  132. $data['mtime'] = time();
  133. $userdata->add($data);
  134. }
  135. }
  136. }
  137. /**
  138. * 更新最近@的人
  139. * @param string $content 原创微博内容
  140. */
  141. public function updateRecentAtForApi( $content ,$row_id){
  142. // 获取@用户的UID数组
  143. preg_match_all($this->_at_regex, $content, $matches);
  144. $unames = $matches[1];
  145. if ( $unames[0] ){
  146. $map = "uname in ('".implode("','",$unames)."') AND uid!=".$GLOBALS['ts']['mid'].' AND `is_audit`=1 AND `is_init`=1 AND `is_active`=1';
  147. $ulist = model('User')->where($map)->field('uid')->findall();
  148. foreach ($ulist as $key => $value) {
  149. // dump($content);dump($row_id);
  150. // $this->addAtme($content,$row_id,$value['uid']);
  151. model('Atme')->setAppName('Public')->setAppTable('feed')->addAtme($content, $row_id, $value['uid']);
  152. }
  153. $matchuids = getSubByKey($ulist,'uid');
  154. $userdata = model( 'UserData' );
  155. $value = $userdata->where('uid='.$GLOBALS['ts']['mid']." and `key`='user_recentat'")->field('value')->find();
  156. if ( $value ){
  157. $atdata = getSubByKey( unserialize( $value['value'] ) , 'uid');
  158. $atdata && $matchuids = array_merge( $matchuids , $atdata);
  159. $matchuids = array_unique( $matchuids );
  160. $matchuids = array_slice( $matchuids , 0 , 10 );
  161. $users = model( 'User' )->getUserInfoByUids( $matchuids );
  162. foreach ( $users as $v){
  163. if ( !$v['uid'] ){
  164. continue;
  165. }
  166. $udata[] = array('uid'=>$v['uid'],'uname'=>$v['uname'],'avatar_small'=>$v['avatar_small'],'search_key'=>$v['search_key']);
  167. }
  168. //更新userdata表里面的最近@的人的信息
  169. $userdata->setField('value' , serialize( $udata ) , "`key`='user_recentat' AND uid=".$GLOBALS['ts']['mid']);
  170. } else {
  171. $matchuids = array_slice( $matchuids , 0 , 10 );
  172. $users = model( 'User' )->getUserInfoByUids( $matchuids );
  173. foreach ( $users as $v){
  174. if ( !$v['uid'] ){
  175. continue;
  176. }
  177. $udata[] = array('uid'=>$v['uid'],'uname'=>$v['uname'],'avatar_small'=>$v['avatar_small'],'search_key'=>$v['search_key']);
  178. }
  179. $data['uid'] = $GLOBALS['ts']['mid'];
  180. $data['key'] = 'user_recentat';
  181. $data['value'] = serialize( $udata );
  182. $data['mtime'] = time();
  183. $userdata->add($data);
  184. }
  185. }
  186. }
  187. /**
  188. * 获取@内容中的@用户
  189. * @param string $content @Me的相关内容
  190. * @param array $extra_uids 额外@用户UID
  191. * @param integer $row_id 资源ID
  192. * @param array $less_uids 去除@用户ID
  193. * @return array 用户UID数组
  194. */
  195. public function getUids($content, $extra_uids = null, $row_id, $less_uids = null) {
  196. // 正则匹配内容
  197. preg_match_all($this->_at_regex, $content, $matches);
  198. $unames = $matches[1];
  199. $map = "uname in ('".implode("','",$unames)."')";
  200. $ulist = model('User')->where($map)->field('uid')->findall();
  201. $matchuids = getSubByKey($ulist,'uid');
  202. // 如果内容匹配中没有用户
  203. if(empty($matchuids) && !empty($extra_uids)) {
  204. // 去除@用户ID
  205. if(!empty($less_uids)) {
  206. foreach($less_uids as $k => $v) {
  207. if(in_array($v, $extra_uids)) {
  208. unset($extra_uids[$k]);
  209. }
  210. }
  211. }
  212. return is_array($extra_uids) ? $extra_uids : array($extra_uids);
  213. }
  214. // 如果匹配内容中存在用户
  215. $suid = array();
  216. foreach($matchuids as $v) {
  217. !in_array($v, $suid) && $suid[] = (int)$v;
  218. }
  219. // 去除@用户ID
  220. if(!empty($less_uids)) {
  221. foreach($suid as $k => $v) {
  222. if(in_array($v, $less_uids)) {
  223. unset($suid[$k]);
  224. }
  225. }
  226. }
  227. // 发邮件流程
  228. $author = model('User')->getUserInfo($GLOBALS['ts']['mid']);
  229. $content = model('Source')->getSourceInfo($this->_app_table, $row_id, false, $this->_app);
  230. $config['content'] = parse_html($content['source_content']);
  231. $config['publish_time'] = date('Y-m-d H:i:s',$content['ctime']);
  232. $config['feed_url'] = $content['source_url'];
  233. $config['name'] = $author['uname'];
  234. $config['space_url'] = $author['space_url'];
  235. $config['face'] = $author['avatar_small'];
  236. foreach($suid as $u_v) {
  237. model('Notify')->sendNotify($u_v, 'atme', $config);
  238. }
  239. /* if(in_array('atme',MailModel::$allowed)){
  240. foreach($suid as $u_v){
  241. $v = array('table'=>$this->_app_table,'app'=>$this->_app,'row_id'=>$row_id,'uid'=>$u_v);
  242. $toUser = model('User')->getUserInfo($u_v);
  243. $map['key'] = 'email';
  244. $map['uid'] = $u_v;
  245. $isEmail = D('user_privacy')->where($map)->field('value')->find();
  246. if($isEmail['value'] == 0){
  247. $content = model('Source')->getSourceInfo($v['table'],$v['row_id'],false,$v['app']);
  248. //model('Mail')->send_email($toUser['email'],'atme','',array('content'=>parse_html($content['source_content'])));
  249. model('Mail')->send_email($toUser['email'],$author['uname'].'在微博中@提到了您',parse_html($content['source_content']));
  250. }
  251. unset($map);
  252. unset($isEmail);
  253. }
  254. }*/
  255. return array_unique(array_filter(array_merge($suid, (array)$extra_uids)));
  256. }
  257. /**
  258. * 删除@Me数据
  259. * @param string $content @Me的相关内容
  260. * @param integer $row_id 资源ID
  261. * @param array $extra_uids 额外@用户UID
  262. * @return boolean 是否删除成功
  263. */
  264. public function deleteAtme($content, $row_id, $extra_uids = null) {
  265. $uids = $this->getUids($content, $extra_uids);
  266. $result = $this->_deleteAtme($uids, $row_id);
  267. return $result;
  268. }
  269. /**
  270. * 添加@Me信息操作
  271. * @param array $uids 用户UID数组
  272. * @param integer $row_id 资源ID
  273. * @return integer 添加成功后的@ID
  274. */
  275. private function _saveAtme($uids, $row_id) {
  276. foreach ($uids as $u_v) {
  277. // 去除自己@自己的数据
  278. if($u_v == $GLOBALS['ts']['mid']) {
  279. continue;
  280. }
  281. $data[] = "('{$this->_app}', '{$this->_app_table}', {$row_id}, {$u_v})";
  282. // 更新@Me的未读数目
  283. model('UserCount')->updateUserCount($u_v, 'unread_atme', 1);
  284. }
  285. !empty($data) && $res = $this->query('INSERT INTO '.$this->tablePrefix.'atme (`app`, `table`, `row_id`, `uid`) VALUES '.implode(',', $data));
  286. return $res;
  287. }
  288. /**
  289. * 删除@Me信息操作
  290. * @param array $uids 用户UID数组
  291. * @param integer $row_id 资源ID
  292. * @return boolean 是否删除成功
  293. */
  294. private function _deleteAtme($uids, $row_id) {
  295. $result = false;
  296. if(!empty($uids)) {
  297. $map['table'] = $this->_app_table;
  298. $map['row_id'] = $row_id;
  299. $map['uid'] = array('IN', $uids);
  300. $res = $this->where($map)->delete();
  301. $res !== false && $result = true;
  302. } else {
  303. $map['table'] = $this->_app_table;
  304. $map['row_id'] = $row_id;
  305. $res = $this->where($map)->delete();
  306. $res !== false && $result = true;
  307. }
  308. return $result;
  309. }
  310. /*** API使用方法 ***/
  311. // 所有的@信息
  312. public function mentions($mid , $since_id = 0 , $max_id = 0 , $limit = 20 , $page = 1, $table=null) {
  313. $since_id = intval($since_id);
  314. $max_id = intval($max_id);
  315. $limit = intval($limit);
  316. $page = intval($page);
  317. $where = "uid = '{$mid}'";
  318. if($table){
  319. $where .= " AND `table`='{$table}' ";
  320. }
  321. if(!empty($since_id) || !empty($max_id)) {
  322. !empty($since_id) && $where .= " AND atme_id > {$since_id}";
  323. !empty($max_id) && $where .= " AND atme_id < {$max_id}";
  324. }
  325. $start = ($page - 1) * $limit;
  326. $end = $limit;
  327. $list = $this->where($where)->limit("$start, $end")->order('atme_id DESC')->findAll();
  328. foreach($list as $k => $v) {
  329. $list[$k] = model('Source')->getSourceInfo($v['table'], $v['row_id'], true, $v['app']);
  330. $list[$k]['atme_id'] = $v['atme_id'];
  331. //评论的内容
  332. $list[$k]['content'] = $list[$k]['source_content'];
  333. unset($list[$k]['source_content']);
  334. }
  335. return $list;
  336. }
  337. // 动态的@信息
  338. public function mentions_feed($mid , $since_id = 0 , $max_id = 0 , $limit = 20 , $page = 1) {
  339. $since_id = intval($since_id);
  340. $max_id = intval($max_id);
  341. $limit = intval($limit);
  342. $page = intval($page);
  343. $where = "uid = '{$mid}' AND `table`='feed' ";
  344. if(!empty($since_id) ) {
  345. !empty($since_id) && $where .= " AND row_id > {$since_id}";
  346. }
  347. if(!empty($max_id)){
  348. !empty($max_id) && $where .= " AND row_id < {$max_id}";
  349. }
  350. $start = ($page - 1) * $limit;
  351. $end = $limit;
  352. $feed_ids = $this->where($where)->limit("$start, $end")->order('atme_id DESC')->field('row_id')->getAsFieldArray('row_id');
  353. $data = model('Feed')->formatFeed($feed_ids,true);
  354. return $data;
  355. }
  356. /**
  357. * 获取动态的种类,用于动态的Tab
  358. * @param array $map 查询条件
  359. * @return array 评论种类与其资源数目
  360. */
  361. public function getTab($map) {
  362. $list = $this->field('COUNT(1) AS `nums`, `table`')->where($map)->group('`table`')->getHashList('table', 'nums');
  363. return $list;
  364. }
  365. }