PageRenderTime 57ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-content/plugins/cpt-onomies/cpt-onomy.php

https://bitbucket.org/metrobee/tr.deconord.eu
PHP | 1670 lines | 1003 code | 217 blank | 450 comment | 268 complexity | be621b387a1a7f8e1ea10d0cbba9b726 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Holds the functions needed for using a custom post type as a taxonomy.
  4. *
  5. * @since 1.0
  6. */
  7. class CPT_TAXONOMY {
  8. /**
  9. * Adds WordPress hooks (actions and filters).
  10. *
  11. * @since 1.0
  12. */
  13. public function CPT_TAXONOMY() { $this->__construct(); }
  14. public function __construct() {
  15. // function filters
  16. add_filter( 'get_terms', array( &$this, 'get_terms' ), 1, 3 );
  17. add_filter( 'wp_get_object_terms', array( &$this, 'wp_get_object_terms' ), 1, 4 );
  18. // other filters
  19. add_filter( 'get_terms_args', array( &$this, 'adjust_get_terms_args' ), 1, 2 );
  20. }
  21. /**
  22. * This function takes an object's information and creates a term object.
  23. *
  24. * As of version 1.2, you can hook into the 'term_description' or
  25. * '{$taxonomy}_description' filter to add a description to your terms.
  26. *
  27. * The variable type (object or array) for the returned $term will match the set type of the passed $object.
  28. *
  29. * @since 1.0
  30. * @uses $cpt_onomies_manager
  31. * @param array|object $object - the information for the object you are converting
  32. * @param boolean $get_count - whether to get the term count
  33. * @return array|object - the information for the term you have created.
  34. */
  35. private function convert_object_to_cpt_onomy_term( $object, $get_count=true ) {
  36. global $cpt_onomies_manager;
  37. if ( empty( $object ) ) return $object;
  38. else {
  39. $term = (object) $object;
  40. if ( !$cpt_onomies_manager->is_registered_cpt_onomy( $term->post_type ) ) return $object;
  41. else {
  42. // sanitize_term_field() lets you apply the 'term_description' or '{$taxonomy}_description' filter to
  43. // tweak the description, if desired. Maybe you want the description to be a custom field? or the
  44. // post content. Just return that info in the filter!
  45. $term = array(
  46. 'term_id' => $term->ID,
  47. 'name' => apply_filters( 'the_title', $term->post_title, $term->ID ),
  48. 'slug' => $term->post_name,
  49. 'term_group' => $term->post_parent,
  50. 'term_taxonomy_id' => 0,
  51. 'taxonomy' => $term->post_type,
  52. 'description' => sanitize_term_field( 'description', '', $term->ID, $term->post_type, 'display' ),
  53. 'parent' => $term->post_parent
  54. );
  55. if ( $get_count ) $term[ 'count' ] = $this->get_term_count( $term[ 'term_id' ], $term[ 'taxonomy' ] );
  56. if ( is_object( $object ) ) return (object) $term;
  57. else return $term;
  58. }
  59. }
  60. }
  61. /**
  62. * Since setting the argument 'fields' to 'count' will not work with CPT-onomies,
  63. * this gets rid of that field and adds a custom count argument that's applied
  64. * in our get_terms() filter function. This allows the WP function wp_count_terms()
  65. * to work with CPT-onomies.
  66. *
  67. * This function is applied to the filter 'get_terms_args'.
  68. * The filter 'get_terms_args' was not added to get_terms() until 3.1 so this
  69. * function will not work before WordPress version 3.1.
  70. *
  71. * @since 1.0.2
  72. * @uses $cpt_onomies_manager
  73. * @param array $args - original get_terms() arguments
  74. * @param array $taxonomies - the taxonomies we're getting terms from
  75. * @return array - the filtered $args
  76. */
  77. public function adjust_get_terms_args( $args, $taxonomies ) {
  78. global $cpt_onomies_manager;
  79. // this function only filters registered CPT-onomies
  80. $cpt_taxonomies = array();
  81. foreach( $taxonomies as $taxonomy ) {
  82. if ( $cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  83. $cpt_taxonomies[] = $taxonomy;
  84. }
  85. // this means there are no CPT-onomies so wrap things up
  86. if ( empty( $cpt_taxonomies ) )
  87. return $args;
  88. // change 'fields' to 'ids' and add a custom count argument
  89. if ( isset( $args[ 'fields' ] ) && $args[ 'fields' ] == 'count' ) {
  90. $args[ 'fields' ] = 'ids';
  91. $args[ 'cpt_onomy_get_count' ] = true;
  92. }
  93. return $args;
  94. }
  95. /**
  96. * This function mimics the WordPress function get_term()
  97. * because we cannot hook into the function without receiving errors.
  98. *
  99. * @since 1.0
  100. * @uses $cpt_onomies_manager
  101. * @param int|object $term If integer, will get from database. If object will apply filters and return $term.
  102. * @param string $taxonomy Taxonomy name that $term is part of.
  103. * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N
  104. * @param string $filter Optional, default is raw or no WordPress defined filter will applied.
  105. * @return mixed|null|WP_Error Term Row from database. Will return null if $term is empty. If taxonomy does not
  106. * exist then WP_Error will be returned.
  107. */
  108. public function get_term( $term, $taxonomy, $output = OBJECT, $filter = 'raw' ) {
  109. global $cpt_onomies_manager;
  110. $null = null;
  111. if ( empty( $term ) ) {
  112. $error = new WP_Error( 'invalid_term', __( 'Empty Term', CPT_ONOMIES_TEXTDOMAIN ) );
  113. return $error;
  114. }
  115. if ( ! taxonomy_exists( $taxonomy ) ) {
  116. $error = new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy', CPT_ONOMIES_TEXTDOMAIN ) );
  117. return $error;
  118. }
  119. // this function only processes registered CPT-onomies
  120. // if this is a normal taxonomy, then use the WordPress function
  121. if ( !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  122. return get_term( $term, $taxonomy, $output, $filter );
  123. if ( is_object( $term ) && empty( $term->filter ) ) {
  124. wp_cache_add( $term->term_id, $term, $taxonomy );
  125. $_term = $term;
  126. } else {
  127. if ( is_object( $term ) )
  128. $term = $term->term_id;
  129. if ( !$term = (int) $term )
  130. return $null;
  131. if ( ! $_term = wp_cache_get( $term, $taxonomy ) ) {
  132. $_term = $this->convert_object_to_cpt_onomy_term( get_post( $term ) );
  133. if ( ! $_term )
  134. return $null;
  135. wp_cache_add( $term, $_term, $taxonomy );
  136. }
  137. }
  138. $_term = apply_filters( 'get_term', $_term, $taxonomy );
  139. $_term = apply_filters( "get_$taxonomy", $_term, $taxonomy );
  140. $_term = sanitize_term( $_term, $taxonomy, $filter );
  141. if ( $output == OBJECT ) {
  142. return $_term;
  143. } elseif ( $output == ARRAY_A ) {
  144. $__term = get_object_vars( $_term );
  145. return $__term;
  146. } elseif ( $output == ARRAY_N ) {
  147. $__term = array_values( get_object_vars( $_term ) );
  148. return $__term;
  149. } else {
  150. return $_term;
  151. }
  152. }
  153. /**
  154. * This function mimics the WordPress function get_term_by()
  155. * because we cannot hook into the function without receiving errors.
  156. *
  157. * @since 1.0
  158. * @uses $wpdb, $cpt_onomies_manager
  159. * @param string $field Either 'slug', 'name', or 'id'
  160. * @param string|int $value Search for this term value
  161. * @param string $taxonomy Taxonomy Name
  162. * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N
  163. * @param string $filter Optional, default is raw or no WordPress defined filter will applied.
  164. * @param inte $parent allows to get a term by its parent's term id
  165. * @return mixed Term Row from database. Will return false if $taxonomy does not exist or $term was not found.
  166. */
  167. public function get_term_by( $field, $value, $taxonomy, $output = OBJECT, $filter = 'raw', $parent = 0 ) {
  168. global $wpdb, $cpt_onomies_manager;
  169. if ( ! taxonomy_exists($taxonomy) )
  170. return false;
  171. // this function only processes registered CPT-onomies
  172. // if this is a normal taxonomy, then use the WordPress function
  173. if ( !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  174. return get_term_by( $field, $value, $taxonomy, $output, $filter );
  175. if ( $parent > 0 )
  176. $parent = " AND post_parent = " . $parent;
  177. else
  178. $parent = NULL;
  179. if ( 'slug' == $field ) {
  180. $value = sanitize_title($value);
  181. if ( empty($value) )
  182. return false;
  183. $query = "SELECT * FROM " . $wpdb->posts . " WHERE post_type = '" . $taxonomy . "' AND post_name = '" . $value . "' and post_status = 'publish'" . $parent;
  184. } else if ( 'name' == $field ) {
  185. // Assume already escaped
  186. $value = stripslashes($value);
  187. $query = "SELECT * FROM " . $wpdb->posts . " WHERE post_type = '" . $taxonomy . "' AND post_title = '" . $value . "' and post_status = 'publish'" . $parent;
  188. } else {
  189. $term = $this->get_term( (int) $value, $taxonomy, $output, $filter);
  190. if ( is_wp_error( $term ) )
  191. $term = false;
  192. return $term;
  193. }
  194. $term = $this->convert_object_to_cpt_onomy_term( $wpdb->get_row( $wpdb->prepare( $query, NULL ) ) );
  195. if ( !$term )
  196. return false;
  197. wp_cache_add($term->term_id, $term, $taxonomy);
  198. $term = apply_filters( 'get_term', $term, $taxonomy );
  199. $term = apply_filters( "get_$taxonomy", $term, $taxonomy );
  200. $term = sanitize_term( $term, $taxonomy, $filter );
  201. if ( $output == OBJECT ) {
  202. return $term;
  203. } elseif ( $output == ARRAY_A ) {
  204. return get_object_vars($term);
  205. } elseif ( $output == ARRAY_N ) {
  206. return array_values(get_object_vars($term));
  207. } else {
  208. return $term;
  209. }
  210. }
  211. /**
  212. * As of 1.0.2, wp_count_terms() works with CPT-onomies so this
  213. * function is now deprecated and will send you to the WordPress function.
  214. *
  215. * As of version 1.0.3, the WordPress minimum version is 3.1 and the filter
  216. * 'get_terms_args' that allows CPT-onomies to work with wp_count_terms() was
  217. * added in 3.1 so everyone is sent to the WordPress function.
  218. *
  219. * @param string $taxonomy Taxonomy name
  220. * @param array|string $args Overwrite defaults. See get_terms()
  221. * @return int How many terms are in $taxonomy
  222. */
  223. public function wp_count_terms( $taxonomy, $args = array() ) {
  224. return wp_count_terms( $taxonomy, $args );
  225. }
  226. /**
  227. * This function determines how many times a term has been assigned to an object.
  228. *
  229. * @since 1.0
  230. * @uses $wpdb, $cpt_onomies_manager
  231. * @param int $term_id - the ID of the term you're counting
  232. * @param string $taxonomy - the taxonomy the term belongs to
  233. * @return int - the number of times a term has been assigned to an object
  234. */
  235. public function get_term_count( $term_id, $taxonomy ) {
  236. global $wpdb, $cpt_onomies_manager;
  237. if ( is_numeric( $term_id ) && $cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) ) {
  238. // we're only counting the posts who are supposed to be associated with this taxonomy
  239. $eligible_post_types = array();
  240. foreach( get_taxonomy( $taxonomy )->object_type as $index => $object_type ) $eligible_post_types[ $index ] = "'" . $object_type . "'";
  241. $eligible_post_types = implode( ',', $eligible_post_types );
  242. return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM " . $wpdb->postmeta . " INNER JOIN " . $wpdb->posts . " ON " . $wpdb->posts . ".ID = " . $wpdb->postmeta . ".post_id WHERE " . $wpdb->postmeta . ".meta_key = %s AND " . $wpdb->postmeta . ".meta_value = %d AND " . $wpdb->posts . ".post_status = 'publish' AND " . $wpdb->posts . ".post_type IN (" . $eligible_post_types . ")", CPT_ONOMIES_POSTMETA_KEY, $term_id ) );
  243. }
  244. return 0;
  245. }
  246. /**
  247. * This function mimics the WordPress function get_term_children()
  248. * because we cannot hook into the function without receiving errors.
  249. *
  250. * As of Wordpress 3.3.2, CPT-onomies will work with get_term_children()
  251. * but I'm not a fan of how WordPress stores the children ids in an option.
  252. *
  253. * @since 1.0
  254. * @uses $wpdb, $cpt_onomies_manager
  255. * @param string $term_id ID of Term to get children
  256. * @param string $taxonomy Taxonomy Name
  257. * @return array|WP_Error List of Term Objects. WP_Error returned if $taxonomy does not exist
  258. */
  259. public function get_term_children( $term_id, $taxonomy ) {
  260. global $wpdb, $cpt_onomies_manager;
  261. if ( ! taxonomy_exists( $taxonomy ) )
  262. return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy', CPT_ONOMIES_TEXTDOMAIN ) );
  263. // this function only processes registered CPT-onomies
  264. // if this is a normal taxonomy, then use the WordPress function
  265. if ( !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  266. return get_term_children( $term_id, $taxonomy );
  267. $term_id = intval( $term_id );
  268. $children = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM " . $wpdb->posts . " WHERE post_parent = %d AND post_status = 'publish' AND post_type = %s", $term_id, $taxonomy ) );
  269. if ( empty( $children ) )
  270. return array();
  271. foreach ( $children as $child_id ) {
  272. $children = array_merge( $children, $this->get_term_children( $child_id, $taxonomy ) );
  273. }
  274. return $children;
  275. }
  276. /**
  277. * Get an array of ancestor IDs for a given term.
  278. *
  279. * @since 1.1
  280. * @uses $cpt_onomies_manager
  281. * @param int $term_id - The ID of the term for which we'll be retrieving ancestors
  282. * @param string $taxonomy - the taxonomy name
  283. * @return array|WP_Error List of Term Objects. WP_Error returned if $taxonomy does not exist
  284. */
  285. public function get_term_ancestors( $term_id = 0, $taxonomy = '' ) {
  286. global $cpt_onomies_manager;
  287. if ( ! taxonomy_exists( $taxonomy ) )
  288. return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy', CPT_ONOMIES_TEXTDOMAIN ) );
  289. // this function only processes registered CPT-onomies
  290. // if this is a normal taxonomy, then use the WordPress function
  291. if ( !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  292. return get_ancestors( $term_id, $taxonomy );
  293. $term_id = (int) $term_id;
  294. $ancestors = array();
  295. if ( empty( $term_id ) )
  296. return apply_filters( 'get_ancestors', $ancestors, $term_id, $taxonomy );
  297. if ( is_taxonomy_hierarchical( $taxonomy ) ) {
  298. $term = $this->get_term( $term_id, $taxonomy );
  299. while ( ! is_wp_error( $term ) && ! empty( $term->parent ) && ! in_array( $term->parent, $ancestors ) ) {
  300. $ancestors[] = (int) $term->parent;
  301. $term = $this->get_term( $term->parent, $taxonomy );
  302. }
  303. }
  304. return apply_filters( 'get_ancestors', $ancestors, $term_id, $taxonomy );
  305. }
  306. /**
  307. * This function mimics the WordPress function term_exists()
  308. * because we cannot hook into the function without receiving errors.
  309. *
  310. * @since 1.0
  311. * @uses $wpdb, $cpt_onomies_manager
  312. * @param int|string $term The term to check
  313. * @param string $taxonomy The taxonomy name to use
  314. * @param int $parent ID of parent term under which to confine the exists search.
  315. * @return mixed Get the term id or Term Object, if exists.
  316. */
  317. public function term_exists( $term, $taxonomy = '', $parent = 0 ) {
  318. global $wpdb, $cpt_onomies_manager;
  319. if ( is_int( $term ) ) {
  320. if ( 0 == $term )
  321. return 0;
  322. // this function only processes registered CPT-onomies
  323. // if this is a normal taxonomy, then use the WordPress function
  324. if ( !empty($taxonomy) && !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  325. return term_exists( $term, $taxonomy, $parent );
  326. else if ( !empty($taxonomy) )
  327. return $this->get_term( $term, $taxonomy );
  328. else {
  329. // make sure this term belongs to a CPT-onomy
  330. $term = $this->convert_object_to_cpt_onomy_term( $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->posts . " WHERE ID = %d AND post_status = 'publish'", $term ) ) );
  331. if ( $cpt_onomies_manager->is_registered_cpt_onomy( $term->taxonomy ) )
  332. return $term;
  333. else
  334. return 0;
  335. }
  336. }
  337. $term = trim( stripslashes( $term ) );
  338. if ( '' === $slug = sanitize_title($term) )
  339. return 0;
  340. // this function only processes registered CPT-onomies
  341. // if this is a normal taxonomy, then use the WordPress function
  342. if ( !empty($taxonomy) && !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  343. return term_exists( $term, $taxonomy, $parent );
  344. else if ( !empty($taxonomy) ) {
  345. // check for parent
  346. $parent = (int) $parent;
  347. if ( $parent > 0 )
  348. $parent = ' AND post_parent = ' . $parent;
  349. else
  350. $parent = NULL;
  351. // check for name first
  352. $result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->posts . " WHERE post_title = %s" . $parent . " AND post_type = %s AND post_status = 'publish'", $term, $taxonomy ) );
  353. // check for slug
  354. if ( empty( $result ) )
  355. $result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->posts . " WHERE post_name = %s" . $parent . " AND post_type = %s AND post_status = 'publish'", $term, $taxonomy ) );
  356. if ( !empty( $result ) && $cpt_onomies_manager->is_registered_cpt_onomy( $result->post_type ) )
  357. return $this->convert_object_to_cpt_onomy_term( $result );
  358. else
  359. return 0;
  360. }
  361. else {
  362. // check for parent
  363. $parent = (int) $parent;
  364. if ( $parent > 0 )
  365. $parent = ' AND post_parent = ' . $parent;
  366. else
  367. $parent = NULL;
  368. //check for name first
  369. $result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->posts . " WHERE post_title = %s" . $parent . " AND post_status = 'publish'", $term ) );
  370. // check for slug
  371. if ( empty( $result ) )
  372. $result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->posts . " WHERE post_name = %s" . $parent . " AND post_status = 'publish'", $term ) );
  373. if ( !empty( $result ) && $cpt_onomies_manager->is_registered_cpt_onomy( $result->post_type ) )
  374. return $this->convert_object_to_cpt_onomy_term( $result );
  375. else
  376. return 0;
  377. }
  378. return 0;
  379. }
  380. /**
  381. * This function mimics the WordPress function get_term_link()
  382. * because we cannot hook into the function without receiving errors
  383. * and returning an incorrect link due to the rewrite war between
  384. * custom post types and taxonomies AND because we create our own
  385. * rewrite rules.
  386. *
  387. * @since 1.0
  388. * @uses $wp_rewrite, $cpt_onomies_manager
  389. * @param object|int|string $term
  390. * @param string $taxonomy (optional if $term is object)
  391. * @return string|WP_Error HTML link to taxonomy term archive on success, WP_Error if term does not exist.
  392. */
  393. public function get_term_link( $term, $taxonomy ) {
  394. global $wp_rewrite, $cpt_onomies_manager;
  395. // this function only processes registered CPT-onomies
  396. // if this is a normal taxonomy, then use the WordPress function
  397. if ( !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  398. return get_term_link( $term, $taxonomy );
  399. if ( !is_object( $term ) ) {
  400. if ( is_int( $term ) )
  401. $term = $this->get_term( $term, $taxonomy );
  402. else
  403. $term = $this->get_term_by( 'slug', $term, $taxonomy );
  404. }
  405. if ( !is_object( $term ) )
  406. $term = new WP_Error( 'invalid_term', __( 'Empty Term', CPT_ONOMIES_TEXTDOMAIN ) );
  407. if ( is_wp_error( $term ) )
  408. return $term;
  409. $taxonomy = $term->taxonomy;
  410. $termlink = NULL;
  411. $slug = $term->slug;
  412. $t = get_taxonomy( $taxonomy );
  413. // link to CPT-onomy archive page
  414. if ( isset( $t->cpt_onomy_archive_slug ) && !empty( $t->cpt_onomy_archive_slug ) ) {
  415. $termlink = $t->cpt_onomy_archive_slug;
  416. if ( $t->hierarchical ) {
  417. $hierarchical_slugs = array();
  418. $ancestors = get_ancestors( $term->term_id, $taxonomy );
  419. foreach ( (array)$ancestors as $ancestor ) {
  420. $ancestor_term = $this->get_term( $ancestor, $taxonomy );
  421. $hierarchical_slugs[] = $ancestor_term->slug;
  422. }
  423. $hierarchical_slugs = array_reverse( $hierarchical_slugs );
  424. $hierarchical_slugs[] = $slug;
  425. // replace the variables ($post_type and $term)
  426. $slug = implode( '/', $hierarchical_slugs );
  427. }
  428. // replace the variables ($post_type and $term)
  429. $termlink = str_replace( array( '$post_type', '$term_slug', '$term_id' ), array( $taxonomy, $slug, $term->term_id ), $termlink );
  430. $termlink = home_url( user_trailingslashit( $termlink, 'category' ) );
  431. }
  432. // If no archive page, link to CPT post
  433. else
  434. $termlink = get_permalink( $term->term_id );
  435. // Back Compat filters.
  436. if ( 'post_tag' == $taxonomy )
  437. $termlink = apply_filters( 'tag_link', $termlink, $term->term_id );
  438. elseif ( 'category' == $taxonomy )
  439. $termlink = apply_filters( 'category_link', $termlink, $term->term_id );
  440. return apply_filters( 'term_link', $termlink, $term, $taxonomy );
  441. }
  442. /**
  443. * This function mimics the WordPress function get_edit_term_link()
  444. * because we cannot hook into the function without receiving errors.
  445. *
  446. * @since 1.0
  447. * @uses $cpt_onomies_manager
  448. * @param int $term_id Term ID
  449. * @param string $taxonomy Taxonomy
  450. * @param string $object_type The object type
  451. * @return string
  452. */
  453. public function get_edit_term_link( $term_id, $taxonomy, $object_type = '' ) {
  454. global $cpt_onomies_manager;
  455. // this function only processes registered CPT-onomies
  456. // if this is a normal taxonomy, then use the WordPress function
  457. if ( !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  458. return get_edit_term_link( $term_id, $taxonomy, $object_type );
  459. $post_type = get_post_type_object( $taxonomy );
  460. if ( !current_user_can( $post_type->cap->edit_posts ) )
  461. return;
  462. $term = $this->get_term( $term_id, $taxonomy );
  463. if ( !$term )
  464. return;
  465. $args = array(
  466. 'post' => $term->term_id,
  467. 'action' => 'edit'
  468. );
  469. if ( $object_type )
  470. $args['post_type'] = $object_type;
  471. $location = add_query_arg( $args, admin_url( 'post.php' ) );
  472. return apply_filters( 'get_edit_term_link', $location, $term_id, $taxonomy, $object_type );
  473. }
  474. /**
  475. * This function mimics the WordPress function previous_post_link()
  476. * because we cannot use that function properly.
  477. *
  478. * In the WordPress function, previous_post_link(), you are only allowed
  479. * to use 'category' for your taxonomy but this function adds a new parameter that
  480. * allows you to designate which CPT-onomy you would like to use.
  481. *
  482. * @since 1.0.2
  483. * @uses $cpt_onomies_manager
  484. * @param string $format Optional. Link anchor format.
  485. * @param string $link Optional. Link permalink format.
  486. * @param bool $in_same_cpt_onomy Optional. Whether link should be in a same CPT-onomy.
  487. * @param array|string $excluded_term_ids Optional. Array or comma-separated list of excluded term IDs.
  488. * @param string $cpt_onomy - name of the CPT-onomy for $in_same_cpt_onomy
  489. */
  490. function previous_post_link( $format='&laquo; %link', $link='%title', $in_same_cpt_onomy = false, $excluded_term_ids = '', $cpt_onomy = '' ) {
  491. global $cpt_onomies_manager;
  492. if ( empty( $format ) )
  493. $format = '&laquo; %link';
  494. if ( empty( $cpt_onomy ) || !$cpt_onomies_manager->is_registered_cpt_onomy( $cpt_onomy ) )
  495. previous_post_link( $format, $link, $in_same_cpt_onomy, $excluded_term_ids );
  496. else
  497. $this->adjacent_post_link( $format, $link, $in_same_cpt_onomy, $excluded_term_ids, true, $cpt_onomy );
  498. }
  499. /**
  500. * This function mimics the WordPress function next_post_link()
  501. * because we cannot use that function properly.
  502. *
  503. * In the WordPress function, next_post_link(), you are only allowed
  504. * to use 'category' for your taxonomy but this function adds a new parameter that
  505. * allows you to designate which CPT-onomy you would like to use.
  506. *
  507. * @since 1.0.2
  508. * @uses $cpt_onomies_manager
  509. * @param string $format Optional. Link anchor format.
  510. * @param string $link Optional. Link permalink format.
  511. * @param bool $in_same_cpt_onomy Optional. Whether link should be in a same CPT-onomy.
  512. * @param array|string $excluded_term_ids Optional. Array or comma-separated list of excluded term IDs.
  513. * @param string $cpt_onomy - name of the CPT-onomy for $in_same_cpt_onomy
  514. */
  515. function next_post_link( $format='%link &raquo;', $link='%title', $in_same_cpt_onomy = false, $excluded_term_ids = '', $cpt_onomy = '' ) {
  516. global $cpt_onomies_manager;
  517. if ( empty( $format ) )
  518. $format = '%link &raquo;';
  519. if ( empty( $cpt_onomy ) || !$cpt_onomies_manager->is_registered_cpt_onomy( $cpt_onomy ) )
  520. next_post_link( $format, $link, $in_same_cpt_onomy, $excluded_term_ids );
  521. else
  522. $this->adjacent_post_link( $format, $link, $in_same_cpt_onomy, $excluded_term_ids, false, $cpt_onomy );
  523. }
  524. /**
  525. * This function mimics the WordPress function adjacent_post_link()
  526. * because we cannot use that function properly.
  527. *
  528. * In the WordPress function, adjacent_post_link(), you are only allowed
  529. * to use 'category' for your taxonomy but this function adds a new parameter that
  530. * allows you to designate which CPT-onomy you would like to use.
  531. *
  532. * @since 1.0.2
  533. * @uses $cpt_onomies_manager
  534. * @param string $format Link anchor format.
  535. * @param string $link Link permalink format.
  536. * @param bool $in_same_cpt_onomy Optional. Whether link should be in a same CPT-onomy.
  537. * @param array|string $excluded_term_ids Optional. Array or comma-separated list of excluded term IDs.
  538. * @param bool $previous Optional, default is true. Whether to display link to previous or next post.
  539. * @param string $cpt_onomy - name of the CPT-onomy for $in_same_cpt_onomy
  540. */
  541. function adjacent_post_link( $format, $link, $in_same_cpt_onomy = false, $excluded_term_ids = '', $previous = true, $cpt_onomy = '' ) {
  542. global $cpt_onomies_manager;
  543. if ( empty( $cpt_onomy ) || !$cpt_onomies_manager->is_registered_cpt_onomy( $cpt_onomy ) )
  544. adjacent_post_link( $format, $link, $in_same_cpt_onomy, $excluded_term_ids, $previous );
  545. else {
  546. if ( $previous && is_attachment() )
  547. $post = & get_post($GLOBALS['post']->post_parent);
  548. else
  549. $post = $this->get_adjacent_post( $in_same_cpt_onomy, $excluded_term_ids, $previous, $cpt_onomy );
  550. if ( !$post )
  551. return;
  552. $title = $post->post_title;
  553. if ( empty($post->post_title) )
  554. $title = $previous ? __( 'Previous Post', CPT_ONOMIES_TEXTDOMAIN ) : __( 'Next Post', CPT_ONOMIES_TEXTDOMAIN );
  555. $title = apply_filters( 'the_title', $title, $post->ID );
  556. $date = mysql2date( get_option( 'date_format' ), $post->post_date );
  557. $rel = $previous ? 'prev' : 'next';
  558. $string = '<a href="'.get_permalink($post).'" rel="'.$rel.'">';
  559. $link = str_replace('%title', $title, $link);
  560. $link = str_replace('%date', $date, $link);
  561. $link = $string . $link . '</a>';
  562. $format = str_replace('%link', $link, $format);
  563. $adjacent = $previous ? 'previous' : 'next';
  564. echo apply_filters( "{$adjacent}_post_link", $format, $link );
  565. }
  566. }
  567. /**
  568. * This function mimics the WordPress function prev_post_rel_link()
  569. * because we cannot use that function properly.
  570. *
  571. * In the WordPress function, prev_post_rel_link(), you are only allowed
  572. * to use 'category' for your taxonomy but this function adds a new parameter that
  573. * allows you to designate which CPT-onomy you would like to use.
  574. *
  575. * @since 1.0.2
  576. * @uses $cpt_onomies_manager
  577. * @param string $title Optional. Link title format.
  578. * @param bool $in_same_cpt_onomy Optional. Whether link should be in a same CPT-onomy.
  579. * @param array|string $excluded_term_ids Optional. Array or comma-separated list of excluded term IDs.
  580. * @param string $cpt_onomy - name of the CPT-onomy for $in_same_cpt_onomy
  581. */
  582. function prev_post_rel_link( $title = '%title', $in_same_cpt_onomy = false, $excluded_term_ids = '', $cpt_onomy = '' ) {
  583. global $cpt_onomies_manager;
  584. if ( empty( $cpt_onomy ) || !$cpt_onomies_manager->is_registered_cpt_onomy( $cpt_onomy ) )
  585. prev_post_rel_link( $title, $in_same_cpt_onomy, $excluded_term_ids );
  586. echo $this->get_adjacent_post_rel_link( $title, $in_same_cpt_onomy, $excluded_term_ids, true, $cpt_onomy );
  587. }
  588. /**
  589. * This function mimics the WordPress function next_post_rel_link()
  590. * because we cannot use that function properly.
  591. *
  592. * In the WordPress function, next_post_rel_link(), you are only allowed
  593. * to use 'category' for your taxonomy but this function adds a new parameter that
  594. * allows you to designate which CPT-onomy you would like to use.
  595. *
  596. * @since 1.0.2
  597. * @uses $cpt_onomies_manager
  598. * @param string $title Optional. Link title format.
  599. * @param bool $in_same_cpt_onomy Optional. Whether link should be in a same CPT-onomy.
  600. * @param array|string $excluded_term_ids Optional. Array or comma-separated list of excluded term IDs.
  601. * @param string $cpt_onomy - name of the CPT-onomy for $in_same_cpt_onomy
  602. */
  603. function next_post_rel_link( $title = '%title', $in_same_cpt_onomy = false, $excluded_term_ids = '', $cpt_onomy = '' ) {
  604. global $cpt_onomies_manager;
  605. if ( empty( $cpt_onomy ) || !$cpt_onomies_manager->is_registered_cpt_onomy( $cpt_onomy ) )
  606. next_post_rel_link( $title, $in_same_cpt_onomy, $excluded_term_ids );
  607. else
  608. echo $this->get_adjacent_post_rel_link( $title, $in_same_cpt_onomy, $excluded_term_ids, false, $cpt_onomy );
  609. }
  610. /**
  611. * This function mimics the WordPress function get_adjacent_post_rel_link()
  612. * because we cannot use that function properly.
  613. *
  614. * In the WordPress function, get_adjacent_post_rel_link(), you are only allowed
  615. * to use 'category' for your taxonomy but this function adds a new parameter that
  616. * allows you to designate which CPT-onomy you would like to use.
  617. *
  618. * @since 1.0.2
  619. * @uses $cpt_onomies_manager
  620. * @param string $title Optional. Link title format.
  621. * @param bool $in_same_cpt_onomy Optional. Whether link should be in a same CPT-onomy.
  622. * @param array|string $excluded_term_ids Optional. Array or comma-separated list of excluded term IDs.
  623. * @param bool $previous Optional, default is true. Whether to display link to previous or next post.
  624. * @param string $cpt_onomy - name of the CPT-onomy for $in_same_cpt_onomy
  625. * @return string
  626. */
  627. function get_adjacent_post_rel_link( $title = '%title', $in_same_cpt_onomy = false, $excluded_term_ids = '', $previous = true, $cpt_onomy = '' ) {
  628. global $cpt_onomies_manager;
  629. if ( empty( $cpt_onomy ) || !$cpt_onomies_manager->is_registered_cpt_onomy( $cpt_onomy ) )
  630. return get_adjacent_post_rel_link( $title, $in_same_cpt_onomy, $excluded_term_ids, $previous );
  631. if ( $previous && is_attachment() && is_object( $GLOBALS['post'] ) )
  632. $post = & get_post($GLOBALS['post']->post_parent);
  633. else
  634. $post = $this->get_adjacent_post( $in_same_cpt_onomy, $excluded_term_ids, $previous, $cpt_onomy );
  635. if ( empty($post) )
  636. return;
  637. if ( empty($post->post_title) )
  638. $post->post_title = $previous ? __( 'Previous Post', CPT_ONOMIES_TEXTDOMAIN ) : __( 'Next Post', CPT_ONOMIES_TEXTDOMAIN );
  639. $date = mysql2date(get_option('date_format'), $post->post_date);
  640. $title = str_replace( '%title', $post->post_title, $title );
  641. $title = str_replace( '%date', $date, $title );
  642. $title = apply_filters( 'the_title', $title, $post->ID );
  643. $link = $previous ? "<link rel='prev' title='" : "<link rel='next' title='";
  644. $link .= esc_attr( $title );
  645. $link .= "' href='" . get_permalink($post) . "' />\n";
  646. $adjacent = $previous ? 'previous' : 'next';
  647. return apply_filters( "{$adjacent}_post_rel_link", $link );
  648. }
  649. /**
  650. * This function mimics the WordPress function get_adjacent_post()
  651. * because we cannot use that function properly.
  652. *
  653. * In the WordPress function, get_adjacent_post(), you are only allowed
  654. * to use 'category' for your taxonomy but this function adds a new parameter that
  655. * allows you to designate which CPT-onomy you would like to use.
  656. *
  657. * @since 1.0.2
  658. * @uses $post, $wpdb, $cpt_onomies_manager
  659. * @param bool $in_same_cpt_onomy Optional. Whether post should be in a same CPT-onomy.
  660. * @param array|string $excluded_term_ids Optional. Array or comma-separated list of excluded term IDs.
  661. * @param bool $previous Optional. Whether to retrieve previous post.
  662. * @param string $cpt_onomy - name of the CPT-onomy for $in_same_cpt_onomy
  663. * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
  664. */
  665. function get_adjacent_post( $in_same_cpt_onomy = false, $excluded_term_ids = '', $previous = true, $cpt_onomy = '' ) {
  666. global $post, $wpdb, $cpt_onomies_manager;
  667. if ( empty( $post ) )
  668. return null;
  669. if ( empty( $cpt_onomy ) || !$cpt_onomies_manager->is_registered_cpt_onomy( $cpt_onomy ) )
  670. return get_adjacent_post( $in_same_cpt_onomy, $excluded_term_ids, $previous );
  671. $current_post_date = $post->post_date;
  672. $join = '';
  673. $posts_in_ex_terms_sql = '';
  674. if ( $in_same_cpt_onomy || ! empty( $excluded_term_ids ) ) {
  675. $join = " INNER JOIN " . $wpdb->postmeta . " AS pm ON p.ID = pm.post_id AND pm.meta_key ='" . CPT_ONOMIES_POSTMETA_KEY . "' INNER JOIN " . $wpdb->posts . " AS p2 ON pm.meta_value = p2.ID AND p2.post_type = '" . $cpt_onomy . "'";
  676. if ( $in_same_cpt_onomy )
  677. $join .= ' AND pm.meta_value IN (' . implode( ',', wp_get_object_terms( $post->ID, $cpt_onomy, array( 'fields' => 'ids' ) ) ) . ')';
  678. if ( ! empty( $excluded_term_ids ) ) {
  679. if ( ! is_array( $excluded_term_ids ) ) {
  680. // back-compat, $excluded_term_ids used to be IDs separated by " and "
  681. if ( strpos( $excluded_term_ids, ' and ' ) !== false ) {
  682. _deprecated_argument( __FUNCTION__, '3.3', sprintf( __( 'Use commas instead of %s to separate excluded categories.', CPT_ONOMIES_TEXTDOMAIN ), "'and'" ) );
  683. $excluded_term_ids = explode( ' and ', $excluded_term_ids );
  684. } else {
  685. $excluded_term_ids = explode( ',', $excluded_term_ids );
  686. }
  687. }
  688. $excluded_term_ids = array_map( 'intval', $excluded_term_ids );
  689. if ( !empty( $excluded_term_ids ) ) {
  690. $posts_in_ex_terms_sql = " AND ( SELECT COUNT(*) FROM " . $wpdb->postmeta . " pm2 WHERE pm2.post_id = p.ID AND pm2.meta_key = '" . CPT_ONOMIES_POSTMETA_KEY . "' AND pm2.meta_value NOT IN (" . implode(',', $excluded_term_ids) . ") ) = ( SELECT COUNT(*) FROM " . $wpdb->postmeta . " pm2 WHERE pm2.post_id = p.ID AND pm.meta_key = '" . CPT_ONOMIES_POSTMETA_KEY . "' )";
  691. }
  692. }
  693. }
  694. $adjacent = $previous ? 'previous' : 'next';
  695. $op = $previous ? '<' : '>';
  696. $order = $previous ? 'DESC' : 'ASC';
  697. $join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_cpt_onomy, $excluded_term_ids );
  698. $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare("WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $posts_in_ex_terms_sql", $current_post_date, $post->post_type), $in_same_cpt_onomy, $excluded_term_ids );
  699. $sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" );
  700. $query = "SELECT p.* FROM $wpdb->posts AS p $join $where $sort";
  701. $query_key = 'adjacent_post_' . md5($query);
  702. $result = wp_cache_get($query_key, 'counts');
  703. if ( false !== $result )
  704. return $result;
  705. $result = $wpdb->get_row("SELECT p.* FROM $wpdb->posts AS p $join $where $sort");
  706. if ( null === $result )
  707. $result = '';
  708. wp_cache_set($query_key, $result, 'counts');
  709. return $result;
  710. }
  711. /**
  712. * This function mimics the WordPress function get_the_term_list()
  713. * because we cannot hook into the function because get_the_term_list()
  714. * uses get_term_link() which is also incompatible with CPT-onomies at this time.
  715. *
  716. * @since 1.0
  717. * @uses $cpt_onomies_manager
  718. * @param int $id Post ID.
  719. * @param string $taxonomy Taxonomy name.
  720. * @param string $before Optional. Before list.
  721. * @param string $sep Optional. Separate items using this.
  722. * @param string $after Optional. After list.
  723. * @return string
  724. */
  725. public function get_the_term_list( $id = 0, $taxonomy, $before = '', $sep = '', $after = '' ) {
  726. global $cpt_onomies_manager;
  727. // this function only processes registered CPT-onomies
  728. // if this is a normal taxonomy, then use the WordPress function
  729. if ( !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  730. return get_the_term_list( $id, $taxonomy, $before, $sep, $after );
  731. $terms = get_the_terms( $id, $taxonomy );
  732. if ( is_wp_error( $terms ) )
  733. return $terms;
  734. if ( empty( $terms ) )
  735. return false;
  736. foreach ( $terms as $term ) {
  737. $link = $this->get_term_link( $term, $taxonomy );
  738. if ( is_wp_error( $link ) )
  739. return $link;
  740. $term_links[] = '<a href="' . $link . '" rel="tag">' . $term->name . '</a>';
  741. }
  742. $term_links = apply_filters( "term_links-$taxonomy", $term_links );
  743. return $before . join( $sep, $term_links ) . $after;
  744. }
  745. /**
  746. * This function mimics the WordPress function the_terms()
  747. * because we cannot hook into the function without receiving errors.
  748. *
  749. * @since 1.0
  750. * @uses $cpt_onomies_manager
  751. * @param int $id Post ID.
  752. * @param string $taxonomy Taxonomy name.
  753. * @param string $before Optional. Before list.
  754. * @param string $sep Optional. Separate items using this.
  755. * @param string $after Optional. After list.
  756. * @return null|bool False on WordPress error. Returns null when displaying.
  757. */
  758. public function the_terms( $id = 0, $taxonomy, $before = '', $sep = ', ', $after = '' ) {
  759. global $cpt_onomies_manager;
  760. // this function only processes registered CPT-onomies
  761. // if this is a normal taxonomy, then use the WordPress function
  762. if ( !$cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  763. return the_terms( $id, $taxonomy, $before, $sep, $after );
  764. $term_list = $this->get_the_term_list( $id, $taxonomy, $before, $sep, $after );
  765. if ( is_wp_error( $term_list ) )
  766. return false;
  767. echo apply_filters( 'the_terms', $term_list, $taxonomy, $before, $sep, $after );
  768. }
  769. /**
  770. * This function hooks into WordPress get_terms() and allows the plugin
  771. * to change what terms are retrieved. This function is invoked in numerous places
  772. * and is called whenever the WordPress function get_terms() is used.
  773. *
  774. * This function is applied to the filter 'get_terms'.
  775. *
  776. * Do not call this function on its own, instead use the core WordPress function: get_terms().
  777. *
  778. * @since 1.0
  779. * @uses $cpt_onomies_manager, $current_screen, $post
  780. * @param array $terms - the terms created by WordPress get_terms() that we will now filter
  781. * @param string|array $taxonomies - the taxonomies we're pulling terms from
  782. * @param array $args - arguments used to customize which terms are returned (!! means its not supported... yet)
  783. 'orderby' Default is 'name'. Can be name, count, term_group, slug or nothing
  784. (will use term_id), Passing a custom value other than these will cause
  785. it to order based on the custom value.
  786. 'order' Default is ASC. Can use DESC.
  787. 'hide_empty' Default is true. Will not return empty terms, which means terms whose
  788. count is 0 according to the given taxonomy.
  789. 'exclude' Default is an empty array. An array, comma- or space-delimited string
  790. of term ids to exclude from the return array. If 'include' is non-empty,
  791. 'exclude' is ignored.
  792. !! 'exclude_tree' Default is an empty array. An array, comma- or space-delimited string
  793. of term ids to exclude from the return array, along with all of their
  794. descendant terms according to the primary taxonomy. If 'include' is non-empty,
  795. 'exclude_tree' is ignored.
  796. 'include' Default is an empty array. An array, comma- or space-delimited string of
  797. term ids to include in the return array.
  798. 'number' The maximum number of terms to return. Default is to return them all.
  799. 'offset' The number by which to offset the terms query. Default is 0.
  800. 'fields' Default is 'all', which returns an array of term objects. If 'fields' is
  801. 'ids' or 'names', returns an array of integers or strings, respectively.
  802. 'slug' Returns terms whose "slug" matches this value. Default is empty string.
  803. !! 'hierarchical' Default is true. Whether to include terms that have non-empty descendants (even if 'hide_empty' is set to true).
  804. 'search' Returned terms' names will contain the value of 'search', case-insensitive. Default is an empty string.
  805. !! 'name__like' Returned terms' names will begin with the value of 'name__like', case-insensitive. Default is empty string.
  806. 'pad_counts' Default is false. If set to true will include the quantity of a term's children in the quantity of each term's "count" object variable.
  807. !! 'get' If set to 'all' instead of its default empty string, returns terms regardless of ancestry or whether the terms are empty.
  808. !! 'child_of' When used should be set to the integer of a term ID. Its default is 0. If set to a non-zero value, all returned terms
  809. will be descendants of that term according to the given taxonomy. Hence 'child_of' is set to 0 if more than one taxonomy
  810. is passed in $taxonomies, because multiple taxonomies make term ancestry ambiguous.
  811. !! 'parent' When used should be set to the integer of a term ID. Its default is the empty string '', which has a different meaning
  812. from the integer 0. If set to an integer value, all returned terms will have as an immediate ancestor the term whose ID is
  813. specified by that integer according to the given taxonomy. The 'parent' argument is different from 'child_of' in that a
  814. term X is considered a 'parent' of term Y only if term X is the father of term Y, not its grandfather or great-grandfather, etc.
  815. * @return array - the terms after they have been filtered
  816. */
  817. public function get_terms( $terms, $taxonomies, $args ) {
  818. global $cpt_onomies_manager, $current_screen, $post;
  819. // if taxonomy name is string, convert to array
  820. if ( !is_array( $taxonomies ) )
  821. $taxonomies = array( $taxonomies );
  822. // this function only filters registered CPT-onomies
  823. $cpt_taxonomies = array();
  824. foreach( $taxonomies as $taxonomy ) {
  825. if ( $cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  826. $cpt_taxonomies[] = $taxonomy;
  827. }
  828. // this means there are no CPT-onomies so wrap things up
  829. if ( empty( $cpt_taxonomies ) )
  830. return $terms;
  831. // since these parameters are not included in get_terms(),
  832. // we have to make sure they're included in our filter
  833. $defaults = array( 'show_count' => false );
  834. $args = wp_parse_args( $args, $defaults );
  835. // Since 'fields' = 'count' will cause get_terms to 'return' before we can filter,
  836. // the adjust_get_terms_args() filter changes 'count' to 'ids' and adds a custom
  837. // count argument. This is included here as a backup.
  838. if ( isset( $args[ 'fields' ] ) && $args[ 'fields' ] == 'count' ) {
  839. $args[ 'fields' ] = 'ids';
  840. $args[ 'cpt_onomy_get_count' ] = true;
  841. }
  842. extract( $args, EXTR_SKIP );
  843. // fix arguments for get_posts vs. get_terms
  844. // wordpress supported orderby - 'count', 'name', 'slug', 'none', 'id' - (still need to add support for 'term_group')
  845. if ( strtolower( $orderby ) == 'none' || strtolower( $orderby ) == 'id' ) $orderby = 'id';
  846. else if ( !in_array( strtolower( $orderby ), array( 'count', 'slug', 'term_group' ) ) ) $orderby = 'title'; //Default is 'name'/'title'
  847. // wordpress supported order - 'asc' and 'desc' (default is asc)
  848. $order = ( isset( $order ) && ( in_array( strtolower( $order ), array( 'asc', 'desc' ) ) ) ) ? strtolower( $order ) : 'asc';
  849. // numberposts (default is -1)
  850. $numberposts = ( isset( $number ) && is_numeric( $number ) && ( $number > 0 ) ) ? $number : -1;
  851. // offset (default is 0)
  852. $offset = ( isset( $offset ) && is_numeric( $offset ) && ( $offset > 0 ) ) ? $offset : 0;
  853. // wordpress supported fields - 'all', 'ids', 'names' (default is all)
  854. if ( in_array( strtolower( $fields ), array( 'ids', 'names', 'id=>parent' ) ) ) $fields = strtolower( $fields );
  855. else $fields = 'all';
  856. // clear out any existing terms and start over
  857. // this is helpful if, somehow, some actual terms got assigned to the taxonomy
  858. if ( !empty( $terms ) && $fields != 'id=>parent' ) {
  859. $new_terms = array();
  860. foreach( $terms as $term ) {
  861. if ( !isset( $term->taxonomy ) || !in_array( $term->taxonomy, $cpt_taxonomies ) )
  862. $new_terms[] = $term;
  863. }
  864. $terms = $new_terms;
  865. }
  866. // get terms
  867. foreach( $cpt_taxonomies as $taxonomy ) {
  868. $cpt_posts = get_posts( array(
  869. 'get_cpt_onomy_terms' => true,
  870. 'suppress_filters' => true,
  871. 'post_type' => $taxonomy,
  872. 'post_status' => 'publish',
  873. 'orderby' => $orderby,
  874. 'order' => $order,
  875. 'numberposts' => ( in_array( $orderby, array( 'id', 'title' ) ) ) ? $numberposts : -1, // we'll need all posts for other parameters for later sorting
  876. 'exclude' => $exclude,
  877. 'include' => $include,
  878. 'name' => $slug,
  879. 's' => $search
  880. ));
  881. if ( !empty( $cpt_posts ) ) {
  882. // we don't want to show the current "term" if on the edit post screen in the admin
  883. $current = NULL;
  884. if ( is_admin() && $current_screen && $current_screen->base == 'post' && $current_screen->parent_base == 'edit' && $current_screen->post_type == $taxonomy && isset( $post->ID ) )
  885. $current = $post->ID;
  886. foreach ( $cpt_posts as $this_post ) {
  887. // dont show current "term"
  888. if ( empty( $current ) || ( !empty( $current ) && $current != $this_post->ID ) ) {
  889. $this_term = $this->convert_object_to_cpt_onomy_term( $this_post );
  890. if ( !$hide_empty || ( $hide_empty && $this_term->count > 0 ) ) {
  891. switch( $fields ) {
  892. case 'ids':
  893. $this_term = $this_term->term_id;
  894. break;
  895. case 'names':
  896. $this_term = $this_term->name;
  897. break;
  898. }
  899. // 'id=>parent' is a beast all its own
  900. if ( $fields == 'id=>parent' )
  901. $terms[ $this_term->term_id ] = $this_term->parent;
  902. else
  903. $terms[] = $this_term;
  904. }
  905. }
  906. }
  907. }
  908. }
  909. // they just want the count
  910. // this argument is defined in $this->adjust_get_terms_args()
  911. if ( isset( $cpt_onomy_get_count ) && $cpt_onomy_get_count )
  912. return count( $terms );
  913. // if true, we have to do manual sorting
  914. // if false, it's already taken care of
  915. $manual_sort = false;
  916. // this means we have a mixture of taxonomies and CPT-onomies
  917. if ( !empty( $cpt_taxonomies ) && ( count( $taxonomies ) > 1 || $taxonomies != $cpt_taxonomies ) ) $manual_sort = true;
  918. // we have to manual sort certain $orderby parameters because they do not work in get_posts()
  919. else if ( in_array( $orderby, array( 'count', 'slug', 'term_group' ) ) ) $manual_sort = true;
  920. // 'id=>parent' is a beast all its own
  921. if ( $manual_sort && $fields != 'id=>parent' ) {
  922. // sort orderby
  923. // if 'ids' or 'names', then we have a simpler sort
  924. if ( in_array( $fields, array( 'ids', 'names' ) ) )
  925. natcasesort( $terms );
  926. else {
  927. switch( $orderby ) {
  928. case 'id':
  929. usort( $terms, 'cpt_onomies_sort_cpt_onomy_term_by_term_id' );
  930. break;
  931. case 'name':
  932. case 'title':
  933. usort( $terms, 'cpt_onomies_sort_cpt_onomy_term_by_name' );
  934. break;
  935. case 'count':
  936. usort( $terms, 'cpt_onomies_sort_cpt_onomy_term_by_count' );
  937. break;
  938. case 'slug':
  939. usort( $terms, 'cpt_onomies_sort_cpt_onomy_term_by_slug' );
  940. break;
  941. case 'term_group':
  942. break;
  943. }
  944. }
  945. // sort order
  946. if ( strtolower( $order ) == 'desc' )
  947. $terms = array_reverse( $terms );
  948. }
  949. // offset
  950. if ( $offset > 0 )
  951. $terms = array_slice( $terms, $offset );
  952. // number of posts
  953. // dont limit when hierarchical
  954. if ( $numberposts > 0 )
  955. $terms = array_slice( $terms, 0, $numberposts );
  956. return $terms;
  957. }
  958. /**
  959. * This function mimics the WordPress function get_objects_in_term()
  960. * because we cannot use that function properly.
  961. *
  962. * @since 1.0.2
  963. * @uses $wpdb, $cpt_onomies_manager
  964. * @param int|array $term_ids Term id or array of term ids of terms that will be used
  965. * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names
  966. * @param array|string $args Change the order of the object_ids, either ASC or DESC
  967. * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success
  968. * the array can be empty meaning that there are no $object_ids found or it will return the $object_ids found.
  969. */
  970. function get_objects_in_term( $term_ids, $taxonomies, $args = array() ) {
  971. global $wpdb, $cpt_onomies_manager;
  972. if ( ! is_array( $term_ids ) )
  973. $term_ids = array( $term_ids );
  974. if ( ! is_array( $taxonomies ) )
  975. $taxonomies = array( $taxonomies );
  976. // this function only filters registered CPT-onomies
  977. $cpt_taxonomies = array();
  978. foreach( $taxonomies as $taxonomy ) {
  979. if ( $cpt_onomies_manager->is_registered_cpt_onomy( $taxonomy ) )
  980. $cpt_taxonomies[] = $taxonomy;
  981. }
  982. // this means there are no CPT-onomies so wrap things up
  983. if ( empty( $cpt_taxonomies ) )
  984. return get_objects_in_term( $term_ids, $taxonomies, $args );
  985. else
  986. $taxonomies = $cpt_taxonomies;
  987. $defaults = array( 'order' => 'ASC' );
  988. $args = wp_parse_args( $args, $defaults );
  989. extract( $args, EXTR_SKIP );
  990. $order = ( 'desc' == strtolower( $order ) ) ? 'DESC' : 'ASC';
  991. $term_ids = array_map('intval', $term_ids );
  992. $taxonomies = "'" . implode( "', '", $taxonomies ) . "'";
  993. $term_ids = "'" . implode( "', '", $term_ids ) . "'";
  994. $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT " . $wpdb->postmeta . ".post_id FROM " . $wpdb->postmeta . " INNER JOIN " . $wpdb->posts . " ON " . $wpdb->posts . ".ID = " . $wpdb->postmeta . ".meta_value AND " . $wpdb->posts . ".post_type IN (" . $taxonomies . ") WHERE " . $wpdb->postmeta . ".meta_key = %s AND " . $wpdb->postmeta . ".meta_value IN (" . $term_ids . ") ORDER BY " . $wpdb->postmeta . ".post_id " . $order, CPT_ONOMIES_POSTMETA_KEY ) );
  995. if ( ! $object_ids )
  996. return array();
  997. return $object_ids;
  998. }
  999. /**
  1000. * This function hooks into WordPress wp_get_object_terms() and allows the plugin
  1001. * to change what terms are retrieved for a particular object. This function is invoked
  1002. * in numerous places and is called whenever the WordPress function wp_get_object_terms() is used.
  1003. *
  1004. * Retrieves the terms associated with the given object(s), in the supplied taxonomies.
  1005. *
  1006. * This function is applied to the filter 'wp_get_object_terms'.
  1007. *
  1008. * Do not call this function on its own, instead use the core WordPress function: wp_get_object_terms().
  1009. *
  1010. * Version 1.1 added the ability to designate terms ids to 'exclude' in the $args array.
  1011. * Will only work if 'fields' is set to 'ids', 'all' or 'all_with_object_id'.
  1012. * 'exclude' - (array) Default is an empty array. An array, comma- or space-delimited string
  1013. * of term ids to exclude in the return array.
  1014. *
  1015. * @since 1.0
  1016. * @uses $wpdb, $cpt_onomies_manager
  1017. * @param array $terms - the terms created by WordPress wp_get_object_terms() that we will now filter
  1018. * @param int|array $object_ids The ID(s) of the object(s) to retrieve.
  1019. * @param string|array $taxonomies The taxonomies to retrieve terms from.
  1020. * @param array|string $args Change what is returned
  1021. * @ret…

Large files files are truncated, but you can click here to view the full file