BP_Docs_Component

The BuddyPress Docs BP Docs Component class.

Defined (1)

The class is defined in the following location(s).

/includes/component.php  
  1. class BP_Docs_Component extends BP_Component { 
  2. var $groups_integration; 
  3. var $submitted_data = array(); 
  4.  
  5. var $post_type_name; 
  6. var $associated_tax_name; 
  7. var $access_tax_name; 
  8.  
  9. var $slugtocheck = array(); 
  10. var $query; 
  11. var $includes_url; 
  12.  
  13. var $current_view; 
  14. var $slug_defined_in_wp_config = array(); 
  15.  
  16. /** 
  17. * Constructor 
  18. * @since 1.2 
  19. */ 
  20. function __construct() { 
  21. global $bp; 
  22.  
  23. parent::start( 
  24. 'bp_docs',  
  25. __( 'BuddyPress Docs', 'bp-docs' ),  
  26. BP_DOCS_INSTALL_PATH 
  27. ); 
  28.  
  29. $bp->active_components[$this->id] = '1'; 
  30.  
  31. $this->setup_hooks(); 
  32.  
  33. /** 
  34. * Sets up the hooks for the Component's custom methods 
  35. * @since 1.2 
  36. */ 
  37. function setup_hooks() { 
  38. require( BP_DOCS_INCLUDES_PATH . 'integration-users.php' ); 
  39. $this->users_integration = new BP_Docs_Users_Integration; 
  40.  
  41. if ( bp_is_active( 'groups' ) ) { 
  42. require( BP_DOCS_INCLUDES_PATH . 'integration-groups.php' ); 
  43. $this->groups_integration = new BP_Docs_Groups_Integration; 
  44.  
  45. if ( bp_is_active( 'activity' ) ) { 
  46. require( BP_DOCS_INCLUDES_PATH . 'activity.php' ); 
  47.  
  48. add_action( 'bp_actions', array( &$this, 'catch_page_load' ), 1 ); 
  49.  
  50. $this->attachments = new BP_Docs_Attachments(); 
  51. // add_action( 'wp', array( $this, 'setup_attachments' ), 1 ); 
  52.  
  53. // Get submitted form data out of the cookie 
  54. add_action( 'bp_actions', array( $this, 'submitted_form_data' ) ); 
  55.  
  56. /** 
  57. * Methods related to comment behavior 
  58. */ 
  59.  
  60. // Redirect to the correct place after a comment 
  61. add_action( 'comment_post_redirect', array( &$this, 'comment_post_redirect' ), 99, 2 ); 
  62.  
  63. // Doc comments are always from trusted members (for the moment), so approve them 
  64. add_action( 'pre_comment_approved', array( $this, 'approve_doc_comments' ), 999, 2 ); 
  65.  
  66. // Filter the location of the comments template to allow it to be included with 
  67. // the plugin 
  68. add_filter( 'comments_template', array( $this, 'comments_template' ) ); 
  69.  
  70. add_filter( 'post_type_link', array( &$this, 'filter_permalinks' ), 10, 4 ); 
  71.  
  72. // Keep comment notifications from being sent 
  73. add_filter( 'comment_post', array( $this, 'check_comment_type' ) ); 
  74.  
  75. // Force comments_open to obey Doc-specific settings. 
  76. add_filter( 'comments_open', array( $this, 'comments_open' ), 10, 2 ); 
  77.  
  78. // Add the Search filter markup 
  79. add_filter( 'bp_docs_filter_types', array( $this, 'filter_type' ) ); 
  80. add_filter( 'bp_docs_filter_sections', array( $this, 'filter_markup' ) ); 
  81.  
  82. // Determine whether the directory view is filtered by a keyword search. 
  83. add_filter( 'bp_docs_is_directory_view_filtered', array( $this, 'is_directory_view_filtered' ), 10, 2 ); 
  84.  
  85. /** 
  86. * MISC 
  87. */ 
  88.  
  89. add_filter( 'bp_core_get_directory_page_ids', array( $this, 'remove_bp_page' ) ); 
  90.  
  91. // Respect $activities_template->disable_blogforum_replies 
  92. add_filter( 'bp_activity_can_comment', array( $this, 'activity_can_comment' ) ); 
  93.  
  94. // Add body class 
  95. add_filter( 'bp_get_the_body_class', array( $this, 'body_class' ) ); 
  96.  
  97. // Global directory tags 
  98. add_filter( 'bp_docs_taxonomy_get_item_terms', array( $this, 'get_item_terms' ) ); 
  99.  
  100. add_action( 'bp_docs_init', array( $this, 'set_includes_url' ) ); 
  101. add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); 
  102. add_action( 'wp_print_styles', array( $this, 'enqueue_styles' ) ); 
  103.  
  104. // Set the "last directory viewed" cookie when viewing the main docs directory. 
  105. add_action( 'bp_actions', array( $this, 'set_directory_cookie' ) ); 
  106.  
  107. // Add the parent and child theme names to the body class when on a BP Docs page. 
  108. add_filter( 'body_class', array( $this, 'filter_body_class' ) ); 
  109.  
  110. /** 
  111. * Implementation of BP_Component::setup_globals() 
  112. * Creates globals required by BP_Component. 
  113. * Registers post_type and taxonomy names in component global. 
  114. * Sets up the 'slugstocheck', which are used when enqueuing styles and scripts. 
  115. * @since 1.2 
  116. * @see BP_Docs_Component::enqueue_scripts() 
  117. * @see BP_Docs_Component::enqueue_styles() 
  118. */ 
  119. function setup_globals( $args = array() ) { 
  120. global $bp_docs; 
  121.  
  122. // Set up the $globals array to be passed along to parent::setup_globals() 
  123. $globals = array( 
  124. 'slug' => bp_docs_get_docs_slug(),  
  125. 'root_slug' => isset( $bp->pages->{$this->id}->slug ) ? $bp->pages->{$this->id}->slug : bp_docs_get_docs_slug(),  
  126. 'has_directory' => false, // Set to false if not required 
  127. 'notification_callback' => 'bp_docs_format_notifications',  
  128. 'search_string' => __( 'Search Docs...', 'bp-docs' ),  
  129. ); 
  130.  
  131. // Let BP_Component::setup_globals() do its work. 
  132. parent::setup_globals( $globals ); 
  133.  
  134. // Stash tax and post type names in the $bp global for use in template tags 
  135. $this->post_type_name = $bp_docs->post_type_name; 
  136. $this->associated_item_tax_name = $bp_docs->associated_item_tax_name; 
  137. $this->access_tax_name = $bp_docs->access_tax_name; 
  138.  
  139. // This info is loaded here because it needs to happen after BP core globals are 
  140. // set up 
  141. $this->slugstocheck = bp_action_variables() ? bp_action_variables() : array(); 
  142. $this->slugstocheck[] = bp_current_component(); 
  143. $this->slugstocheck[] = bp_current_action(); 
  144.  
  145. $this->set_current_item_type(); 
  146. $this->set_current_view(); 
  147.  
  148. /** 
  149. * Sets up Docs menu under My Account toolbar 
  150. * @since 1.3 
  151. */ 
  152. public function setup_admin_bar( $wp_admin_nav = array() ) { 
  153. global $bp; 
  154.  
  155. $wp_admin_nav = array(); 
  156.  
  157. if ( is_user_logged_in() ) { 
  158.  
  159. $title = bp_docs_get_user_tab_name(); 
  160.  
  161. // Add the "My Account" sub menus 
  162. $wp_admin_nav[] = array( 
  163. 'parent' => $bp->my_account_menu_id,  
  164. 'id' => 'my-account-' . $this->id,  
  165. 'title' => $title,  
  166. 'href' => bp_docs_get_mydocs_link(),  
  167. ); 
  168.  
  169. $wp_admin_nav[] = array( 
  170. 'parent' => 'my-account-' . $this->id,  
  171. 'id' => 'my-account-' . $this->id . '-started',  
  172. 'title' => __( 'Started By Me', 'bp-docs' ),  
  173. 'href' => bp_docs_get_mydocs_started_link(),  
  174. ); 
  175.  
  176. $wp_admin_nav[] = array( 
  177. 'parent' => 'my-account-' . $this->id,  
  178. 'id' => 'my-account-' . $this->id . '-edited',  
  179. 'title' => __( 'Edited By Me', 'bp-docs' ),  
  180. 'href' => bp_docs_get_mydocs_edited_link(),  
  181. ); 
  182.  
  183. $wp_admin_nav[] = array( 
  184. 'parent' => 'my-account-' . $this->id,  
  185. 'id' => 'my-account-' . $this->id . '-create',  
  186. 'title' => __( 'Create New Doc', 'bp-docs' ),  
  187. 'href' => bp_docs_get_create_link(),  
  188. ); 
  189.  
  190.  
  191. parent::setup_admin_bar( $wp_admin_nav ); 
  192.  
  193. /** 
  194. * Get previously submitted form data out of the cookie, and stash. 
  195. * @since 1.8 
  196. */ 
  197. public function submitted_form_data() { 
  198. if ( isset( $_COOKIE['bp-docs-submit-data'] ) ) { 
  199. $this->submitted_data = json_decode( stripslashes( $_COOKIE['bp-docs-submit-data'] ) ); 
  200. setcookie( 'bp-docs-submit-data', '', time() - 24*60*60, '/' ); 
  201.  
  202. /** 
  203. * In Docs 1.2 through 1.2.2, there was an error in which Docs registered 
  204. * a bp-pages entry. This fixes the error 
  205. * @since 1.2.3 
  206. */ 
  207. function remove_bp_page( $pages ) { 
  208. if ( isset( $pages['bp_docs'] ) ) { 
  209. unset( $pages['bp_docs']); 
  210. bp_update_option( 'bp-pages', $pages ); 
  211.  
  212. return $pages; 
  213.  
  214. /** 
  215. * Gets the item type of the item you're looking at - e.g 'group', 'user'. 
  216. * @since 1.0-beta 
  217. * @return str $view The current item type 
  218. */ 
  219. function set_current_item_type() { 
  220. global $bp; 
  221.  
  222. $type = ''; 
  223.  
  224. if ( bp_is_user() ) { 
  225. $type = 'user'; 
  226.  
  227. $type = apply_filters( 'bp_docs_get_item_type', $type, $this ); 
  228.  
  229. $this->item_type = $type; 
  230.  
  231. /** 
  232. * Gets the current view, based on the page you're looking at. 
  233. * Filter 'bp_docs_get_current_view' to extend to different components. 
  234. * @since 1.0-beta 
  235. * @param str $item_type Defaults to the object's item type 
  236. * @return str $view The current view. Core values: edit, single, list, category 
  237. */ 
  238. function set_current_view( $item_type = false ) { 
  239. global $bp; 
  240.  
  241. $view = ''; 
  242.  
  243. if ( !$item_type ) 
  244. $item_type = $this->item_type; 
  245.  
  246. $view = apply_filters( 'bp_docs_get_current_view', $view, $item_type ); 
  247.  
  248. $this->current_view = $view; 
  249.  
  250. /** 
  251. * Creates component navigation (Member > Docs) 
  252. * @since 1.2 
  253. * @todo Make the 'Docs' label customizable by the admin 
  254. */ 
  255. function setup_nav( $main_nav = array(), $sub_nav = array() ) { 
  256.  
  257. $main_nav = array( 
  258. 'name' => bp_docs_get_user_tab_name(),  
  259.  
  260. // Disabled count for now. See https://github.com/boonebgorges/buddypress-docs/issues/261 
  261. //'name' => sprintf( __( 'Docs <span>%d</span>', 'bp-docs' ), bp_docs_get_doc_count( bp_displayed_user_id(), 'user' ) ),  
  262. 'slug' => bp_docs_get_docs_slug(),  
  263. 'position' => 80,  
  264. 'screen_function' => array( &$this, 'template_loader' ),  
  265. 'default_subnav_slug' => BP_DOCS_STARTED_SLUG 
  266. ); 
  267.  
  268. $parent_url = trailingslashit( bp_displayed_user_domain() . bp_docs_get_docs_slug() ); 
  269.  
  270. $mydocs_label = bp_is_my_profile() ? __( 'My Docs ', 'bp-docs' ) : sprintf( __( '%s’s Docs', 'bp-docs' ), bp_get_user_firstname( bp_get_displayed_user_fullname() ) ); 
  271.  
  272. $sub_nav[] = array( 
  273. 'name' => bp_is_my_profile() ? __( 'Started By Me', 'bp-docs' ) : sprintf( __( 'Started By %s', 'bp-docs' ), bp_get_user_firstname() ),  
  274. 'slug' => BP_DOCS_STARTED_SLUG,  
  275. 'parent_url' => $parent_url,  
  276. 'parent_slug' => bp_docs_get_docs_slug(),  
  277. 'screen_function' => array( &$this, 'template_loader' ),  
  278. 'position' => 10 
  279. ); 
  280.  
  281. $sub_nav[] = array( 
  282. 'name' => bp_is_my_profile() ? __( 'Edited By Me', 'bp-docs' ) : sprintf( __( 'Edited By %s', 'bp-docs' ), bp_get_user_firstname() ),  
  283. 'slug' => BP_DOCS_EDITED_SLUG,  
  284. 'parent_url' => $parent_url,  
  285. 'parent_slug' => bp_docs_get_docs_slug(),  
  286. 'screen_function' => array( &$this, 'template_loader' ),  
  287. 'position' => 20,  
  288. ); 
  289.  
  290. parent::setup_nav( $main_nav, $sub_nav ); 
  291.  
  292. /** 
  293. * Utility function for loading component template and hooking content 
  294. * @since 1.2 
  295. * @see self::setup_nav() 
  296. */ 
  297. function template_loader() { 
  298. add_action( 'bp_template_content', array( &$this, 'select_template' ) ); 
  299. bp_core_load_template( 'members/single/plugins' ); 
  300.  
  301. /** 
  302. * Utility function for selecting the correct Docs template to be loaded in the component 
  303. * At the moment, this only loads a single template. Logic could be 
  304. * put here in the future in case more than one template needs to be 
  305. * displayable on the component page 
  306. * @since 1.2 
  307. */ 
  308. function select_template() { 
  309. $template = 'docs-loop.php'; 
  310. include bp_docs_locate_template( apply_filters( 'bp_docs_select_template', $template ) ); 
  311.  
  312. /** 
  313. * Loads the Docs query. 
  314. * We do this in order to have some of the info about the current doc throughout the 
  315. * loading process 
  316. * @since 1.0-beta 
  317. * @deprecated No longer used since 1.2 
  318. */ 
  319. function do_query() { 
  320. _deprecated_function( __METHOD__, '1.2' ); 
  321.  
  322. /** 
  323. * Catches page loads, determines what to do, and sends users on their merry way 
  324. * @since 1.0-beta 
  325. * @todo This needs a ton of cleanup 
  326. */ 
  327. function catch_page_load() { 
  328. global $bp; 
  329.  
  330. if ( !empty( $_POST['doc-edit-submit'] ) ) { 
  331.  
  332. // Existing Docs have a more specific permission check. 
  333. $doc = bp_docs_get_current_doc(); 
  334. if ( $doc && ! current_user_can( 'bp_docs_edit', $doc->ID ) ) { 
  335. return; 
  336. } elseif ( ! $doc && ! current_user_can( 'bp_docs_create' ) ) { 
  337. return; 
  338.  
  339. check_admin_referer( 'bp_docs_save' ); 
  340.  
  341. $this_doc = new BP_Docs_Query; 
  342. $result = $this_doc->save(); 
  343.  
  344. bp_core_add_message( $result['message'], $result['message_type'] ); 
  345. bp_core_redirect( trailingslashit( $result['redirect_url'] ) ); 
  346.  
  347. if ( !empty( $_POST['docs-filter-submit'] ) ) { 
  348. $this->handle_filters(); 
  349.  
  350. // If this is the edit screen, ensure that the user can edit the 
  351. // doc before querying, and redirect if necessary 
  352. if ( bp_docs_is_doc_edit() ) { 
  353. if ( current_user_can( 'bp_docs_edit' ) ) { 
  354. $doc = bp_docs_get_current_doc(); 
  355.  
  356. // The user can edit, so we check for edit locks 
  357. // Because we're not using WP autosave at the moment, ensure that 
  358. // the lock interval always returns as in process 
  359. add_filter( 'wp_check_post_lock_window', create_function( false, 'return time();' ) ); 
  360.  
  361. if ( $doc ) { 
  362. $lock = bp_docs_check_post_lock( $doc->ID ); 
  363.  
  364. if ( $lock ) { 
  365. bp_core_add_message( sprintf( __( 'This doc is currently being edited by %s. To prevent overwrites, you cannot edit until that user has finished. Please try again in a few minutes.', 'bp-docs' ), bp_core_get_user_displayname( $lock ) ), 'error' ); 
  366.  
  367. // Redirect back to the non-edit view of this document 
  368. bp_core_redirect( bp_docs_get_doc_link( $doc->ID ) ); 
  369. bp_core_redirect( $group_permalink . $bp->bp_docs->slug . '/' . $doc_slug ); 
  370. } else { 
  371. if ( function_exists( 'bp_core_no_access' ) && !is_user_logged_in() ) { 
  372. bp_core_no_access(); 
  373.  
  374. // The user does not have edit permission. Redirect. 
  375. bp_core_add_message( __( 'You do not have permission to edit the doc.', 'bp-docs' ), 'error' ); 
  376.  
  377. // Redirect back to the non-edit view of this document 
  378. bp_core_redirect( bp_docs_get_doc_link( $doc->ID ) ); 
  379. die(); 
  380.  
  381. if ( bp_docs_is_doc_create() ) { 
  382. if ( ! current_user_can( 'bp_docs_create' ) ) { 
  383. // The user does not have edit permission. Redirect. 
  384. if ( function_exists( 'bp_core_no_access' ) && !is_user_logged_in() ) 
  385. bp_core_no_access(); 
  386.  
  387. bp_core_add_message( __( 'You do not have permission to create a Doc in this group.', 'bp-docs' ), 'error' ); 
  388.  
  389. $group_permalink = bp_get_group_permalink( $bp->groups->current_group ); 
  390.  
  391. // Redirect back to the Doc list view 
  392. bp_core_redirect( $group_permalink . $bp->bp_docs->slug . '/' ); 
  393. die(); 
  394.  
  395. if ( !empty( $bp->bp_docs->current_view ) && 'history' == $bp->bp_docs->current_view ) { 
  396. if ( ! current_user_can( 'bp_docs_view_history' ) ) { 
  397. // The user does not have edit permission. Redirect. 
  398. if ( function_exists( 'bp_core_no_access' ) && !is_user_logged_in() ) 
  399. bp_core_no_access(); 
  400.  
  401. bp_core_add_message( __( 'You do not have permission to view this Doc\'s history.', 'bp-docs' ), 'error' ); 
  402.  
  403. $doc = bp_docs_get_current_doc(); 
  404.  
  405. $redirect = bp_docs_get_doc_link( $doc->ID ); 
  406.  
  407. // Redirect back to the Doc list view 
  408. bp_core_redirect( $redirect ); 
  409. die(); 
  410.  
  411. // Cancel edit lock 
  412. if ( !empty( $_GET['bpd_action'] ) && $_GET['bpd_action'] == 'cancel_edit_lock' ) { 
  413. // Check the nonce 
  414. check_admin_referer( 'bp_docs_cancel_edit_lock' ); 
  415.  
  416. // Todo: make this part of the perms system 
  417. if ( is_super_admin() || bp_group_is_admin() ) { 
  418. $doc = bp_docs_get_current_doc(); 
  419.  
  420. // Todo: get this into a proper method as well, blech 
  421. delete_post_meta( $doc->ID, '_bp_docs_last_pinged' ); 
  422.  
  423. bp_core_add_message( __( 'Lock successfully removed', 'bp-docs' ) ); 
  424. bp_core_redirect( bp_docs_get_doc_link( $doc->ID ) ); 
  425. die(); 
  426.  
  427. // Cancel edit 
  428. // Have to have a catcher for this so the edit lock can be removed 
  429. if ( !empty( $_GET['bpd_action'] ) && $_GET['bpd_action'] == 'cancel_edit' ) { 
  430. $doc = bp_docs_get_current_doc(); 
  431.  
  432. // Todo: get this into a proper method as well, blech 
  433. delete_post_meta( $doc->ID, '_bp_docs_last_pinged' ); 
  434.  
  435. bp_core_redirect( bp_docs_get_doc_link( $doc->ID ) ); 
  436. die(); 
  437.  
  438. // Todo: get this into a proper method 
  439. if ( bp_docs_is_doc_read() && ! empty( $_GET['delete'] ) ) { 
  440.  
  441. check_admin_referer( 'bp_docs_delete' ); 
  442.  
  443. if ( current_user_can( 'bp_docs_manage' ) ) { 
  444. $force_delete = false; 
  445. if ( ! empty( $_GET['force_delete'] ) ) { 
  446. $force_delete = true; 
  447.  
  448. $delete_doc_id = get_queried_object_id(); 
  449.  
  450. if ( bp_docs_trash_doc( $delete_doc_id, $force_delete ) ) { 
  451. bp_core_add_message( __( 'Doc successfully deleted!', 'bp-docs' ) ); 
  452. } else { 
  453. bp_core_add_message( __( 'Could not delete doc.', 'bp-docs' ) ); 
  454. } else { 
  455. bp_core_add_message( __( 'You do not have permission to delete that doc.', 'bp-docs' ), 'error' ); 
  456.  
  457. // Send the user back to the most recently viewed directory if possible. 
  458. if ( isset( $_COOKIE[ 'bp-docs-last-docs-directory' ] ) && filter_var( $_COOKIE[ 'bp-docs-last-docs-directory' ], FILTER_VALIDATE_URL) ) { 
  459. $delete_redirect = $_COOKIE[ 'bp-docs-last-docs-directory' ]; 
  460. } else { 
  461. $delete_redirect = home_url( bp_docs_get_docs_slug() ); 
  462.  
  463. bp_core_redirect( $delete_redirect ); 
  464. die(); 
  465.  
  466. if ( bp_docs_is_doc_read() && ! empty( $_GET['untrash'] ) && ! empty( $_GET['doc_id'] ) ) { 
  467. check_admin_referer( 'bp_docs_untrash' ); 
  468.  
  469. $untrash_doc_id = absint( $_GET['doc_id'] ); 
  470.  
  471. if ( current_user_can( 'bp_docs_manage', $untrash_doc_id ) ) { 
  472. if ( bp_docs_untrash_doc( $untrash_doc_id ) ) { 
  473. bp_core_add_message( __( 'Doc successfully removed from Trash!', 'bp-docs' ) ); 
  474. } else { 
  475. bp_core_add_message( __( 'Could not remove Doc from Trash.', 'bp-docs' ) ); 
  476. } else { 
  477. bp_core_add_message( __( 'You do not have permission to remove that Doc from the Trash.', 'bp-docs' ), 'error' ); 
  478.  
  479. bp_core_redirect( bp_docs_get_doc_link( $untrash_doc_id ) ); 
  480. die(); 
  481.  
  482. if ( bp_docs_is_doc_read() && ! empty( $_GET[ BP_DOCS_UNLINK_FROM_GROUP_SLUG ] ) && ! empty( $_GET['doc_id'] ) && ! empty( $_GET['group_id'] ) ) { 
  483. check_admin_referer( 'bp_docs_unlink_from_group' ); 
  484.  
  485. $unlink_doc_id = absint( $_GET['doc_id'] ); 
  486. $unlink_group_id = absint( $_GET['group_id'] ); 
  487.  
  488. if ( current_user_can( 'bp_docs_dissociate_from_group', $unlink_group_id ) ) { 
  489. if ( bp_docs_unlink_from_group( $unlink_doc_id, $unlink_group_id ) ) { 
  490. bp_core_add_message( __( 'Doc successfully removed from the group', 'bp-docs' ) ); 
  491. } else { 
  492. bp_core_add_message( __( 'Could not remove Doc from the group.', 'bp-docs' ) ); 
  493. } else { 
  494. bp_core_add_message( __( 'You do not have permission to remove that Doc from this group.', 'bp-docs' ), 'error' ); 
  495. bp_core_redirect( bp_get_group_permalink( groups_get_group( array( 'group_id' => $unlink_group_id ) ) ) . $bp->bp_docs->slug . '/' ); 
  496. die(); 
  497.  
  498. /** 
  499. * METHODS RELATED TO DOC COMMENTS 
  500. */ 
  501.  
  502. /** 
  503. * Approve Doc comments as necessary. 
  504. * Docs handles its own comment permissions, so we override WP's value 
  505. * @since 1.3.3 
  506. * @param string $approved 
  507. * @param array $commentdata 
  508. * @return string $approved 
  509. */ 
  510. public function approve_doc_comments( $approved, $commentdata ) { 
  511. $post = get_post( $commentdata['comment_post_ID'] ); 
  512. if ( bp_docs_get_post_type_name() === $post->post_type ) { 
  513. if ( bp_docs_user_can( 'post_comments', bp_loggedin_user_id(), $post->ID ) ) { 
  514. $approved = 1; 
  515. } else { 
  516. $approved = 0; 
  517.  
  518. return $approved; 
  519.  
  520. /** 
  521. * Filters the comment_post_direct URL so that the user gets sent back to the true 
  522. * comment URL after posting 
  523. * @since 1.0-beta 
  524. * @param str $location The original location, created by WP 
  525. * @param obj $comment The new comment object 
  526. * @return str $location The correct location 
  527. */ 
  528. function comment_post_redirect( $location, $comment ) { 
  529. global $bp; 
  530.  
  531. // Check to see whether this is a BP Doc 
  532. $post = get_post( $comment->comment_post_ID ); 
  533.  
  534. if ( $bp->bp_docs->post_type_name != $post->post_type ) 
  535. return $location; 
  536.  
  537. $location = bp_docs_get_doc_link( $comment->comment_post_ID ) . '#comment-' . $comment->comment_ID; 
  538.  
  539. return $location; 
  540.  
  541.  
  542. /** 
  543. * Posts an activity item when a comment is posted to a doc 
  544. * @since 1.0-beta 
  545. * @param obj $comment_id The id of the comment that's just been saved. 
  546. * @return int $activity_id The id number of the activity created 
  547. */ 
  548. function post_comment_activity( $comment_id ) { 
  549. return bp_docs_post_comment_activity( $comment_id ); 
  550.  
  551. /** 
  552. * Filter the location of the comments.php template 
  553. * This function uses a little trick to make sure that the comments.php file can be 
  554. * overridden by child themes, yet still has a fallback in the plugin folder. 
  555. * If you find this annoying, I have provided a filter for your convenience. 
  556. * @since 1.0-beta 
  557. * @param str $path The path (STYLESHEETPATH . $file) from comments_template() 
  558. * @return str The path of the preferred template 
  559. */ 
  560. function comments_template( $path ) { 
  561. if ( ! bp_docs_is_existing_doc() ) 
  562. return $path; 
  563.  
  564. $original_path = $path; 
  565.  
  566. if ( ! $path = locate_template( 'docs/single/comments.php' ) ) { 
  567. $path = BP_DOCS_INSTALL_PATH . 'includes/templates/docs/single/comments.php'; 
  568.  
  569. return apply_filters( 'bp_docs_comment_template_path', $path, $original_path ); 
  570.  
  571. /** 
  572. * Prevents comment notification emails from being sent on BP Docs comments 
  573. * For the moment, I'm shutting off WP's native email notifications on BP Docs comments. 
  574. * They are better handled as part of the BP activity stream. This maneuver requires a 
  575. * trick: when a comment is posted on a BP Doc type post, I hijack the get_option() call 
  576. * for comments_notify and return 0 (rather than false, which would not stop the real 
  577. * get_option operation from running). 
  578. * @since 1.0-beta 
  579. * @param int $comment_id ID number of the new comment being posted 
  580. */ 
  581. function check_comment_type( $comment_id ) { 
  582. global $bp; 
  583.  
  584. $comment = get_comment( $comment_id ); 
  585. $post = get_post( $comment->comment_post_ID ); 
  586.  
  587. if ( $bp->bp_docs->post_type_name == $post->post_type ) { 
  588. add_filter( 'pre_option_comments_notify', create_function( false, 'return 0;' ) ); 
  589.  
  590. /** 
  591. * Force comments_open status to obey Doc-specific settings. 
  592. * @since 1.8.6 
  593. * @param bool $open Whether the current post is open for comments. 
  594. * @param int $post_id ID of the post. 
  595. * @return bool 
  596. */ 
  597. public function comments_open( $open, $post_id ) { 
  598. $post = get_post( $post_id ); 
  599. if ( ! ( $post instanceof WP_Post ) || bp_docs_get_post_type_name() !== $post->post_type ) { 
  600. return $open; 
  601.  
  602. return current_user_can( 'bp_docs_post_comments', $post_id ); 
  603.  
  604. /** 
  605. * Adds BP Docs options to activity filter dropdowns 
  606. * @since 1.0-beta 
  607. */ 
  608. function activity_filter_options() { 
  609. return bp_docs_activity_filter_options(); 
  610.  
  611. /** 
  612. * Posts an activity item on doc save 
  613. * @since 1.0-beta 
  614. * @param obj $query The query object created in BP_Docs_Query and passed to the 
  615. * bp_docs_doc_saved filter 
  616. * @return int $activity_id The id number of the activity created 
  617. */ 
  618. function post_activity( $query ) { 
  619. return bp_docs_post_activity( $query ); 
  620.  
  621. /** 
  622. * Delete activity associated with a Doc 
  623. * Run on transition_post_status, to catch deletes from all locations 
  624. * @since 1.3 
  625. * @param string $new_status 
  626. * @param string $old_status 
  627. * @param obj WP_Post object 
  628. */ 
  629. public function delete_doc_activity( $new_status, $old_status, $post ) { 
  630. return bp_docs_delete_doc_activity( $new_status, $old_status, $post ); 
  631.  
  632. /** 
  633. * MISCELLANEOUS 
  634. */ 
  635.  
  636. /** 
  637. * Display the proper permalink for Docs 
  638. * This function filters 'post_type_link', which in turn powers get_permalink() and related 
  639. * functions. 
  640. * BuddyPress Docs has a completely flat architecture for URLs, where 
  641. * parent slugs never appear in the URL (as they do in the case of WP 
  642. * pages). So we reconstruct the link completely. 
  643. * @since 1.1.8 
  644. * @param str $link The permalink 
  645. * @param obj $post The post object 
  646. * @param bool $leavename 
  647. * @param bool $sample See get_post_permalink() for an explanation of these two params 
  648. * @return str $link The filtered permalink 
  649. */ 
  650. function filter_permalinks( $link, $post, $leavename, $sample ) { 
  651. if ( bp_docs_get_post_type_name() == $post->post_type ) { 
  652. $link = trailingslashit( bp_docs_get_archive_link() . $post->post_name ); 
  653.  
  654. return html_entity_decode( $link ); 
  655.  
  656. /** 
  657. * Repsect disable_blogforum_replies 
  658. * BuddyPress allows you to disable activity commenting on items related to blog posts or 
  659. * to forums, content types that have their own reply/comment mechanisms. Since BuddyPress 
  660. * Docs are similar in this respect, they should respect this setting as well. 
  661. * In the future, I may add a separate toggle for this. I may also build a filter that 
  662. * redirects the Comment/Reply link so that it goes to the Doc's Comment section, or so that 
  663. * this setting reflects the individual Doc's can_comment settings. (For now, this would 
  664. * require too many additional queries.) 
  665. * This function filters bp_activity_can_comment, which was introduced in BP 1.5. It is 
  666. * therefore not backward compatible with BP < 1.5. 
  667. * @since 1.1.17 
  668. * @param bool $can_comment Whether the current user can comment. Comes from 
  669. * bp_activity_can_comment() 
  670. * @return bool $can_comment 
  671. */ 
  672. function activity_can_comment( $can_comment ) { 
  673. global $activities_template; 
  674.  
  675. if ( 'bp_doc_created' == bp_get_activity_action_name() || 
  676. 'bp_doc_edited' == bp_get_activity_action_name() || 
  677. 'bp_doc_comment' == bp_get_activity_action_name() 
  678. ) { 
  679. // Flip the 'disable' 
  680. $can_comment = !(bool)$activities_template->disable_blogforum_replies; 
  681.  
  682. return apply_filters( 'bp_docs_activity_can_comment', $can_comment ); 
  683.  
  684. /** 
  685. * Handles doc filters from a form post and translates to $_GET arguments before redirect 
  686. * @since 1.0-beta 
  687. */ 
  688. function handle_filters() { 
  689. $redirect_url = apply_filters( 'bp_docs_handle_filters', bp_docs_get_item_docs_link() ); 
  690.  
  691. bp_core_redirect( $redirect_url ); 
  692.  
  693. /** 
  694. * Sets the includes URL for use when loading scripts and styles 
  695. * @since 1.0-beta 
  696. */ 
  697. function set_includes_url() { 
  698. $this->includes_url = plugins_url() . '/' . BP_DOCS_PLUGIN_SLUG . '/includes/'; 
  699.  
  700. /** 
  701. * Add a bp-docs class to bp-docs pages 
  702. * @since 1.3 
  703. */ 
  704. function body_class( $classes ) { 
  705. if ( bp_docs_is_docs_component() ) { 
  706. $classes[] = 'bp-docs'; 
  707.  
  708. if ( bp_docs_is_doc_trashed() ) { 
  709. $classes[] = 'trashed-doc'; 
  710.  
  711. if ( wp_is_mobile() ) { 
  712. $classes[] = 'mobile'; 
  713.  
  714. if ( bp_docs_is_doc_edit() ) { 
  715. $classes[] = 'bp-docs-edit'; 
  716.  
  717. if ( bp_docs_is_doc_create() ) { 
  718. $classes[] = 'bp-docs-create'; 
  719.  
  720. return array_unique( $classes ); 
  721.  
  722. /** 
  723. * When on a global directory, get terms for the tag cloud 
  724. * @since 1.4 
  725. */ 
  726. public function get_item_terms( $terms ) { 
  727. global $wpdb, $bp; 
  728.  
  729. // Only on global directory and mygroups view 
  730. if ( ! bp_docs_is_global_directory() && ! bp_docs_is_mygroups_directory() ) { 
  731. return $terms; 
  732.  
  733. // Get list of docs the user has access to 
  734. $item_ids = bp_docs_get_doc_ids_accessible_to_current_user(); 
  735.  
  736. // Pass to wp_get_object_terms() 
  737. $terms = wp_get_object_terms( $item_ids, array( $bp->bp_docs->docs_tag_tax_name ) ); 
  738.  
  739. // Reformat 
  740. $terms_array = array(); 
  741. foreach ( $terms as $t ) { 
  742. $terms_array[ $t->slug ] = array( 
  743. 'count' => $t->count,  
  744. 'name' => $t->name,  
  745. ); 
  746.  
  747. unset( $item_ids, $terms ); 
  748.  
  749. return $terms_array; 
  750.  
  751. public static function filter_type( $types ) { 
  752. $types[] = array( 
  753. 'slug' => 'search',  
  754. 'title' => __( 'Search', 'bp-docs' ),  
  755. 'query_arg' => 's',  
  756. ); 
  757. return $types; 
  758.  
  759. public static function filter_markup() { 
  760. $has_search = ! empty( $_GET['s'] ); 
  761. ?> 
  762. <div id="docs-filter-section-search" class="docs-filter-section<?php if ( $has_search ) : ?> docs-filter-section-open<?php endif ?>"> 
  763. <form action="" method="get"> 
  764. <input name="s" value="<?php the_search_query() ?>"> 
  765. <input name="search_submit" type="submit" value="<?php _e( 'Search', 'bp-docs' ) ?>" /> 
  766. <?php do_action( 'bp_docs_directory_filter_search_form' ) ?> 
  767. </form> 
  768. </div> 
  769. <?php 
  770.  
  771. /** 
  772. * Determine whether the directory view is filtered by a keyword search. 
  773. * @since 1.9.0 
  774. * @param bool $is_filtered Is the current directory view filtered? 
  775. * @param array $exclude Array of filter types to ignore. 
  776. * @return bool $is_filtered 
  777. */ 
  778. public function is_directory_view_filtered( $is_filtered, $exclude ) { 
  779. // If this filter is excluded, stop now. 
  780. if ( in_array( 's', $exclude ) ) { 
  781. return $is_filtered; 
  782.  
  783. if ( ! empty( $_GET['s'] ) ) { 
  784. $is_filtered = true; 
  785. return $is_filtered; 
  786.  
  787. /** 
  788. * Loads JavaScript 
  789. * @since 1.0-beta 
  790. */ 
  791. function enqueue_scripts() { 
  792. wp_register_script( 'bp-docs-js', plugins_url( BP_DOCS_PLUGIN_SLUG . '/includes/js/bp-docs.js' ), array( 'jquery' ) ); 
  793.  
  794. // This is for edit/create scripts 
  795. if ( bp_docs_is_doc_edit() 
  796. || 
  797. bp_docs_is_doc_create() 
  798. || ( !empty( $this->query->current_view ) 
  799. && 
  800. ( 'edit' == $this->query->current_view || 'create' == $this->query->current_view ) 
  801. ) { 
  802. require_once( ABSPATH . '/wp-admin/includes/post.php' ); 
  803. wp_enqueue_script( 'common' ); 
  804. wp_enqueue_script( 'jquery-color' ); 
  805. wp_enqueue_script( 'editor' ); 
  806. wp_enqueue_script( 'utils' ); 
  807.  
  808. wp_register_script( 'bp-docs-idle-js', plugins_url( BP_DOCS_PLUGIN_SLUG . '/includes/js/idle.js' ), array( 'jquery', 'bp-docs-js' ) ); 
  809. wp_enqueue_script( 'bp-docs-idle-js' ); 
  810.  
  811. wp_register_script( 'jquery-colorbox', plugins_url( BP_DOCS_PLUGIN_SLUG . '/lib/js/colorbox/jquery.colorbox-min.js' ), array( 'jquery' ) ); 
  812. wp_enqueue_script( 'jquery-colorbox' ); 
  813. // Edit mode requires bp-docs-js to be dependent on TinyMCE, so we must 
  814. // reregister bp-docs-js with the correct dependencies 
  815. wp_deregister_script( 'bp-docs-js' ); 
  816. wp_register_script( 'bp-docs-js', plugins_url( BP_DOCS_PLUGIN_SLUG . '/includes/js/bp-docs.js' ), array( 'jquery', 'editor', 'heartbeat' ) ); 
  817.  
  818. wp_register_script( 'word-counter', site_url() . '/wp-admin/js/word-count.js', array( 'jquery' ) ); 
  819.  
  820. wp_enqueue_script( 'bp-docs-edit-validation', plugins_url( BP_DOCS_PLUGIN_SLUG . '/includes/js/edit-validation.js' ), array( 'jquery', 'bp-docs-js' ) ); 
  821.  
  822. // Only load our JS on the right sorts of pages. Generous to account for 
  823. // different item types 
  824. if ( in_array( bp_docs_get_docs_slug(), $this->slugstocheck ) || bp_docs_is_single_doc() || bp_docs_is_global_directory() || bp_docs_is_mygroups_directory() || bp_docs_is_doc_create() ) { 
  825. wp_enqueue_script( 'bp-docs-js' ); 
  826. wp_enqueue_script( 'comment-reply' ); 
  827.  
  828. $strings = array( 
  829. 'upload_title' => __( 'Upload File', 'bp-docs' ),  
  830. 'upload_button' => __( 'OK', 'bp-docs' ),  
  831. 'still_working' => __( 'Still working?', 'bp-docs' ),  
  832. 'and_x_more' => __( 'and %d more', 'bp-docs' ),  
  833. 'failed_submission' => ! empty( buddypress()->bp_docs->submitted_data ) ? 1 : 0,  
  834. ); 
  835.  
  836. if ( bp_docs_is_doc_edit() ) { 
  837. $strings['pulse'] = bp_docs_heartbeat_pulse(); 
  838. wp_localize_script( 'bp-docs-js', 'bp_docs', $strings ); 
  839.  
  840. do_action( 'bp_docs_enqueue_scripts' ); 
  841.  
  842. /** 
  843. * Loads styles 
  844. * @since 1.0-beta 
  845. */ 
  846. function enqueue_styles() { 
  847. global $bp; 
  848.  
  849. // Load the main CSS only on the proper pages 
  850. if ( in_array( bp_docs_get_docs_slug(), $this->slugstocheck ) || bp_docs_is_docs_component() ) { 
  851. wp_enqueue_style( 'bp-docs-css', $this->includes_url . 'css/screen.css' ); 
  852.  
  853. if ( bp_docs_is_doc_edit() || bp_docs_is_doc_create() ) { 
  854. wp_enqueue_style( 'bp-docs-edit-css', $this->includes_url . 'css/edit.css' ); 
  855. wp_enqueue_style( 'thickbox' ); 
  856.  
  857. /** 
  858. * Renew the last directory cookie if the user is viewing the main docs library. 
  859. * @since 1.9.0 
  860. */ 
  861. public function set_directory_cookie() { 
  862. if ( bp_docs_is_global_directory() ) { 
  863. @setcookie( 'bp-docs-last-docs-directory', home_url( $_SERVER['REQUEST_URI'] ), 0, '/' ); 
  864.  
  865. /** 
  866. * Add the parent and child theme names to the body class when on a BP Docs page. 
  867. * @since 1.9.0 
  868. * @param array $classes An array of body classes. 
  869. */ 
  870. public function filter_body_class( $classes ) { 
  871. if ( bp_docs_is_docs_component() ) { 
  872. $classes[] = 'bp-docs-body-theme-' . get_stylesheet(); 
  873. $classes[] = 'bp-docs-body-theme-' . get_template(); 
  874. return $classes;