PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/posts-to-posts/core/api.php

https://gitlab.com/blueprintmrk/bladencountyrecords
PHP | 377 lines | 195 code | 70 blank | 112 comment | 35 complexity | a35345fdd7d9b575796aee870cb111e9 MD5 | raw file
  1. <?php
  2. /**
  3. * Register a connection between two post types.
  4. *
  5. * This creates the appropriate meta box in the admin edit screen.
  6. *
  7. * Takes the following parameters, as an associative array:
  8. *
  9. * - 'name' - string A unique identifier for this connection type.
  10. *
  11. * - 'from' - string|array The first end of the connection.
  12. *
  13. * - 'from_query_vars' - array Additional query vars to pass to WP_Query. Default: none.
  14. *
  15. * - 'to' - string|array The second end of the connection.
  16. *
  17. * - 'to_query_vars' - array Additional query vars to pass to WP_Query. Default: none.
  18. *
  19. * - 'fields' - array( key => Title ) Metadata fields editable by the user. Default: none.
  20. *
  21. * - 'cardinality' - string How many connection can each post have: 'one-to-many', 'many-to-one' or 'many-to-many'. Default: 'many-to-many'
  22. *
  23. * - 'prevent_duplicates' - bool Whether to disallow duplicate connections between the same two posts. Default: true.
  24. *
  25. * - 'sortable' - bool|string Whether to allow connections to be ordered via drag-and-drop. Can be 'from', 'to', 'any' or false. Default: false.
  26. *
  27. * - 'title' - string|array The box's title. Default: 'Connected {$post_type}s'
  28. *
  29. * - 'from_labels' - array Additional labels for the admin box (optional)
  30. *
  31. * - 'to_labels' - array Additional labels for the admin box (optional)
  32. *
  33. * - 'reciprocal' - bool For indeterminate connections: True means all connections are displayed in a single box. False means 'from' connections are shown in one box and 'to' connections are shown in another box. Default: false.
  34. *
  35. * - 'admin_box' - bool|string|array Whether and where to show the admin connections box.
  36. *
  37. * - 'can_create_post' - bool Whether to allow post creation via the connection box. Default: true.
  38. *
  39. * @param array $args
  40. *
  41. * @return bool|object False on failure, P2P_Connection_Type instance on success.
  42. */
  43. function p2p_register_connection_type( $args ) {
  44. if ( !did_action('init') ) {
  45. trigger_error( "Connection types should not be registered before the 'init' hook." );
  46. }
  47. $argv = func_get_args();
  48. $args = _p2p_back_compat_args( $argv );
  49. if ( isset( $args['name'] ) ) {
  50. if ( strlen( $args['name'] ) > 32 ) {
  51. trigger_error( sprintf( "Connection name '%s' is longer than 32 characters.", $args['name'] ), E_USER_WARNING );
  52. return false;
  53. }
  54. } else {
  55. trigger_error( "Connection types without a 'name' parameter are deprecated.", E_USER_WARNING );
  56. }
  57. // Box args
  58. if ( isset( $args['admin_box'] ) ) {
  59. $metabox_args = _p2p_pluck( $args, 'admin_box' );
  60. if ( !is_array( $metabox_args ) )
  61. $metabox_args = array( 'show' => $metabox_args );
  62. } else {
  63. $metabox_args = array();
  64. }
  65. foreach ( array( 'fields', 'can_create_post' ) as $key ) {
  66. if ( isset( $args[ $key ] ) ) {
  67. $metabox_args[ $key ] = _p2p_pluck( $args, $key );
  68. }
  69. }
  70. // Column args
  71. if ( isset( $args['admin_column'] ) ) {
  72. $column_args = _p2p_pluck( $args, 'admin_column' );
  73. } else {
  74. $column_args = false;
  75. }
  76. $ctype = P2P_Connection_Type_Factory::register( $args );
  77. if ( is_admin() ) {
  78. P2P_Box_Factory::register( $ctype->name, $metabox_args );
  79. P2P_Column_Factory::register( $ctype->name, $column_args );
  80. }
  81. return $ctype;
  82. }
  83. /** @internal */
  84. function _p2p_back_compat_args( $argv ) {
  85. if ( count( $argv ) > 1 ) {
  86. $args = array();
  87. foreach ( array( 'from', 'to', 'reciprocal' ) as $i => $key ) {
  88. if ( isset( $argv[ $i ] ) )
  89. $args[ $key ] = $argv[ $i ];
  90. }
  91. } else {
  92. $args = $argv[0];
  93. }
  94. if ( isset( $args['id'] ) ) {
  95. $args['name'] = _p2p_pluck( $args, 'id' );
  96. }
  97. if ( isset( $args['show_ui'] ) ) {
  98. $args['admin_box'] = array(
  99. 'show' => _p2p_pluck( $args, 'show_ui' )
  100. );
  101. if ( isset( $args['context'] ) )
  102. $args['admin_box']['context'] = _p2p_pluck( $args, 'context' );
  103. }
  104. return $args;
  105. }
  106. /**
  107. * Get a connection type.
  108. *
  109. * @param string $p2p_type
  110. *
  111. * @return bool|object False if connection type not found, P2P_Connection_Type instance on success.
  112. */
  113. function p2p_type( $p2p_type ) {
  114. return P2P_Connection_Type_Factory::get_instance( $p2p_type );
  115. }
  116. /**
  117. * Check if a certain connection exists.
  118. *
  119. * @param string $p2p_type A valid connection type.
  120. * @param array $args Query args.
  121. *
  122. * @return bool
  123. */
  124. function p2p_connection_exists( $p2p_type, $args = array() ) {
  125. $args['fields'] = 'count';
  126. $r = p2p_get_connections( $p2p_type, $args );
  127. return (bool) $r;
  128. }
  129. /**
  130. * Retrieve connections.
  131. *
  132. * @param string $p2p_type A valid connection type.
  133. * @param array $args Query args:
  134. *
  135. * - 'direction': Can be 'from', 'to' or 'any'
  136. * - 'from': Object id. The first end of the connection. (optional)
  137. * - 'to': Object id. The second end of the connection. (optional)
  138. * - 'fields': Which field of the connection to return. Can be:
  139. * 'all', 'object_id', 'p2p_from', 'p2p_to', 'p2p_id' or 'count'
  140. *
  141. * @return array
  142. */
  143. function p2p_get_connections( $p2p_type, $args = array() ) {
  144. extract( wp_parse_args( $args, array(
  145. 'direction' => 'from',
  146. 'from' => 'any',
  147. 'to' => 'any',
  148. 'fields' => 'all',
  149. ) ), EXTR_SKIP );
  150. $r = array();
  151. foreach ( _p2p_expand_direction( $direction ) as $direction ) {
  152. $args = array( $from, $to );
  153. if ( 'to' == $direction ) {
  154. $args = array_reverse( $args );
  155. }
  156. if ( 'object_id' == $fields )
  157. $field = ( 'to' == $direction ) ? 'p2p_from' : 'p2p_to';
  158. else
  159. $field = $fields;
  160. $r = array_merge( $r, _p2p_get_connections( $p2p_type, array(
  161. 'from' => $args[0],
  162. 'to' => $args[1],
  163. 'fields' => $field
  164. ) ) );
  165. }
  166. if ( 'count' == $fields )
  167. return array_sum( $r );
  168. return $r;
  169. }
  170. /**
  171. * @internal
  172. */
  173. function _p2p_get_connections( $p2p_type, $args = array() ) {
  174. global $wpdb;
  175. extract( $args, EXTR_SKIP );
  176. $where = $wpdb->prepare( 'WHERE p2p_type = %s', $p2p_type );
  177. foreach ( array( 'from', 'to' ) as $key ) {
  178. if ( 'any' == $$key )
  179. continue;
  180. $where .= $wpdb->prepare( " AND p2p_$key = %d", $$key );
  181. }
  182. switch ( $fields ) {
  183. case 'p2p_id':
  184. case 'p2p_from':
  185. case 'p2p_to':
  186. $sql_field = $fields;
  187. break;
  188. case 'count':
  189. $sql_field = 'COUNT(*)';
  190. break;
  191. default:
  192. $sql_field = '*';
  193. }
  194. $query = "SELECT $sql_field FROM $wpdb->p2p $where";
  195. if ( '*' == $sql_field )
  196. return $wpdb->get_results( $query );
  197. else
  198. return $wpdb->get_col( $query );
  199. }
  200. /**
  201. * Retrieve a single connection.
  202. *
  203. * @param int $p2p_id The connection id.
  204. *
  205. * @return object
  206. */
  207. function p2p_get_connection( $p2p_id ) {
  208. global $wpdb;
  209. return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->p2p WHERE p2p_id = %d", $p2p_id ) );
  210. }
  211. /**
  212. * Create a connection.
  213. *
  214. * @param int $p2p_type A valid connection type.
  215. * @param array $args Connection information.
  216. *
  217. * @return bool|int False on failure, p2p_id on success.
  218. */
  219. function p2p_create_connection( $p2p_type, $args ) {
  220. global $wpdb;
  221. extract( wp_parse_args( $args, array(
  222. 'from' => false,
  223. 'to' => false,
  224. 'meta' => array()
  225. ) ), EXTR_SKIP );
  226. $from = absint( $from );
  227. $to = absint( $to );
  228. if ( !$from || !$to )
  229. return false;
  230. $wpdb->insert( $wpdb->p2p, array( 'p2p_type' => $p2p_type, 'p2p_from' => $from, 'p2p_to' => $to ) );
  231. $p2p_id = $wpdb->insert_id;
  232. foreach ( $meta as $key => $value )
  233. p2p_add_meta( $p2p_id, $key, $value );
  234. return $p2p_id;
  235. }
  236. /**
  237. * Delete one or more connections.
  238. *
  239. * @param int $p2p_type A valid connection type.
  240. * @param array $args Connection information.
  241. *
  242. * @return int Number of connections deleted
  243. */
  244. function p2p_delete_connections( $p2p_type, $args = array() ) {
  245. $args['fields'] = 'p2p_id';
  246. return p2p_delete_connection( p2p_get_connections( $p2p_type, $args ) );
  247. }
  248. /**
  249. * Delete connections using p2p_ids.
  250. *
  251. * @param int|array $p2p_id Connection ids
  252. *
  253. * @return int Number of connections deleted
  254. */
  255. function p2p_delete_connection( $p2p_id ) {
  256. global $wpdb;
  257. if ( empty( $p2p_id ) )
  258. return 0;
  259. $p2p_ids = array_map( 'absint', (array) $p2p_id );
  260. $where = "WHERE p2p_id IN (" . implode( ',', $p2p_ids ) . ")";
  261. $count = $wpdb->query( "DELETE FROM $wpdb->p2p $where" );
  262. $wpdb->query( "DELETE FROM $wpdb->p2pmeta $where" );
  263. return $count;
  264. }
  265. function p2p_get_meta( $p2p_id, $key = '', $single = false ) {
  266. return get_metadata( 'p2p', $p2p_id, $key, $single );
  267. }
  268. function p2p_update_meta( $p2p_id, $key, $value, $prev_value = '' ) {
  269. return update_metadata( 'p2p', $p2p_id, $key, $value, $prev_value );
  270. }
  271. function p2p_add_meta( $p2p_id, $key, $value, $unique = false ) {
  272. return add_metadata( 'p2p', $p2p_id, $key, $value, $unique );
  273. }
  274. function p2p_delete_meta( $p2p_id, $key, $value = '' ) {
  275. return delete_metadata( 'p2p', $p2p_id, $key, $value );
  276. }
  277. /**
  278. * List some posts.
  279. *
  280. * @param object|array A WP_Query instance, or a list of post objects
  281. * @param array $args (optional)
  282. */
  283. function p2p_list_posts( $posts, $args = array() ) {
  284. if ( is_object( $posts ) )
  285. $posts = $posts->posts;
  286. $args = wp_parse_args( $args, array(
  287. 'before_list' => '<ul>', 'after_list' => '</ul>',
  288. 'before_item' => '<li>', 'after_item' => '</li>',
  289. 'template' => false
  290. ) );
  291. extract( $args, EXTR_SKIP );
  292. if ( empty( $posts ) )
  293. return;
  294. echo $before_list;
  295. foreach ( $posts as $post ) {
  296. $GLOBALS['post'] = $post;
  297. setup_postdata( $post );
  298. echo $before_item;
  299. if ( $template )
  300. locate_template( $template, true, false );
  301. else
  302. echo html( 'a', array( 'href' => get_permalink( $post->ID ) ), get_the_title( $post->ID ) );
  303. echo $after_item;
  304. }
  305. echo $after_list;
  306. wp_reset_postdata();
  307. }