/bp-forums/bbpress/bb-includes/functions.bb-topic-tags.php

  1. <?php 
  2.  
  3. /** Tags */ 
  4.  
  5. /** 
  6. * bb_add_topic_tag() - Adds a single tag to a topic. 
  7. * 
  8. * @param int $topic_id 
  9. * @param string $tag The (unsanitized) full name of the tag to be added 
  10. * @return int|bool The TT_ID of the new bb_topic_tag or false on failure 
  11. */ 
  12. function bb_add_topic_tag( $topic_id, $tag ) { 
  13. $tt_ids = bb_add_topic_tags( $topic_id, $tag ); 
  14. if ( is_array( $tt_ids ) ) 
  15. return $tt_ids[0]; 
  16. return false; 
  17.  
  18. /** 
  19. * bb_add_topic_tag() - Adds a multiple tags to a topic. 
  20. * 
  21. * @param int $topic_id 
  22. * @param array|string $tags The (unsanitized) full names of the tag to be added. CSV or array. 
  23. * @return array|bool The TT_IDs of the new bb_topic_tags or false on failure 
  24. */ 
  25. function bb_add_topic_tags( $topic_id, $tags ) { 
  26. global $wp_taxonomy_object; 
  27. $topic_id = (int) $topic_id; 
  28. if ( !$topic = get_topic( $topic_id ) ) 
  29. return false; 
  30. if ( !bb_current_user_can( 'add_tag_to', $topic_id ) ) 
  31. return false; 
  32.  
  33. $user_id = bb_get_current_user_info( 'id' ); 
  34.  
  35. $tags = apply_filters( 'bb_add_topic_tags', $tags, $topic_id ); 
  36.  
  37. if ( !is_array( $tags ) ) 
  38. $tags = explode(', ', (string) $tags); 
  39.  
  40. $tt_ids = $wp_taxonomy_object->set_object_terms( $topic->topic_id, $tags, 'bb_topic_tag', array( 'append' => true, 'user_id' => $user_id ) ); 
  41.  
  42. if ( is_array($tt_ids) ) { 
  43. global $bbdb; 
  44. $bbdb->query( $bbdb->prepare( 
  45. "UPDATE $bbdb->topics SET tag_count = tag_count + %d WHERE topic_id = %d", count( $tt_ids ), $topic->topic_id 
  46. ) ); 
  47. wp_cache_delete( $topic->topic_id, 'bb_topic' ); 
  48. foreach ( $tt_ids as $tt_id ) 
  49. do_action('bb_tag_added', $tt_id, $user_id, $topic_id); 
  50. return $tt_ids; 
  51. return false; 
  52.  
  53. /** 
  54. * bb_create_tag() - Creates a single bb_topic_tag. 
  55. * 
  56. * @param string $tag The (unsanitized) full name of the tag to be created 
  57. * @return int|bool The TT_ID of the new bb_topic_tags or false on failure 
  58. */ 
  59. function bb_create_tag( $tag ) { 
  60. global $wp_taxonomy_object; 
  61.  
  62. if ( list($term_id, $tt_id) = $wp_taxonomy_object->is_term( $tag, 'bb_topic_tag' ) ) 
  63. return $tt_id; 
  64.  
  65. $term = $wp_taxonomy_object->insert_term( $tag, 'bb_topic_tag' ); 
  66. if ( is_wp_error( $term ) ) 
  67. return false; 
  68.  
  69. list( $term_id, $tt_id ) = $term; 
  70. if ( ! $tt_id ) 
  71. return false; 
  72.  
  73. return $tt_id; 
  74.  
  75. /** 
  76. * bb_remove_topic_tag() - Removes a single bb_topic_tag by a user from a topic. 
  77. * 
  78. * @param int $tt_id The TT_ID of the bb_topic_tag to be removed 
  79. * @param int $user_id 
  80. * @param int $topic_id 
  81. * @return array|false The TT_IDs of the users bb_topic_tags on that topic or false on failure 
  82. */ 
  83. function bb_remove_topic_tag( $tt_id, $user_id, $topic_id ) { 
  84. global $wp_taxonomy_object; 
  85. $tt_id = (int) $tt_id; 
  86. $user_id = (int) $user_id; 
  87. $topic_id = (int) $topic_id; 
  88. if ( !$topic = get_topic( $topic_id ) ) 
  89. return false; 
  90. if ( !bb_current_user_can( 'edit_tag_by_on', $user_id, $topic_id ) ) 
  91. return false; 
  92.  
  93. $_tag = bb_get_tag( $tt_id ); 
  94.  
  95. do_action('bb_pre_tag_removed', $tt_id, $user_id, $topic_id); 
  96. $currents = $wp_taxonomy_object->get_object_terms( $topic_id, 'bb_topic_tag', array( 'user_id' => $user_id, 'fields' => 'all' ) ); 
  97. if ( !is_array( $currents ) ) 
  98. return false; 
  99.  
  100. $found_tag_to_remove = false; 
  101. $current_tag_term_ids = array(); 
  102. foreach ( $currents as $current ) { 
  103. if ( $current->term_taxonomy_id == $tt_id ) { 
  104. $found_tag_to_remove = true; 
  105. continue; 
  106. $current_tag_term_ids[] = $current->term_id; 
  107.  
  108. if ( !$found_tag_to_remove ) 
  109. return false; 
  110.  
  111. $current_tag_term_ids = array_map( 'intval', $current_tag_term_ids ); 
  112.  
  113. $tt_ids = $wp_taxonomy_object->set_object_terms( $topic_id, array_values($current_tag_term_ids), 'bb_topic_tag', array( 'user_id' => $user_id ) ); 
  114. if ( is_array( $tt_ids ) ) { 
  115. global $bbdb; 
  116. $bbdb->query( $bbdb->prepare( 
  117. "UPDATE $bbdb->topics SET tag_count = %d WHERE topic_id = %d", count( $tt_ids ), $topic_id 
  118. ) ); 
  119. wp_cache_delete( $topic_id, 'bb_topic' ); 
  120.  
  121. // Count is updated at set_object_terms() 
  122. if ( $_tag && 2 > $_tag->tag_count ) { 
  123. bb_destroy_tag( $_tag->term_taxonomy_id ); 
  124. } elseif ( is_wp_error( $tt_ids ) ) { 
  125. return false; 
  126. return $tt_ids; 
  127.  
  128. /** 
  129. * bb_remove_topic_tag() - Removes all bb_topic_tags from a topic. 
  130. * 
  131. * @param int $topic_id 
  132. * @return bool 
  133. */ 
  134. function bb_remove_topic_tags( $topic_id ) { 
  135. global $wp_taxonomy_object; 
  136. $topic_id = (int) $topic_id; 
  137. if ( !$topic_id || !get_topic( $topic_id ) ) 
  138. return false; 
  139.  
  140. $_tags = bb_get_topic_tags( $topic_id ); 
  141.  
  142. do_action( 'bb_pre_remove_topic_tags', $topic_id ); 
  143.  
  144. $wp_taxonomy_object->delete_object_term_relationships( $topic_id, 'bb_topic_tag' ); 
  145.  
  146. global $bbdb; 
  147. $bbdb->query( $bbdb->prepare( 
  148. "UPDATE $bbdb->topics SET tag_count = 0 WHERE topic_id = %d", $topic_id 
  149. ) ); 
  150. wp_cache_delete( $topic_id, 'bb_topic' ); 
  151.  
  152. if ( $_tags ) { 
  153. foreach ( $_tags as $_tag ) { 
  154. // Count is updated at delete_object_term_relationships() 
  155. if ( 2 > $_tag->tag_count ) { 
  156. bb_destroy_tag( $_tag->term_taxonomy_id ); 
  157.  
  158. return true; 
  159.  
  160. /** 
  161. * bb_destroy_tag() - Completely removes a bb_topic_tag. 
  162. * 
  163. * @param int $tt_id The TT_ID of the tag to destroy 
  164. * @return bool 
  165. */ 
  166. function bb_destroy_tag( $tt_id, $recount_topics = true ) { 
  167. global $wp_taxonomy_object; 
  168.  
  169. $tt_id = (int) $tt_id; 
  170.  
  171. if ( !$tag = bb_get_tag( $tt_id ) ) 
  172. return false; 
  173.  
  174. if ( is_wp_error($tag) ) 
  175. return false; 
  176.  
  177. $topic_ids = bb_get_tagged_topic_ids( $tag->term_id ); 
  178.  
  179. $return = $wp_taxonomy_object->delete_term( $tag->term_id, 'bb_topic_tag' ); 
  180.  
  181. if ( is_wp_error($return) ) 
  182. return false; 
  183.  
  184. if ( !is_wp_error( $topic_ids ) && is_array( $topic_ids ) ) { 
  185. global $bbdb; 
  186. $bbdb->query( 
  187. "UPDATE $bbdb->topics SET tag_count = tag_count - 1 WHERE topic_id IN (" . join( ', ', $topic_ids ) . ")" 
  188. ); 
  189. foreach ( $topic_ids as $topic_id ) { 
  190. wp_cache_delete( $topic_id, 'bb_topic' ); 
  191.  
  192. return $return; 
  193.  
  194. /** 
  195. * bb_get_tag_id() - Returns the id of the specified or global tag. 
  196. * 
  197. * @param mixed $id The TT_ID, tag name of the desired tag, or 0 for the global tag 
  198. * @return int  
  199. */ 
  200. function bb_get_tag_id( $id = 0 ) { 
  201. global $tag; 
  202. if ( $id ) { 
  203. $_tag = bb_get_tag( $id ); 
  204. } else { 
  205. $_tag =& $tag; 
  206. return (int) $_tag->tag_id; 
  207.  
  208. /** 
  209. * bb_get_tag() - Returns the specified tag. If $user_id and $topic_id are passed, will check to see if that tag exists on that topic by that user. 
  210. * 
  211. * @param mixed $id The TT_ID or tag name of the desired tag 
  212. * @param int $user_id (optional) 
  213. * @param int $topic_id (optional) 
  214. * @return object Term object (back-compat) 
  215. */ 
  216. function bb_get_tag( $id, $user_id = 0, $topic_id = 0 ) { 
  217. global $wp_taxonomy_object; 
  218. $user_id = (int) $user_id; 
  219. $topic_id = (int) $topic_id; 
  220.  
  221. $term = false; 
  222. if ( is_integer( $id ) ) { 
  223. $tt_id = (int) $id; 
  224. } else { 
  225. if ( !$term = $wp_taxonomy_object->get_term_by( 'slug', $id, 'bb_topic_tag' ) ) 
  226. return false; 
  227. $tt_id = (int) $term->term_taxonomy_id; 
  228.  
  229. if ( $user_id && $topic_id ) { 
  230. $args = array( 'user_id' => $user_id, 'fields' => 'tt_ids' ); 
  231. $cache_id = $topic_id . serialize( $args ); 
  232.  
  233. $tt_ids = wp_cache_get( $cache_id, 'bb_topic_tag_terms' ); 
  234. if ( empty( $tt_ids ) ) { 
  235. $tt_ids = $wp_taxonomy_object->get_object_terms( $topic_id, 'bb_topic_tag', $args ); 
  236. wp_cache_set( $cache_id, $tt_ids, 'bb_topic_tag_terms' ); 
  237. if ( !in_array( $tt_id, $tt_ids ) ) 
  238. return false; 
  239.  
  240. if ( !$term ) 
  241. $term = $wp_taxonomy_object->get_term_by( 'tt_id', $tt_id, 'bb_topic_tag' ); 
  242.  
  243. _bb_make_tag_compat( $term ); 
  244.  
  245. return $term; 
  246.  
  247. /** 
  248. * bb_get_topic_tags() - Returns all of the bb_topic_tags associated with the specified topic. 
  249. * 
  250. * @param int $topic_id 
  251. * @param mixed $args 
  252. * @return array|false Term objects (back-compat), false on failure 
  253. */ 
  254. function bb_get_topic_tags( $topic_id = 0, $args = null ) { 
  255. global $wp_taxonomy_object; 
  256.  
  257. if ( !$topic = get_topic( get_topic_id( $topic_id ) ) ) 
  258. return false; 
  259.  
  260. $topic_id = (int) $topic->topic_id; 
  261.  
  262. $cache_id = $topic_id . serialize( $args ); 
  263.  
  264. $terms = wp_cache_get( $cache_id, 'bb_topic_tag_terms' ); 
  265. if ( false === $terms ) { 
  266. $terms = $wp_taxonomy_object->get_object_terms( (int) $topic->topic_id, 'bb_topic_tag', $args ); 
  267. wp_cache_set( $cache_id, $terms, 'bb_topic_tag_terms' ); 
  268.  
  269. if ( is_wp_error( $terms ) ) 
  270. return false; 
  271.  
  272. for ( $i = 0; isset($terms[$i]); $i++ ) 
  273. _bb_make_tag_compat( $terms[$i] ); 
  274.  
  275. return $terms; 
  276.  
  277. function bb_get_user_tags( $topic_id, $user_id ) { 
  278. $tags = bb_get_topic_tags( $topic_id ); 
  279. if ( !is_array( $tags ) ) 
  280. return; 
  281. $user_tags = array(); 
  282.  
  283. foreach ( $tags as $tag ) : 
  284. if ( $tag->user_id == $user_id ) 
  285. $user_tags[] = $tag; 
  286. endforeach; 
  287. return $user_tags; 
  288.  
  289. function bb_get_other_tags( $topic_id, $user_id ) { 
  290. $tags = bb_get_topic_tags( $topic_id ); 
  291. if ( !is_array( $tags ) ) 
  292. return; 
  293. $other_tags = array(); 
  294.  
  295. foreach ( $tags as $tag ) : 
  296. if ( $tag->user_id != $user_id ) 
  297. $other_tags[] = $tag; 
  298. endforeach; 
  299. return $other_tags; 
  300.  
  301. function bb_get_public_tags( $topic_id ) { 
  302. $tags = bb_get_topic_tags( $topic_id ); 
  303. if ( !is_array( $tags ) ) 
  304. return; 
  305. $used_tags = array(); 
  306. $public_tags = array(); 
  307.  
  308. foreach ( $tags as $tag ) : 
  309. if ( !in_array($tag->tag_id, $used_tags) ) : 
  310. $public_tags[] = $tag; 
  311. $used_tags[] = $tag->tag_id; 
  312. endif; 
  313. endforeach; 
  314. return $public_tags; 
  315.  
  316. function bb_get_tagged_topic_ids( $tag_id ) { 
  317. global $wp_taxonomy_object, $tagged_topic_count; 
  318.  
  319. if ( $topic_ids = (array) $wp_taxonomy_object->get_objects_in_term( $tag_id, 'bb_topic_tag', array( 'field' => 'tt_id' ) ) ) { 
  320. $tagged_topic_count = count($topic_ids); 
  321. return apply_filters('get_tagged_topic_ids', $topic_ids); 
  322. } else { 
  323. $tagged_topic_count = 0; 
  324. return false; 
  325.  
  326. function get_tagged_topics( $args ) { 
  327. global $tagged_topic_count; 
  328. $_args = func_get_args(); 
  329. $defaults = array( 'tag_id' => false, 'page' => 1, 'number' => false, 'count' => true ); 
  330. if ( is_numeric( $args ) ) 
  331. $args = array( 'tag_id' => $args ); 
  332. else 
  333. $args = wp_parse_args( $args ); // Make sure it's an array 
  334. if ( 1 < func_num_args() ) 
  335. $args['page'] = $_args[1]; 
  336. if ( 2 < func_num_args() ) 
  337. $args['number'] = $_args[2]; 
  338.  
  339. $args = wp_parse_args( $args, $defaults ); 
  340. extract( $args, EXTR_SKIP ); 
  341.  
  342. $q = array('tag_id' => (int) $tag_id, 'page' => (int) $page, 'per_page' => (int) $number, 'count' => $count ); 
  343.  
  344. $query = new BB_Query( 'topic', $q, 'get_tagged_topics' ); 
  345. $tagged_topic_count = $query->found_rows; 
  346.  
  347. return $query->results; 
  348.  
  349. function get_tagged_topic_posts( $args ) { 
  350. $_args = func_get_args(); 
  351. $defaults = array( 'tag_id' => false, 'page' => 1, 'number' => false ); 
  352. if ( is_numeric( $args ) ) 
  353. $args = array( 'tag_id' => $args ); 
  354. else 
  355. $args = wp_parse_args( $args ); // Make sure it's an array 
  356. if ( 1 < func_num_args() ) 
  357. $args['page'] = $_args[1]; 
  358. if ( 2 < func_num_args() ) 
  359. $args['number'] = $_args[2]; 
  360.  
  361. $args = wp_parse_args( $args, $defaults ); 
  362. extract( $args, EXTR_SKIP ); 
  363.  
  364. $q = array('tag_id' => (int) $tag_id, 'page' => (int) $page, 'per_page' => (int) $number); 
  365.  
  366. $query = new BB_Query( 'post', $q, 'get_tagged_topic_posts' ); 
  367. return $query->results; 
  368.  
  369. /** 
  370. * bb_get_top_tags() - Returns most popular tags. 
  371. * 
  372. * @param mixed $args 
  373. * @return array|false Term objects (back-compat), false on failure 
  374. */ 
  375. function bb_get_top_tags( $args = null ) { 
  376. global $wp_taxonomy_object; 
  377.  
  378. $args = wp_parse_args( $args, array( 'number' => 40 ) ); 
  379. $args['order'] = 'DESC'; 
  380. $args['orderby'] = 'count'; 
  381.  
  382. $terms = $wp_taxonomy_object->get_terms( 'bb_topic_tag', $args ); 
  383. if ( is_wp_error( $terms ) ) 
  384. return false; 
  385.  
  386. foreach ( $terms as $term ) 
  387. _bb_make_tag_compat( $term ); 
  388.  
  389. return $terms; 
  390.  
  391. /** 
  392. * Adds some back-compat properties/elements to a term. 
  393. * 
  394. * Casting $tag->term_taxonomy_id to an integer is important since 
  395. * we check it against is_integer() in bb_get_tag() 
  396. * 
  397. * @internal 
  398. */ 
  399. function _bb_make_tag_compat( &$tag ) { 
  400. if ( is_object($tag) && isset($tag->term_id) ) { 
  401. $tag->term_taxonomy_id = (int) $tag->term_taxonomy_id; 
  402. $tag->tag_id =& $tag->term_taxonomy_id; 
  403. $tag->tag =& $tag->slug; 
  404. $tag->raw_tag =& $tag->name; 
  405. $tag->tag_count =& $tag->count; 
  406. } elseif ( is_array($tag) && isset($tag['term_id']) ) { 
  407. $tag['term_taxonomy_id'] = (int) $tag['term_taxonomy_id']; 
  408. $tag['tag_id'] =& $tag['term_taxonomy_id']; 
  409. $tag['tag'] =& $tag['slug']; 
  410. $tag['raw_tag'] =& $tag['name']; 
  411. $tag['tag_count'] =& $tag['count']; 
  412.  
  413. function bb_rename_tag( $tag_id, $tag_name ) { 
  414. if ( !bb_current_user_can( 'manage_tags' ) ) { 
  415. return false; 
  416.  
  417. $tag_id = (int) $tag_id; 
  418. $raw_tag = bb_trim_for_db( $tag_name, 50 ); 
  419. $tag_name = tag_sanitize( $tag_name );  
  420.  
  421. if ( empty( $tag_name ) ) { 
  422. return false; 
  423.  
  424. if ( $existing_tag = bb_get_tag( $tag_name ) ) { 
  425. if ( $existing_tag->term_id !== $tag_id ) { 
  426. return false; 
  427.  
  428. if ( !$old_tag = bb_get_tag( $tag_id ) ) { 
  429. return false; 
  430.  
  431. global $wp_taxonomy_object; 
  432. $ret = $wp_taxonomy_object->update_term( $tag_id, 'bb_topic_tag', array( 'name' => $raw_tag, 'slug' => $tag_name ) ); 
  433.  
  434. if ( $ret && !is_wp_error( $ret ) ) { 
  435. do_action( 'bb_tag_renamed', $tag_id, $old_tag->raw_tag, $raw_tag ); 
  436. return bb_get_tag( $tag_id ); 
  437. return false; 
  438.  
  439. // merge $old_id into $new_id. 
  440. function bb_merge_tags( $old_id, $new_id ) { 
  441. if ( !bb_current_user_can( 'manage_tags' ) ) { 
  442. return false; 
  443.  
  444. $old_id = (int) $old_id; 
  445. $new_id = (int) $new_id; 
  446.  
  447. if ( $old_id == $new_id ) { 
  448. return false; 
  449.  
  450. do_action( 'bb_pre_merge_tags', $old_id, $new_id ); 
  451.  
  452. // Get all topics tagged with old tag 
  453. $old_topics = bb_get_tagged_topic_ids( $old_id ); 
  454.  
  455. // Get all toics tagged with new tag 
  456. $new_topics = bb_get_tagged_topic_ids( $new_id ); 
  457.  
  458. // Get intersection of those topics 
  459. $both_topics = array_intersect( $old_topics, $new_topics ); 
  460.  
  461. // Discard the intersection from the old tags topics 
  462. $old_topics = array_diff( $old_topics, $both_topics ); 
  463.  
  464. // Add the remainder of the old tag topics to the new tag 
  465. if ( count( $old_topics ) ) { 
  466. $new_tag = bb_get_tag( $new_id ); 
  467. foreach ( $old_topics as $old_topic ) { 
  468. bb_add_topic_tag( $old_topic, $new_tag->slug ); 
  469.  
  470. // Destroy the old tag 
  471. $old_tag = bb_destroy_tag( $old_id ); 
  472.  
  473. return array( 'destroyed' => $old_tag, 'old_count' => count( $old_topics ), 'diff_count' => count( $both_topics ) ); 
.