/** * Ajax handler to create dummy doc on creation * * @since 1.4 */ function bp_docs_create_dummy_doc() { add_filter('wp_insert_post_empty_content', '__return_false'); $doc_id = wp_insert_post(array('post_type' => bp_docs_get_post_type_name(), 'post_status' => 'auto-draft')); remove_filter('wp_insert_post_empty_content', '__return_false'); wp_send_json_success(array('doc_id' => $doc_id)); }
/** * Callback function for replacing bracketed links with the proper links * * If a page is found, a link to the page is produced. Otherwise a link to the create page * is produced, with the create_title flag. * * @since 1.2 * * @param array $match A single match passed from preg_replace_callback() * @return str A formatted link */ function process_bracket_content($match) { global $bp, $wpdb; // Check for a pipe if ($pipe_pos = strpos($match[1], '|')) { // If one is found, then the link text will be different from // the page name $link_text = substr($match[1], $pipe_pos + 1); $link_page = substr($match[1], 0, $pipe_pos); } else { // If no pipe is found, set the link text and link page the same $link_text = $link_page = $match[1]; } // Look for a page with this title. WP_Query does not allow this for some reason $docs = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE post_title = %s AND post_type = %s {$in_clause}", $link_page, bp_docs_get_post_type_name())); // If none were found, do the same query with page slugs if (empty($docs)) { $docs = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE post_name = %s AND post_type = %s {$in_clause}", sanitize_title_with_dashes($link_page), bp_docs_get_post_type_name())); } // Filter the docs. This will be used to exclude docs that do not belong to a group $docs = apply_filters('bp_docs_bracket_matches', $docs); if (!empty($docs)) { // If we have a result, create a link to that page // There might be more than one result. I guess we take the first one $doc = $docs[0]; $permalink = get_permalink($doc); $class = 'existing-doc'; } else { // If no result is found, create a link to the edit page $permalink = add_query_arg('create_title', urlencode($link_page), bp_docs_get_create_link()); $class = 'nonexistent-doc'; } return apply_filters('bp_docs_bracket_link', '<a href="' . $permalink . '" class="' . $class . '">' . $link_text . '</a>'); }
/** * Registers the post taxonomies with the bp_docs post type * * @since 1.0-beta * * @param array The $bp_docs_post_type_args array created in BP_Docs::register_post_type() * @return array $args The modified parameters */ function register_with_post_type() { $this->taxonomies = array($this->docs_tag_tax_name); foreach ($this->taxonomies as $tax) { register_taxonomy_for_object_type($tax, bp_docs_get_post_type_name()); } }
/** * Possibly intercept the template being loaded * * Listens to the 'template_include' filter and waits for a BP Docs post_type * to appear. When one is found, we look to see whether the current theme provides * its own version of the template; otherwise we fall back on the template shipped * with BuddyPress Docs. * * @since 1.2 * * @param string $template * * @return string The path to the template file that is being used */ function bp_docs_template_include($template = '') { if (bp_docs_is_single_doc() && ($new_template = bp_docs_locate_template('single-bp_doc.php'))) { } elseif (bp_docs_is_doc_create() && ($new_template = bp_docs_locate_template('single-bp_doc.php'))) { } elseif (is_post_type_archive(bp_docs_get_post_type_name()) && ($new_template = bp_docs_locate_template('archive-bp_doc.php'))) { } // Custom template file exists $template = !empty($new_template) ? $new_template : $template; return apply_filters('bp_docs_template_include', $template); }
/** * Callback function for replacing bracketed links with the proper links * * If a page is found, a link to the page is produced. Otherwise a link to the create page * is produced, with the create_title flag. * * @package BuddyPress Docs * @since 1.2 * * @param array $match A single match passed from preg_replace_callback() * @return str A formatted link */ function process_bracket_content($match) { global $bp, $wpdb; // Check for a pipe if ($pipe_pos = strpos($match[1], '|')) { // If one is found, then the link text will be different from // the page name $link_text = substr($match[1], $pipe_pos + 1); $link_page = substr($match[1], 0, $pipe_pos); } else { // If no pipe is found, set the link text and link page the same $link_text = $link_page = $match[1]; } // Exclude docs from other groups. Todo: move this out // Query for all the current group's docs if (isset($bp->groups->current_group->id)) { $query_args = array('tax_query' => array(array('taxonomy' => $bp->bp_docs->associated_item_tax_name, 'terms' => array($bp->groups->current_group->id), 'field' => 'name', 'operator' => 'IN', 'include_children' => false)), 'post_type' => $bp->bp_docs->post_type_name, 'showposts' => '-1'); } $this_group_docs = new WP_Query($query_args); $this_group_doc_ids = array(); foreach ($this_group_docs->posts as $gpost) { $this_group_doc_ids[] = $gpost->ID; } if (!empty($this_group_doc_ids)) { $in_clause = " AND {$wpdb->posts}.ID IN (" . implode(',', $this_group_doc_ids) . ")"; } else { $in_clause = ''; } // Look for a page with this title. WP_Query does not allow this for some reason $docs = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE post_title = %s AND post_type = %s {$in_clause}", $link_page, bp_docs_get_post_type_name())); // If none were found, do the same query with page slugs if (empty($docs)) { $docs = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE post_name = %s AND post_type = %s {$in_clause}", sanitize_title_with_dashes($link_page), bp_docs_get_post_type_name())); } // Filter the docs. This will be used to exclude docs that do not belong to a group $docs = apply_filters('bp_docs_bracket_matches', $docs); if (!empty($docs)) { // If we have a result, create a link to that page // There might be more than one result. I guess we take the first one $doc = $docs[0]; $permalink = get_permalink($doc); $class = 'existing-doc'; } else { // If no result is found, create a link to the edit page $permalink = add_query_arg('create_title', urlencode($link_page), bp_docs_get_item_docs_link() . BP_DOCS_CREATE_SLUG); $class = 'nonexistent-doc'; } return apply_filters('bp_docs_bracket_link', '<a href="' . $permalink . '" class="' . $class . '">' . $link_text . '</a>'); }
/** * Possibly intercept the template being loaded * * This function does two different things, depending on whether you're using BP * 1.7's theme compatibility feature. * - If so, the function runs the 'bp_setup_theme_compat' hook, which tells BP * to run the theme compat layer * - If not, the function checks to see which page you intend to be looking at * and loads the correct top-level bp-docs template * * The theme compatibility feature kicks in automatically for users running BP * 1.7+. If you are running 1.7+, but you do not want theme compat running for * a given Docs template type (archive, single, create), you can filter * 'bp_docs_do_theme_compat' and return false. This should only be done in the * case of legacy templates; if you're customizing new top-level templates for * Docs, you may put a file called plugin-buddypress-docs.php into the root of * your theme. * * @since 1.2 * * @param string $template * * @return string The path to the template file that is being used */ function bp_docs_template_include($template = '') { if (!bp_docs_is_docs_component()) { return $template; } $do_theme_compat = class_exists('BP_Theme_Compat') && apply_filters('bp_docs_do_theme_compat', true, $template); if ($do_theme_compat) { do_action('bp_setup_theme_compat'); } else { if (bp_docs_is_single_doc() && ($new_template = bp_docs_locate_template('single-bp_doc.php'))) { } elseif (bp_docs_is_doc_create() && ($new_template = bp_docs_locate_template('single-bp_doc.php'))) { } elseif (is_post_type_archive(bp_docs_get_post_type_name()) && ($new_template = bp_docs_locate_template('archive-bp_doc.php'))) { } $template = !empty($new_template) ? $new_template : $template; } return apply_filters('bp_docs_template_include', $template); }
/** * Gets the list of terms used by a user's docs * * At the moment, this method (and the next one) assumes that you want the terms of the * displayed user. At some point, that should be abstracted a bit. * * @package BuddyPress_Docs * @subpackage Users * @since 1.2 * * @return array $terms */ function get_user_terms($terms = array()) { global $wpdb; if (!bp_is_user()) { return $terms; } $query_args = array('post_type' => bp_docs_get_post_type_name(), 'update_meta_cache' => false, 'update_term_cache' => true, 'showposts' => '-1', 'posts_per_page' => '-1'); if (bp_docs_is_edited_by()) { $query_args['post__in'] = BP_Docs_Query::get_edited_by_post_ids_for_user(bp_displayed_user_id()); $query_args['post_status'] = array('publish'); } else { if (bp_docs_is_started_by()) { $query_args['author'] = bp_displayed_user_id(); $query_args['post_status'] = array('publish', 'trash'); } else { // Just in case $query_args['post__in'] = array(0); } } $user_doc_query = new WP_Query($query_args); $terms = array(); foreach ($user_doc_query->posts as $p) { $p_terms = wp_get_post_terms($p->ID, buddypress()->bp_docs->docs_tag_tax_name); foreach ($p_terms as $p_term) { if (!isset($terms[$p_term->slug])) { $terms[$p_term->slug] = array('name' => $p_term->name, 'posts' => array()); } if (!in_array($p->ID, $terms[$p_term->slug]['posts'])) { $terms[$p_term->slug]['posts'][] = $p->ID; } } } foreach ($terms as &$t) { $t['count'] = count($t['posts']); } if (empty($terms)) { $terms = array(); } return apply_filters('bp_docs_taxonomy_get_user_terms', $terms); }
/** * Display the proper permalink for Docs * * This function filters 'post_type_link', which in turn powers get_permalink() and related * functions. * * BuddyPress Docs has a completely flat architecture for URLs, where * parent slugs never appear in the URL (as they do in the case of WP * pages). So we reconstruct the link completely. * * @package BuddyPress Docs * @since 1.1.8 * * @param str $link The permalink * @param obj $post The post object * @param bool $leavename * @param bool $sample See get_post_permalink() for an explanation of these two params * @return str $link The filtered permalink */ function filter_permalinks($link, $post, $leavename, $sample) { if (bp_docs_get_post_type_name() == $post->post_type) { $link = trailingslashit(bp_docs_get_archive_link() . $post->post_name); } return html_entity_decode($link); }
/** * */ public static function get_edited_by_post_ids_for_user($editor_ids) { $editor_ids = wp_parse_id_list($editor_ids); $post_ids = array(); foreach ($editor_ids as $editor_id) { // @todo - Not sure how this will scale $posts = get_posts(array('author' => $editor_id, 'post_status' => array('inherit', 'publish'), 'post_type' => array('revision', bp_docs_get_post_type_name()), 'posts_per_page' => -1, 'update_post_meta_cache' => false, 'update_post_term_cache' => false)); $this_author_post_ids = array(); foreach ($posts as $post) { if ('revision' === $post->post_type) { $this_author_post_ids[] = $post->post_parent; } else { $this_author_post_ids[] = $post->ID; } } $post_ids = array_merge($post_ids, $this_author_post_ids); } // If the list is empty (the users haven't edited any Docs yet) // force 0 so that no items are shown if (empty($post_ids)) { $post_ids = array(0); } // @todo Might be faster to let the dupes through and let MySQL optimize return array_unique($post_ids); }
/** * Load up the doc to check against for meta cap mapping * * @since 1.2 * * @param array $args The $args argument passed by the map_meta_cap filter. May be empty * @return obj $doc */ function bp_docs_get_doc_for_caps($args = array()) { global $post; $doc_id = 0; $doc = NULL; if (isset($args[0])) { $doc_id = $args[0]; $doc = get_post($doc_id); } else { if (isset($post->ID)) { $doc = $post; } } if (!is_a($doc, 'WP_Post') || bp_docs_get_post_type_name() !== $doc->post_type) { $doc = null; } return apply_filters('bp_docs_get_doc_for_caps', $doc, $args); }
/** * Delete activity associated with a Doc * * Run on transition_post_status, to catch deletes from all locations * * @since 1.3 * * @param string $new_status * @param string $old_status * @param obj WP_Post object */ function bp_docs_delete_doc_activity($new_status, $old_status, $post) { if (!bp_is_active('activity')) { return; } if (bp_docs_get_post_type_name() != $post->post_type) { return; } if ('trash' != $new_status) { return; } $activities = bp_activity_get(array('filter' => array('secondary_id' => $post->ID, 'component' => 'docs'))); foreach ((array) $activities['activities'] as $activity) { bp_activity_delete(array('id' => $activity->id)); } }
/** * Display the proper permalink for Docs * * This function filters 'post_type_link', which in turn powers get_permalink() and related * functions. * * As of 1.2, the only role of this function is to ensure that child * Doc permalinks are returned correctly (without the parent slug) * * @package BuddyPress Docs * @since 1.1.8 * * @param str $link The permalink * @param obj $post The post object * @param bool $leavename * @param bool $sample See get_post_permalink() for an explanation of these two params * @return str $link The filtered permalink */ function filter_permalinks($link, $post, $leavename, $sample) { if (bp_docs_get_post_type_name() == $post->post_type && !empty($post->post_parent)) { $link = $post->guid; } return html_entity_decode($link); }
/** * Fetch a list of Doc IDs that are forbidden for the user * * @since 1.2.8 */ public function get_doc_ids() { remove_action('pre_get_posts', 'bp_docs_general_access_protection'); $tax_query = $this->get_tax_query(); foreach ($tax_query as &$tq) { $tq['operator'] = "NOT IN"; } $forbidden_fruit = get_posts(array('post_type' => bp_docs_get_post_type_name(), 'posts_per_page' => -1, 'nopaging' => true, 'tax_query' => $tax_query, 'update_post_term_cache' => false, 'update_post_meta_cache' => false, 'no_found_rows' => 1)); add_action('pre_get_posts', 'bp_docs_general_access_protection'); return wp_list_pluck($forbidden_fruit, 'ID'); }
/** * Is this the My Groups directory? * * @since 1.5 * @return bool */ function bp_docs_is_mygroups_directory() { $is_mygroups_directory = false; if (is_post_type_archive(bp_docs_get_post_type_name()) && get_query_var(BP_DOCS_MY_GROUPS_SLUG) && !get_query_var(BP_DOCS_CREATE_SLUG)) { $is_mygroups_directory = true; } return apply_filters('bp_docs_is_mygroups_directory', $is_mygroups_directory); }
/** * Give users the 'edit_post' and 'upload_files' cap, when appropriate * * @since 1.4 * * @param array $caps The mapped caps * @param string $cap The cap being mapped * @param int $user_id The user id in question * @param $args * @return array $caps */ public static function map_meta_cap($caps, $cap, $user_id, $args) { if ('upload_files' !== $cap && 'edit_post' !== $cap) { return $caps; } $maybe_user = new WP_User($user_id); if (!is_a($maybe_user, 'WP_User') || empty($maybe_user->ID)) { return $caps; } $is_doc = false; // DOING_AJAX is not set yet, so we cheat $is_ajax = isset($_SERVER['REQUEST_METHOD']) && 'POST' === $_SERVER['REQUEST_METHOD'] && 'async-upload.php' === substr($_SERVER['REQUEST_URI'], strrpos($_SERVER['REQUEST_URI'], '/') + 1); if ($is_ajax) { // WordPress sends the 'media-form' nonce, which we use // as an initial screen $nonce = isset($_REQUEST['_wpnonce']) ? stripslashes($_REQUEST['_wpnonce']) : ''; $post_id = isset($_REQUEST['post_id']) ? intval($_REQUEST['post_id']) : ''; if (wp_verify_nonce($nonce, 'media-form') && $post_id) { $post = get_post($post_id); // The dummy Doc created during the Create // process should pass this test, in addition to // existing Docs $is_doc = isset($post->post_type) && bp_docs_get_post_type_name() === $post->post_type; } } else { $is_doc = bp_docs_is_existing_doc() || bp_docs_is_doc_create(); } if ($is_doc) { $caps = array('exist'); // Since we've already done the permissions check, // we can filter future current_user_can() checks on // this pageload add_filter('map_meta_cap', array(__CLASS__, 'map_meta_cap_supp'), 10, 4); } return $caps; }
/** * Handles stuff that needs to be done at 'parse_query' * * - Ensures that no post is loaded on the creation screen * - Ensures that an archive template is loaded in /docs/my-groups/ */ function parse_query($posts_query) { // Bail if $posts_query is not the main loop if (!$posts_query->is_main_query()) { return; } // Bail if filters are suppressed on this query if (true == $posts_query->get('suppress_filters')) { return; } // Bail if in admin if (is_admin()) { return; } // Don't query for any posts on /docs/create/ if ($posts_query->get(BP_DOCS_CREATE_SLUG)) { $posts_query->is_404 = false; $posts_query->set('p', -1); } // Fall back on archive template on /docs/my-groups/ if ($posts_query->get(BP_DOCS_MY_GROUPS_SLUG)) { $posts_query->is_404 = false; } // For single Doc views, allow access to 'deleted' items // that the current user is the admin of if ($posts_query->is_single && bp_docs_get_post_type_name() === $posts_query->get('post_type')) { $doc_slug = $posts_query->get('name'); // Direct query, because barf global $wpdb; $author_id = $wpdb->get_var($wpdb->prepare("SELECT post_author FROM {$wpdb->posts} WHERE post_type = %s AND post_name = %s", bp_docs_get_post_type_name(), $doc_slug)); // Post author or mod can visit it if ($author_id && ($author_id == get_current_user_id() || current_user_can('bp_moderate'))) { $posts_query->set('post_status', array('publish', 'trash')); // Make the 'trash' post status public add_filter('posts_request', array($this, 'make_trash_public')); // ... and undo that when we're done add_filter('the_posts', array($this, 'remove_make_trash_public')); } } }
function bp_docs_upgrade_1_2($udata = array()) { global $wpdb; $url_base = admin_url(add_query_arg(array('post_type' => bp_docs_get_post_type_name(), 'page' => 'bp-docs-upgrade'), 'edit.php')); if (empty($udata['total'])) { $udata['total'] = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s", bp_docs_get_post_type_name())); } if (!isset($udata['done'])) { $udata['done'] = 0; } if (empty($udata['group_terms_migrated'])) { $tn = bp_docs_get_associated_item_tax_name(); // Get the group parent term $group_parent_term = term_exists('group', $tn); // Get all the group terms if ($group_parent_term) { // Delete the cached children terms, for good measure delete_option($tn . '_children'); $group_terms = get_terms($tn, array('parent' => intval($group_parent_term['term_id']))); foreach ($group_terms as $group_term) { // Concatenate new term slugs $new_desc = sprintf(__('Docs associated with the group %s', 'bp-docs'), $group_term->description); $new_slug = 'bp_docs_associated_group_' . $group_term->name; $new_name = $group_term->description; wp_update_term($group_term->term_id, $tn, array('description' => $new_desc, 'slug' => $new_slug, 'name' => $new_name, 'parent' => 0)); } } // Store that we're done $udata['group_terms_migrated'] = 1; $udata['message'] = __('Group terms migrated. Now migrating Doc access terms....', 'bp-docs'); $udata['refresh_url'] = add_query_arg(array('do_upgrade' => '1', '_wpnonce' => wp_create_nonce('bp-docs-upgrade')), $url_base); $udata['total'] = 0; } else { if (intval($udata['done']) < intval($udata['total'])) { $counter = 0; while ($counter < 5) { $next_doc_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND ID > %d LIMIT 1", bp_docs_get_post_type_name(), intval($udata['last']))); if (!$next_doc_id) { $udata['done'] = $udata['total']; $all_done = true; break; } // Set the 'read' setting to a taxonomy $doc_settings = get_post_meta($next_doc_id, 'bp_docs_settings', true); if (isset($doc_settings['read'])) { $read_setting = $doc_settings['read']; } else { $group = groups_get_group('group_id=' . bp_docs_get_associated_group_id($next_doc_id)); if (!empty($group->status) && 'public' != $group->status) { $read_setting = 'group-members'; // Sanitize settings as well foreach ($doc_settings as $doc_settings_key => $doc_settings_value) { if (in_array($doc_settings_value, array('anyone', 'loggedin'))) { $doc_settings[$doc_settings_key] = 'group-members'; } } $doc_settings['read'] = 'group-members'; update_post_meta($next_doc_id, 'bp_docs_settings', $doc_settings); } else { $read_setting = 'anyone'; } } bp_docs_update_doc_access($next_doc_id, $read_setting); // Count the total number of edits $count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = 'revision' AND post_status = 'inherit' AND post_parent = %d", $next_doc_id)); update_post_meta($next_doc_id, 'bp_docs_revision_count', $count + 1); $counter++; $udata['done']++; $udata['last'] = $next_doc_id; $udata['message'] = sprintf(__('Migrated %s of %s Docs. Migrating....', 'bp-docs'), $udata['done'], $udata['total']); $udata['refresh_url'] = add_query_arg(array('do_upgrade' => '1', '_wpnonce' => wp_create_nonce('bp-docs-upgrade')), $url_base); } } else { $all_done = true; $udata['refresh_url'] = add_query_arg(array('bp_docs_upgraded' => 1), admin_url()); } } if (isset($all_done)) { bp_update_option('_bp_docs_done_upgrade_1_2', 1); } return $udata; }
/** * Update the global $post with dummy data regarding doc creation * * @since 1.3 */ public function create_dummy_post() { bp_theme_compat_reset_post(array('ID' => 0, 'post_title' => __('Create a Doc', 'bp-docs'), 'post_author' => get_current_user_id(), 'post_date' => 0, 'post_content' => '', 'post_type' => bp_docs_get_post_type_name(), 'post_status' => 'publish', 'is_archive' => true, 'comment_status' => 'closed')); }
function bp_docs_get_doc_ids_accessible_to_current_user() { global $wpdb; // Direct query for speeeeeeed $exclude = bp_docs_access_query()->get_doc_ids(); if (empty($exclude)) { $exclude = array(0); } $exclude_sql = '(' . implode(',', $exclude) . ')'; $items_sql = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND ID NOT IN {$exclude_sql}", bp_docs_get_post_type_name()); return $wpdb->get_col($items_sql); }
/** * AJAX handler for setting edit lock. * * Called when a user enters an Edit page. * * @since 1.6.0 */ function bp_docs_add_edit_lock_cb() { $doc_id = isset($_POST['doc_id']) ? (int) $_POST['doc_id'] : false; if (!$doc_id) { return; } $doc = get_post($doc_id); if (!$doc || is_wp_error($doc)) { return; } if (bp_docs_get_post_type_name() !== $doc->post_type) { return; } if (!is_user_logged_in()) { return; } // Is this post already locked? $lock = bp_docs_check_post_lock($doc_id); if (!empty($lock) && $lock != bp_loggedin_user_id()) { die; } $now = time(); $user_id = bp_loggedin_user_id(); $lock = "{$now}:{$user_id}"; update_post_meta($doc_id, '_bp_docs_last_pinged', $lock); die(json_encode('1')); }
/** * Map our caps to WP's * * @since 1.2 * * @param array $caps Capabilities for meta capability * @param string $cap Capability name * @param int $user_id User id * @param mixed $args Arguments passed to map_meta_cap filter * @uses get_post() To get the post * @uses get_post_type_object() To get the post type object * @uses apply_filters() Calls 'bp_docs_map_meta_caps' with caps, cap, user id and * args * @return array Actual capabilities for meta capability */ function bp_docs_map_meta_caps($caps, $cap, $user_id, $args) { global $post, $wp_post_types; // No need to continue if BuddyPress Docs hasn't been initialized $pt = bp_docs_get_post_type_name(); if (empty($pt)) { return $caps; } // Set up some data we'll need for these permission checks $doc = bp_docs_get_doc_for_caps($args); // Nothing to check if (empty($doc)) { return $caps; } $post_type = get_post_type_object($doc->post_type); $doc_settings = bp_docs_get_doc_settings($doc_id); // Reset all caps. We bake from scratch $caps = array(); switch ($cap) { case 'create_bp_doc': // @todo This will probably need more thought if (!is_user_logged_in()) { $caps[] = 'do_not_allow'; } else { // @todo - need to detect group membership $caps[] = $cap; } break; case 'read_bp_doc': $caps[] = 'exist'; // anyone can read Docs by default break; case 'edit_bp_doc': if ($user_id == $doc->post_author) { $caps[] = $cap; } else { if (isset($doc_settings['edit'])) { var_dump($doc_settings['edit']); } else { if (bp_docs_user_has_custom_access($user_id, $doc_settings, 'edit')) { $caps[] = $cap; } else { $caps[] = 'do_not_allow'; } } } break; case 'view_bp_doc_history': if ($user_id == $doc->post_author) { $caps[] = $cap; } else { if (bp_docs_user_has_custom_access($user_id, $doc_settings, 'view_history')) { $caps[] = $cap; } else { $caps[] = 'do_not_allow'; } } break; } return apply_filters('bp_docs_map_meta_caps', $caps, $cap, $user_id, $args); }
/** * Determine how many revisions to retain for Docs. * * @since 1.8 * * @return int */ function bp_docs_revisions_to_keep($num, $post) { if (bp_docs_get_post_type_name() !== $post->post_type) { return $num; } if (defined('BP_DOCS_REVISIONS')) { if (true === BP_DOCS_REVISIONS) { $num = -1; } else { $num = intval(BP_DOCS_REVISIONS); } } return intval($num); }
/** * @group bp_docs_delete_folder_contents */ public function test_bp_docs_delete_folder_contents() { $f1 = bp_docs_create_folder(array('name' => 'foo')); $f1_d1 = $this->factory->doc->create(); $f1_d2 = $this->factory->doc->create(); bp_docs_add_doc_to_folder($f1_d1, $f1); bp_docs_add_doc_to_folder($f1_d2, $f1); $f2 = bp_docs_create_folder(array('name' => 'foo', 'parent' => $f1)); $f2_d1 = $this->factory->doc->create(); $f2_d2 = $this->factory->doc->create(); bp_docs_add_doc_to_folder($f2_d1, $f2); bp_docs_add_doc_to_folder($f2_d2, $f2); $f3 = bp_docs_create_folder(array('name' => 'foo', 'parent' => $f1)); $f3_d1 = $this->factory->doc->create(); $f3_d2 = $this->factory->doc->create(); bp_docs_add_doc_to_folder($f3_d1, $f3); bp_docs_add_doc_to_folder($f3_d2, $f3); $f4 = bp_docs_create_folder(array('name' => 'foo', 'parent' => $f2)); $f4_d1 = $this->factory->doc->create(); $f4_d2 = $this->factory->doc->create(); bp_docs_add_doc_to_folder($f4_d1, $f4); bp_docs_add_doc_to_folder($f4_d2, $f4); $this->assertTrue(bp_docs_delete_folder_contents($f1)); $f1_term = bp_docs_get_folder_term($f1); $f1_docs = get_posts(array('post_type' => bp_docs_get_post_type_name(), 'tax_query' => array(array('taxonomy' => 'bp_docs_doc_in_folder', 'field' => 'term_id', 'terms' => $f1_term)), 'update_meta_cache' => false, 'update_term_cache' => false)); $this->assertSame(array(), $f1_docs); $f2_term = bp_docs_get_folder_term($f2); $f2_docs = get_posts(array('post_type' => bp_docs_get_post_type_name(), 'tax_query' => array(array('taxonomy' => 'bp_docs_doc_in_folder', 'field' => 'term_id', 'terms' => $f2_term)), 'update_meta_cache' => false, 'update_term_cache' => false)); $this->assertSame(array(), $f2_docs); $f3_term = bp_docs_get_folder_term($f3); $f3_docs = get_posts(array('post_type' => bp_docs_get_post_type_name(), 'tax_query' => array(array('taxonomy' => 'bp_docs_doc_in_folder', 'field' => 'term_id', 'terms' => $f3_term)), 'update_meta_cache' => false, 'update_term_cache' => false)); $this->assertSame(array(), $f3_docs); $f4_term = bp_docs_get_folder_term($f4); $f4_docs = get_posts(array('post_type' => bp_docs_get_post_type_name(), 'tax_query' => array(array('taxonomy' => 'bp_docs_doc_in_folder', 'field' => 'term_id', 'terms' => $f4_term)), 'update_meta_cache' => false, 'update_term_cache' => false)); $this->assertSame(array(), $f4_docs); $this->assertSame(array(), bp_docs_get_folders(array('parent_id' => $f1))); $this->assertSame(array(), bp_docs_get_folders(array('parent_id' => $f2))); }
/** * Give users the 'upload_files' cap, when appropriate * * @since 1.4 * * @param array $caps The mapped caps * @param string $cap The cap being mapped * @param int $user_id The user id in question * @param $args * @return array $caps */ public static function map_meta_cap($caps, $cap, $user_id, $args) { if ('upload_files' !== $cap) { return $caps; } $maybe_user = new WP_User($user_id); if (!is_a($maybe_user, 'WP_User') || empty($maybe_user->ID)) { return $caps; } $is_doc = false; // DOING_AJAX is not set yet, so we cheat $is_ajax = isset($_SERVER['REQUEST_METHOD']) && 'POST' === $_SERVER['REQUEST_METHOD'] && 'async-upload.php' === substr($_SERVER['REQUEST_URI'], strrpos($_SERVER['REQUEST_URI'], '/') + 1); if ($is_ajax) { // Clean up referer $referer = $_SERVER['HTTP_REFERER']; $qp = strpos($referer, '?'); if (false !== $qp) { $referer = substr($referer, 0, $qp); } $referer = trailingslashit($referer); // Existing Doc $item_id = self::get_doc_id_from_url($referer); if ($item_id) { $item = get_post($item_id); $is_doc = bp_docs_get_post_type_name() === $item->post_type; } // Create Doc if (!$is_doc) { $is_doc = $referer === bp_docs_get_create_link(); } } else { $is_doc = bp_docs_is_existing_doc() || bp_docs_is_doc_create(); } if ($is_doc) { $caps = array('exist'); // Since we've already done the permissions check, // we can filter future current_user_can() checks on // this pageload add_filter('map_meta_cap', array(__CLASS__, 'map_meta_cap_supp'), 10, 4); } return $caps; }
/** * Gets the list of terms used by a group's docs * * At the moment, this method (and the next one) assumes that you want the terms of the * current group. At some point, that should be abstracted a bit. * * @since 1.0-beta * * @return array $terms */ function get_group_terms($terms = array()) { global $bp; // Either it's a group directory... if (!($group_id = bp_get_current_group_id())) { // ... or a single doc associated with a group... if (bp_docs_is_existing_doc()) { $doc = get_post(); $group_id = bp_docs_get_associated_group_id($doc->ID, $doc); } } if (!$group_id) { return $terms; } $query_args = array('post_type' => bp_docs_get_post_type_name(), 'update_meta_cache' => false, 'update_term_cache' => true, 'showposts' => '-1', 'posts_per_page' => '-1', 'tax_query' => array(self::tax_query_arg_for_groups($group_id))); $group_doc_query = new WP_Query($query_args); $terms = array(); foreach ($group_doc_query->posts as $p) { $p_terms = wp_get_post_terms($p->ID, buddypress()->bp_docs->docs_tag_tax_name); foreach ($p_terms as $p_term) { if (!isset($terms[$p_term->slug])) { $terms[$p_term->slug] = array('name' => $p_term->name, 'posts' => array()); } if (!in_array($p->ID, $terms[$p_term->slug]['posts'])) { $terms[$p_term->slug]['posts'][] = $p->ID; } } } foreach ($terms as &$t) { $t['count'] = count($t['posts']); } if (empty($terms)) { $terms = array(); } return apply_filters('bp_docs_taxonomy_get_group_terms', $terms); }
/** * Is this the BP Docs component? */ function bp_docs_is_docs_component() { $retval = false; $p = get_queried_object(); if (is_post_type_archive(bp_docs_get_post_type_name())) { $retval = true; } else { if (isset($p->post_type) && bp_docs_get_post_type_name() == $p->post_type) { $retval = true; } else { if (bp_is_current_component(bp_docs_get_slug())) { // This covers cases where we're looking at the Docs component of a user $retval = true; } } } return $retval; }
public function setup_menus() { // Settings add_submenu_page('edit.php?post_type=' . bp_docs_get_post_type_name(), __('BuddyPress Docs Settings', 'bp-docs'), __('Settings', 'bp-docs'), 'bp_moderate', 'bp-docs-settings', array($this, 'settings_cb')); }
public function end_el(&$output, $page, $depth = 0, $args = array(), $current_page = 0) { // Get the docs belonging to this folder $folder_term = bp_docs_get_folder_term($page->ID); $folder_docs = get_posts(array('post_type' => bp_docs_get_post_type_name(), 'tax_query' => array(array('taxonomy' => 'bp_docs_doc_in_folder', 'field' => 'term_id', 'terms' => $folder_term)))); $empty_class = empty($folder_docs) ? 'empty' : ''; $output .= sprintf('<ul class="docs-in-folder %s" id="docs-in-folder-%d">', $empty_class, $page->ID); $output .= '<li class="folder-empty">' . __('This folder contains no Docs.', 'bp-docs') . '</li>'; foreach ($folder_docs as $folder_doc) { $output .= sprintf('<li class="doc-in-folder" id="doc-in-folder-%d" data-doc-id="%d">%s<a href="%s">%s</a>%s</li>', $folder_doc->ID, $folder_doc->ID, bp_docs_get_genericon('document', $folder_doc->ID), get_permalink($folder_doc), esc_html($folder_doc->post_title), wp_nonce_field('bp-docs-folder-drop-' . $folder_doc->ID, 'bp-docs-folder-drop-nonce-' . $folder_doc->ID, false, false)); } $output .= '</ul>'; $output .= '</li>'; }
/** * Get a list of an item's docs for display in the parent dropdown * * @package BuddyPress Docs * @since 1.0-beta */ function bp_docs_edit_parent_dropdown() { global $bp; $include = array(); $doc_query_builder = new BP_Docs_Query(array('doc_slug' => false, 'posts_per_page' => -1)); $doc_query = $doc_query_builder->get_wp_query(); if ($doc_query->have_posts()) { while ($doc_query->have_posts()) { $doc_query->the_post(); $include[] = get_the_ID(); } } $current_doc = get_queried_object(); $exclude = $parent = false; if (isset($current_doc->post_type) && bp_docs_get_post_type_name() === $current_doc->post_type) { $exclude = array($current_doc->ID); $parent = $current_doc->post_parent; } $pages = wp_dropdown_pages(array('post_type' => $bp->bp_docs->post_type_name, 'exclude' => $exclude, 'include' => $include, 'selected' => $parent, 'name' => 'parent_id', 'show_option_none' => __('(no parent)', 'bp-docs'), 'sort_column' => 'menu_order, post_title', 'echo' => 0)); echo $pages; }
/** * Get a list of an item's docs for display in the parent dropdown * * @package BuddyPress Docs * @since 1.0-beta */ function bp_docs_edit_parent_dropdown() { global $bp; $include = array(); $query_args = apply_filters('bp_docs_parent_dropdown_query_args', array('doc_slug' => false, 'posts_per_page' => -1)); $doc_query_builder = new BP_Docs_Query($query_args); $doc_query = $doc_query_builder->get_wp_query(); if ($doc_query->have_posts()) { while ($doc_query->have_posts()) { $doc_query->the_post(); $include[] = get_the_ID(); } } $current_doc = get_queried_object(); $exclude = $parent = false; // If this is a failed submission, use the value from the POST cookie if (!empty(buddypress()->bp_docs->submitted_data->parent_id)) { $parent = intval(buddypress()->bp_docs->submitted_data->parent_id); } else { if (isset($current_doc->post_type) && bp_docs_get_post_type_name() === $current_doc->post_type) { $exclude = array($current_doc->ID); $parent = $current_doc->post_parent; } } $pages = wp_dropdown_pages(array('post_type' => $bp->bp_docs->post_type_name, 'exclude' => $exclude, 'include' => $include, 'selected' => $parent, 'name' => 'parent_id', 'show_option_none' => __('(no parent)', 'bp-docs'), 'sort_column' => 'menu_order, post_title', 'echo' => 0)); echo $pages; }