PageRenderTime 89ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/upload/src/service/tag/srv/PwTagService.php

https://gitlab.com/wuhang2003/phpwind
PHP | 482 lines | 277 code | 31 blank | 174 comment | 38 complexity | beda0f38c7e645b2786f889e255c662d MD5 | raw file
  1. <?php
  2. Wind::import('SRV:tag.dm.PwTagDm');
  3. /**
  4. * 话题业务
  5. *
  6. * @author peihong <peihong.zhangph@aliyun-inc.com>
  7. * @copyright ©2003-2103 phpwind.com
  8. * @license http://www.phpwind.com
  9. * @version $Id: PwTagService.php 3833 2012-02-16 03:32:27Z peihong.zhangph $
  10. * @package src.service.tag.srv
  11. */
  12. class PwTagService {
  13. private $expireDay = 7;
  14. /**
  15. * 批量添加话题
  16. *
  17. * @param array $dmArray
  18. */
  19. public function addTags($dmArray) {
  20. if(!is_array($dmArray) || !$dmArray) return false;
  21. $_tagsInfo = $this->_getTagDs()->getTagsByNames(array_keys($dmArray));
  22. $tagsKeys = $tagsInfo = array();
  23. foreach ($_tagsInfo as $k => $tag){
  24. $tagsKeys[] = strtolower($k);
  25. $k = strtolower($k);
  26. $tagsInfo[$k] = $tag;
  27. }
  28. $dmArrays = array();
  29. foreach ($dmArray as $k => $dm){
  30. $k = strtolower($k);
  31. $dmArrays[$k] = $dm;
  32. }
  33. $tagRecords = $updateTagDms = $relationDms = $attentionTags = array();
  34. foreach ($dmArrays as $k => $dm) {
  35. $k = strtolower(trim($k));
  36. if (!$k || !$dm instanceof PwTagDm) continue;
  37. $time = Pw::getTime();
  38. $dm->setCreatedTime($time);
  39. $dm->setName($k);
  40. if (in_array($k, $tagsKeys)) {
  41. $dm->tag_id = $tagsInfo[$k]['parent_tag_id'] ? $tagsInfo[$k]['parent_tag_id'] : $tagsInfo[$k]['tag_id'];
  42. $dm->setContentTagId($tagsInfo[$k]['tag_id']);
  43. $dm->setIfhot($tagsInfo[$k]['ifhot']);
  44. $updateTagDm = new PwTagDm($dm->tag_id);
  45. $updateTagDm->addContentCount(1);
  46. $updateTagDms[] = $updateTagDm;
  47. } else {
  48. $dm->setContentCount(1);
  49. $result = $this->_getTagDs()->addTag($dm);
  50. if ($result instanceof PwError) {
  51. return $result;
  52. }
  53. $dm->tag_id = $result;
  54. $dm->setContentTagId($dm->tag_id);
  55. }
  56. if ($dm->getIfhot()) {
  57. $tagRecords[] = array('tag_id' => $dm->tag_id, 'update_time' => $time);
  58. }
  59. $relationDms[] = $dm;
  60. // $this->addAttention($dm->getCreateUid(),$dm->tag_id);
  61. }
  62. $this->_getTagDs()->batchAddRelation($relationDms);
  63. $this->_getTagDs()->batchAddTagRecord($tagRecords);
  64. $updateTagDms && $this->_getTagDs()->batchUpdate($updateTagDms);
  65. return $dm->tag_id;
  66. }
  67. /**
  68. * 批量更新帖子话题
  69. *
  70. * @param int $typeId
  71. * @param int $paramId
  72. * @param array $dmArray
  73. */
  74. public function updateTags($typeId,$paramId,$dmArray) {
  75. if (!$typeId || !$paramId) {
  76. return new PwError('data.error');
  77. }
  78. $tagsInfo = $this->_getTagDs()->getTagRelationByType($typeId,$paramId);
  79. $this->_getTagDs()->batchDeleteRelationsByType($typeId,$paramId,array_keys($tagsInfo));
  80. $dmArray && $this->addTags($dmArray);
  81. $types = $this->_getTypeMap();
  82. $tags = $this->getTagByType($types[$typeId],$paramId);
  83. Wind::import('SRV:forum.dm.PwTopicDm');
  84. $dm = new PwTopicDm($paramId);
  85. $dm->setTags($this->_formatTags($tags));
  86. Wekit::load('forum.PwThread')->updateThread($dm,PwThread::FETCH_CONTENT);
  87. return true;
  88. }
  89. /**
  90. * 批量将话题parent_id置0
  91. *
  92. * @param array $tagIds
  93. * @return bool
  94. */
  95. public function clearTagsByParentIds($tagIds){
  96. if (!is_array($tagIds) || !count($tagIds)) return false;
  97. Wind::import('SRV:tag.dm.PwTagDm');
  98. $dm = new PwTagDm();
  99. $dm->setParent(0);
  100. return $this->_getTagDs()->updateTags($tagIds,$dm);
  101. }
  102. /**
  103. *
  104. * 根据类型名获取最新
  105. * @param int $tagId
  106. * @param string $typeName
  107. * @param int $num
  108. */
  109. public function getContentsByTypeName($tagId,$typeName,$ifcheck,$offset=0,$num = 4){
  110. $tagId = intval($tagId);
  111. $num = intval($num);
  112. $typeId = $this->getTypeIdByTypeName($typeName);
  113. $relations = $this->_getTagDs()->getTagRelation($tagId,$typeId,$ifcheck,$offset,$num);
  114. $ids = $array = $return = array();
  115. foreach ($relations as $v) {
  116. $array[$v['param_id']] = $v;
  117. $ids[] = $v['param_id'];
  118. }
  119. if (!$ids) return array();
  120. $action = $this->_getTagAction($typeName);
  121. if (!$action) return new PwError('undefined content type');
  122. $result = $action->getContents($ids);
  123. foreach ($ids as $id) {
  124. $result[$id] && $result[$id]['tagifcheck'] = $array[$id]['ifcheck'];
  125. $return[$id] = $result[$id];
  126. }
  127. usort($return, array($this, 'cmp'));
  128. return $return;
  129. }
  130. private static function cmp($a, $b) {
  131. return strcmp($b["created_time"], $a["created_time"]);
  132. }
  133. public function getHotTags($categoryId = 0,$num = 100) {
  134. return Wekit::cache()->get('hot_tags', array($categoryId, $num));
  135. }
  136. /**
  137. *
  138. * 获取热门话题
  139. * @param ing $categoryId
  140. * @param ing $num
  141. */
  142. public function getHotTagsNoCache($categoryId = 0,$num = 100){
  143. // 删除过期数据
  144. $updateTime = pw::getTime() - 86400 * $this->expireDay;
  145. $this->_getTagDs()->deleteExpireHotTag($updateTime);
  146. $tags = $this->_getTagDs()->getCountHotTag($categoryId,$num);
  147. $tagIds = array_keys($tags);
  148. if (!$tagIds) return array();
  149. return $this->_getTagDs()->fetchTag($tagIds);
  150. }
  151. /**
  152. *
  153. * 获取内容的其它话题
  154. * @param string $typeName
  155. * @param array $params 内容参数ID
  156. * @param array $excludeTagIds 需排除的当前话题列表 format: array(tag_id_param_id,..);
  157. */
  158. public function getRelatedTags($typeName,$params,$excludeTagIds = array()){
  159. $relatedTags = array();
  160. $params = array_unique($params);
  161. $typeId = $this->getTypeIdByTypeName($typeName);
  162. $params and $tmpRelatedTags = $this->_getTagDs()->getTagsByParamIds($typeId,$params);
  163. foreach ($tmpRelatedTags as $v) {
  164. $tmpTagId = $v['tag_id'];
  165. $tmpParamId = $v['param_id'];
  166. //if (in_array("{$tmpTagId}_$tmpParamId", $excludeTagIds)) continue;
  167. $relatedTags[$tmpParamId][$tmpTagId] = $v;
  168. }
  169. return $relatedTags;
  170. }
  171. /**
  172. *
  173. * 获取关注会员
  174. * @param unknown_type $tagId
  175. */
  176. public function getTagMembers($tagId,$offset,$num = 20){
  177. $count = $this->_getTagAttentionDs()->countAttentionByTagId($tagId);
  178. if ($count < 1) {
  179. return array(0,array());
  180. }
  181. $attentions = $this->_getTagAttentionDs()->getAttentionUids($tagId,$offset,$num);
  182. $users = $this->_getUserDs()->fetchUserByUid(array_keys($attentions));
  183. return array($count,$users);
  184. }
  185. /**
  186. * 获取我关注的话题
  187. *
  188. * @param int $uid
  189. * @param int $start
  190. * @param int $limit
  191. * @return array
  192. */
  193. public function getAttentionTags($uid,$start,$limit) {
  194. $uid = intval($uid);
  195. $count = $this->_getTagAttentionDs()->countAttentionByUid($uid);
  196. if ($count < 1) {
  197. return array(0,array());
  198. }
  199. $relations = $this->_getTagDs()->getAttentionByUid($uid,$start,$limit);
  200. $tags = $this->_getTagDs()->fetchTag(array_keys($relations));
  201. return array($count,$tags);
  202. }
  203. /**
  204. * 根据应用类型和id获取话题
  205. *
  206. * @param string $type
  207. * @param int $paramId
  208. * @param int $uid 带关注
  209. * @return array
  210. */
  211. public function getTagByType($type,$paramId) {
  212. $paramId = intval($paramId);
  213. if (!$type || $paramId < 1) {
  214. return array();
  215. }
  216. $typeId = $this->getTypeIdByTypeName($type);
  217. if (!$typeId) return array();
  218. $tagRelations = $this->_getTagDs()->getTagRelationByType($typeId,$paramId);
  219. if (!count($tagRelations)) return array();
  220. $tagIds = array_keys($tagRelations);
  221. return $this->_getTagDs()->fetchTag($tagIds);
  222. }
  223. /**
  224. * 话题小名片
  225. *
  226. * @param string $name
  227. * @param int $uid 带关注
  228. * @return array
  229. */
  230. public function getTagCard($name,$uid = null) {
  231. $tag = $this->_getTagDs()->getTagByName($name);
  232. if (!$tag) return array();
  233. if ($uid) {
  234. $attention = $this->_getTagAttentionDs()->isAttentioned($uid,$tag['tag_id']);
  235. }
  236. $attention && $tag['isAttention'] = $attention ? true : false;
  237. return $tag;
  238. }
  239. /**
  240. *
  241. * 根据类型名获取类型ID
  242. * @param string $typeName
  243. */
  244. public function getTypeIdByTypeName($typeName){
  245. $types = array_flip($this->_getTypeMap());
  246. return $types[$typeName];
  247. }
  248. /**
  249. * 关注话题
  250. *
  251. * @param int $uid
  252. * @param int $tagId
  253. * @return array
  254. */
  255. public function addAttention($uid,$tagId) {
  256. // 是否关注过了
  257. if ($this->_getTagAttentionDs()->isAttentioned($uid,$tagId)) return new PwError('Tag:have.attentioned');
  258. if (($count = $this->_getTagAttentionDs()->countAttentionByUid($uid)) > 49) {
  259. return new PwError('Tag:attentioned.count.error');
  260. }
  261. $result = (int)$this->_getTagAttentionDs()->addAttention($uid,$tagId);
  262. // 更新话题表内容数
  263. Wind::import('SRV:tag.dm.PwTagDm');
  264. $dm = new PwTagDm($tagId);
  265. $dm->addAttentionCount($result);
  266. return $this->_getTagDs()->updateTag($dm);
  267. }
  268. /**
  269. * 取消关注的话题
  270. *
  271. * @param int $uid
  272. * @param int $tagId
  273. * @return array
  274. */
  275. public function deleteAttention($uid,$tagId) {
  276. $result = (int)$this->_getTagAttentionDs()->deleteAttention($uid,$tagId);
  277. // 更新话题表内容数
  278. Wind::import('SRV:tag.dm.PwTagDm');
  279. $dm = new PwTagDm($tagId);
  280. $dm->addAttentionCount(-$result);
  281. return $this->_getTagDs()->updateTag($dm);
  282. }
  283. /**
  284. * 批量删除话题 -- 只供管理话题删除接口
  285. *
  286. * @param array $tagIds
  287. * @return bool
  288. */
  289. public function deleteByTagIds($tagIds) {
  290. $result = $this->_getTagDs()->fetchTag($tagIds);
  291. if (!$result) return false;
  292. foreach ($result as $tag) {
  293. $tag['tag_logo'] && Pw::deleteAttach($tag['tag_logo']);
  294. }
  295. $tagIds = array_keys($result);
  296. // 删除热门话题排行
  297. $this->_getTagDs()->deleteTagRecords($tagIds);
  298. // 删除分类关系
  299. $this->_getTagCateGoryDs()->deleteCateGoryRelations($tagIds);
  300. // 删除关注
  301. $this->_getTagAttentionDs()->deleteAttentions($tagIds);
  302. // 删除内容关系
  303. $this->_getTagDs()->deleteRelations($tagIds);
  304. $this->clearTagsByParentIds($tagIds);//TODO
  305. // 删除话题
  306. $this->_getTagDs()->batchDelete($tagIds);
  307. return true;
  308. }
  309. /**
  310. *
  311. * 取消某话题的关联话题
  312. * @param int $tagId
  313. */
  314. public function removeRelatedTopic($tagId){
  315. $tagId = intval($tagId);
  316. $childTags = $this->_getTagDs()->getTagByParent($tagId);
  317. if (!$childTags) return true;
  318. $childTagIds = array();
  319. foreach ($childTags as $tag){
  320. $childTagIds[] = $tag['tag_id'];
  321. $this->_getTagDs()->updateTagRelationByTagId($tagId,$tag['tag_id']);
  322. }
  323. Wind::import('SRV:tag.dm.PwTagDm');
  324. $dm = new PwTagDm();
  325. $dm->setParent(0);
  326. $this->_getTagDs()->updateTags($childTagIds,$dm);
  327. }
  328. /**
  329. * 搜索话题列表
  330. *
  331. * @param int $start
  332. * @param int $limit
  333. * @param string $name
  334. * @param int $ifHot
  335. * @param int $categoryId
  336. * @param int $attentionCountStart
  337. * @param int $attentionCountEnd
  338. * @param int $contentCountStart
  339. * @param int $contentCountEnd
  340. * @return array
  341. */
  342. public function getTagByCondition($start,$limit,$name,$ifHot,$categoryId,$attentionCountStart,$attentionCountEnd,$contentCountStart,$contentCountEnd) {
  343. $count = $this->_getTagDs()->countTagByCondition($name,$ifHot,$categoryId,$attentionCountStart,$attentionCountEnd,$contentCountStart,$contentCountEnd);
  344. if ($count < 1) return array(0,array());
  345. $tags = $this->_getTagDs()->getTagByCondition($start,$limit,$name,$ifHot,$categoryId,$attentionCountStart,$attentionCountEnd,$contentCountStart,$contentCountEnd);
  346. //取话题分类关系
  347. $categoryRelations = $this->_getTagCateGoryDs()->getRelationsByTagIds(array_keys($tags));
  348. $tmpCategories = array();
  349. foreach ($categoryRelations as $l) {
  350. $tmpCategories[$l['tag_id']][] = $l['category_id'];
  351. }
  352. foreach ($tags as $k => $v) {
  353. $v['parent_tag_id'] or $v['joinTag'] = $this->_getTagDs()->getTagByParent($k);
  354. $v['categories'] = $tmpCategories[$k];
  355. $tags[$k] = $v;
  356. }
  357. return array($count,$tags);
  358. }
  359. /**
  360. * 批量删除内容关系
  361. *
  362. * @param string $type
  363. * @param array $paramIds
  364. * @return bool
  365. */
  366. public function batchDeleteRelation($typeId,$paramIds) {
  367. return $this->_getTagDs()->batchDeleteRelation($typeId,$paramIds);
  368. }
  369. /**
  370. * 解析话题 #话题#
  371. *
  372. * @param string $content
  373. * @return string
  374. */
  375. public function parserTags($content) {
  376. if (!$content) return array();
  377. preg_match_all('/\#(.*)\#/iUs', $content, $matches);
  378. if (!$matches[1]) return array();
  379. $tags = array();
  380. foreach ($matches[1] as $v) {
  381. $v = trim($v);
  382. if (!$v) continue;
  383. $tags[] = $v;
  384. }
  385. return $tags;
  386. }
  387. /**
  388. *
  389. * 获取类型ID和类型名的对应关系
  390. * @return array
  391. */
  392. private function _getTypeMap(){
  393. return $this->_getTagDs()->typeMap;
  394. }
  395. /**
  396. *
  397. * 获取Tag实现方法
  398. * @param string $typeName
  399. */
  400. private function _getTagAction($typeName){
  401. $typeName = strtolower($typeName);
  402. if (!$this->getTypeIdByTypeName($typeName)) return null;
  403. $className = 'PwTag' . ucfirst($typeName);
  404. Wind::import('SRV:tag.srv.action.' . $className);
  405. return new $className;
  406. }
  407. protected function _formatTags($tags) {
  408. if (!$tags) return false;
  409. $tagname = array();
  410. foreach ($tags as $v) {
  411. $tagname[] = $v['tag_name'];
  412. }
  413. return implode(',',$tagname);
  414. }
  415. private function _getCacheService(){
  416. Wind::import("Lib:utility.PwCacheService");
  417. return new PwCacheService();
  418. }
  419. /**
  420. * 话题DS
  421. *
  422. * @return PwTag
  423. */
  424. private function _getTagDs(){
  425. return Wekit::load('tag.PwTag');
  426. }
  427. /**
  428. * 分类DS
  429. *
  430. * @return PwTagCateGory
  431. */
  432. private function _getTagCateGoryDs(){
  433. return Wekit::load('tag.PwTagCateGory');
  434. }
  435. /**
  436. * 关注DS
  437. *
  438. * @return PwTagAttention
  439. */
  440. private function _getTagAttentionDs(){
  441. return Wekit::load('tag.PwTagAttention');
  442. }
  443. /**
  444. *
  445. * Enter description here ...
  446. * @return PwUser
  447. */
  448. private function _getUserDs(){
  449. return Wekit::load('user.PwUser');
  450. }
  451. }