function test_bp_docs_get_doc_link() { // rewrite - @todo This stinks global $wp_rewrite; $GLOBALS['wp_rewrite']->init(); flush_rewrite_rules(); $doc_id = $this->factory->doc->create(array('post_name' => 'foo')); $this->assertEquals(bp_docs_get_doc_link($doc_id), 'http://example.org/docs/foo/'); // Set a parent to make sure it still works $doc_id2 = $this->factory->doc->create(); wp_update_post(array('ID' => $doc_id, 'post_parent' => $doc_id2)); $this->assertEquals(bp_docs_get_doc_link($doc_id), 'http://example.org/docs/foo/'); }
/** * Get the URL for canceling out of Edit mode on a doc * * This used to be a straight link back to non-edit mode, but something fancier is needed * in order to detect the Cancel and to remove the edit lock. * * @package BuddyPress Docs * @since 1.0-beta-2 * * @return string $cancel_link href for the cancel edit link */ function bp_docs_get_cancel_edit_link() { global $bp, $post; $doc_id = get_queried_object_id(); if (!$doc_id) { return false; } $doc_permalink = bp_docs_get_doc_link($doc_id); $cancel_link = add_query_arg('bpd_action', 'cancel_edit', $doc_permalink); return apply_filters('bp_docs_get_cancel_edit_link', $cancel_link, $doc_permalink); }
/** * Format 'bp_doc_comment' activity actions. * * @since 1.7.0 * * @param string $action Activity action. * @param object $activity Activity object. * @return string */ function bp_docs_format_activity_action_bp_doc_comment($action, $activity) { $doc = get_post($comment->comment_post_ID); if (!$doc) { return $action; } $user_link = bp_core_get_userlink($activity->user_id); $comment = get_comment($activity->secondary_item_id); $doc_url = bp_docs_get_doc_link($doc->ID); $comment_url = $doc_url . '#comment-' . $comment->comment_ID; $doc_link = sprintf('<a href="%s">%s</a>', $comment_url, $doc->post_title); $action = sprintf(__('%1$s commented on the doc %2$s', 'bp-docs'), $user_link, $doc_link); return $action; }
function bp_docs_attachment_item_markup($attachment_id, $format = 'full') { $markup = ''; $att_url = bp_docs_get_attachment_url($attachment_id); $attachment = get_post($attachment_id); $att_base = basename(get_attached_file($attachment_id)); $doc_url = bp_docs_get_doc_link($attachment->post_parent); $attachment_ext = preg_replace('/^.+?\\.([^.]+)$/', '$1', $att_url); if ('full' === $format) { $attachment_delete_html = ''; if (current_user_can('bp_docs_edit') && (bp_docs_is_doc_edit() || bp_docs_is_doc_create())) { $attachment_delete_url = wp_nonce_url($doc_url, 'bp_docs_delete_attachment_' . $attachment_id); $attachment_delete_url = add_query_arg(array('delete_attachment' => $attachment_id), $attachment_delete_url); $attachment_delete_html = sprintf('<a href="%s" class="doc-attachment-delete confirm button">%s</a> ', $attachment_delete_url, __('Delete', 'buddypress')); } $markup = sprintf('<li id="doc-attachment-%d"><span class="doc-attachment-mime-icon doc-attachment-mime-%s"></span><a href="%s" title="%s">%s</a>%s</li>', $attachment_id, $attachment_ext, $att_url, esc_attr($att_base), esc_html($att_base), $attachment_delete_html); } else { $markup = sprintf('<li id="doc-attachment-%d"><span class="doc-attachment-mime-icon doc-attachment-mime-%s"></span><a href="%s" title="%s">%s</a></li>', $attachment_id, $attachment_ext, $att_url, esc_attr($att_base), esc_html($att_base)); } return $markup; }
function url_backpat() { global $bp, $wpdb; if (bp_is_group() && bp_is_current_action('docs')) { if ('single' == $bp->bp_docs->current_view) { // Look up a Doc by this name $maybe_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_name = %s LIMIT 1", bp_action_variable(0))); // Redirect to that Doc. Permissions will be handled there if ($maybe_id) { bp_core_redirect(bp_docs_get_doc_link($maybe_id)); } } } }
/** * Filters the comment_post_direct URL so that the user gets sent back to the true * comment URL after posting * * @package BuddyPress Docs * @since 1.0-beta * * @param str $location The original location, created by WP * @param obj $comment The new comment object * @return str $location The correct location */ function comment_post_redirect($location, $comment) { global $bp; // Check to see whether this is a BP Doc $post = get_post($comment->comment_post_ID); if ($bp->bp_docs->post_type_name != $post->post_type) { return $location; } $location = bp_docs_get_doc_link($comment->comment_post_ID) . '#comment-' . $comment->comment_ID; return $location; }
/** * Posts an activity item when a comment is posted to a doc * * @package BuddyPress Docs * @since 1.0-beta * * @param obj $query The id of the comment that's just been saved * @return int $activity_id The id number of the activity created */ function post_comment_activity($comment_id) { global $bp; if (!bp_is_active('activity')) { return false; } if (empty($comment_id)) { return false; } $comment = get_comment($comment_id); $doc = !empty($comment->comment_post_ID) ? get_post($comment->comment_post_ID) : false; if (empty($doc)) { return false; } // Only continue if this is a BP Docs post if ($doc->post_type != $bp->bp_docs->post_type_name) { return; } $doc_id = !empty($doc->ID) ? $doc->ID : false; if (!$doc_id) { return false; } // Make sure that BP doesn't record this comment with its native functions remove_action('comment_post', 'bp_blogs_record_comment', 10, 2); // Until better individual activity item privacy controls are available in BP, // comments will only be shown in the activity stream if "Who can read comments on // this doc?" is set to "Anyone" or "Group members" $doc_settings = get_post_meta($doc_id, 'bp_docs_settings', true); if (!empty($doc_settings['read_comments']) && ('admins-mods' == $doc_settings['read_comments'] || 'no-one' == $doc_settings['read_comments'])) { return false; } // Get the associated item for this doc. Todo: abstract to standalone function $items = wp_get_post_terms($doc_id, $bp->bp_docs->associated_item_tax_name); // It's possible that there will be more than one item; for now, post only to the // first one. Todo: make this extensible $item = !empty($items[0]->name) ? $items[0]->name : false; // From the item, we can obtain the component (the parent tax of the item tax) if (!empty($items[0]->parent)) { $parent = get_term((int) $items[0]->parent, $bp->bp_docs->associated_item_tax_name); // For some reason, I named them singularly. So we have to canonicalize switch ($parent->slug) { case 'user': $component = 'profile'; break; case 'group': default: $component = 'groups'; break; } } // Set the action. Filterable so that other integration pieces can alter it $action = ''; $commenter = get_user_by_email($comment->comment_author_email); $commenter_id = !empty($commenter->ID) ? $commenter->ID : false; // Since BP Docs only allows member comments, the following should never happen if (!$commenter_id) { return false; } $user_link = bp_core_get_userlink($commenter_id); $doc_url = bp_docs_get_doc_link($doc_id); $comment_url = $doc_url . '#comment-' . $comment->comment_ID; $comment_link = '<a href="' . $comment_url . '">' . $doc->post_title . '</a>'; $action = sprintf(__('%1$s commented on the doc %2$s', 'bp-docs'), $user_link, $comment_link); $action = apply_filters('bp_docs_comment_activity_action', $action, $user_link, $comment_link, $component, $item); // Set the type, to be used in activity filtering $type = 'bp_doc_comment'; $args = array('user_id' => $commenter_id, 'action' => $action, 'content' => $comment->comment_content, 'primary_link' => $comment_url, 'component' => $component, 'type' => $type, 'item_id' => $item, 'secondary_item_id' => $comment_id, 'recorded_time' => bp_core_current_time(), 'hide_sitewide' => apply_filters('bp_docs_hide_sitewide', false, $comment, $doc, $item, $component)); do_action('bp_docs_before_comment_activity_save', $args); $activity_id = bp_activity_add(apply_filters('bp_docs_comment_activity_args', $args)); do_action('bp_docs_after_comment_activity_save', $activity_id, $args); return $activity_id; }
/** * Protects group docs from unauthorized access * * @since 1.2 */ function protect_doc_access() { // What is the user trying to do? if (bp_docs_is_doc_read()) { $action = 'bp_docs_read'; } else { if (bp_docs_is_doc_create()) { $action = 'bp_docs_create'; } else { if (bp_docs_is_doc_edit()) { $action = 'bp_docs_edit'; } else { if (bp_docs_is_doc_history()) { $action = 'bp_docs_view_history'; } } } } if (!isset($action)) { return; } if (!current_user_can($action)) { $redirect_to = bp_docs_get_doc_link(); bp_core_no_access(array('mode' => 2, 'redirect' => $redirect_to)); } }
/** * Generates the rewrite rules to be put in .htaccess of the upload dir * * @since 1.4 * @return array $rules One per line, to be put together by insert_with_markers() */ public function generate_rewrite_rules() { $rules = array(); $doc_id = $this->get_doc_id(); if (!$doc_id) { return $rules; } $url = bp_docs_get_doc_link($doc_id); $url_parts = parse_url($url); if (!empty($url_parts['path'])) { $rules = array('RewriteEngine On', 'RewriteBase ' . $url_parts['path'], 'RewriteRule (.+) ?bp-attachment=$1 [R=302,NC]'); } return apply_filters('bp_docs_attachments_generate_rewrite_rules', $rules, $this); }
/** * Echo the History header tab. * * This is hooked to bp_docs_header_tabs, so that it only loads if the History addon is * enabled. * * @package BuddyPress Docs * @since 1.1.4 */ function bp_docs_history_tab() { if (current_user_can('bp_docs_view_history')) { ?> <li<?php if (bp_docs_is_doc_history()) { ?> class="current"<?php } ?> > <a href="<?php echo bp_docs_get_doc_link() . BP_DOCS_HISTORY_SLUG; ?> "><?php _e('History', 'bp-docs'); ?> </a> </li> <?php } }
/** * Posts an activity item on doc save * * @package BuddyPress Docs * @since 1.0-beta * * @param obj $query The query object created in BP_Docs_Query and passed to the * bp_docs_doc_saved filter * @return int $activity_id The id number of the activity created */ function post_activity($query) { global $bp; // todo: exception for autosave? if (!bp_is_active('activity')) { return false; } $doc_id = !empty($query->doc_id) ? $query->doc_id : false; if (!$doc_id) { return false; } $last_editor = get_post_meta($doc_id, 'bp_docs_last_editor', true); // Throttle 'doc edited' posts. By default, one per user per hour if (!$query->is_new_doc) { // Look for an existing activity item corresponding to this user editing // this doc $already_args = array('max' => 1, 'sort' => 'DESC', 'show_hidden' => 1, 'filter' => array('user_id' => $last_editor, 'action' => 'bp_doc_edited', 'secondary_id' => $doc_id)); $already_activity = bp_activity_get($already_args); // If any activity items are found, compare its date_recorded with time() to // see if it's within the allotted throttle time. If so, don't record the // activity item if (!empty($already_activity['activities'])) { $date_recorded = $already_activity['activities'][0]->date_recorded; $drunix = strtotime($date_recorded); if (time() - $drunix <= apply_filters('bp_docs_edit_activity_throttle_time', 60 * 60)) { return; } } } $doc = get_post($doc_id); // Set the action. Filterable so that other integration pieces can alter it $action = ''; $user_link = bp_core_get_userlink($last_editor); $doc_url = bp_docs_get_doc_link($doc_id); $doc_link = '<a href="' . $doc_url . '">' . $doc->post_title . '</a>'; if ($query->is_new_doc) { $action = sprintf(__('%1$s created the doc %2$s', 'bp-docs'), $user_link, $doc_link); } else { $action = sprintf(__('%1$s edited the doc %2$s', 'bp-docs'), $user_link, $doc_link); } $action = apply_filters('bp_docs_activity_action', $action, $user_link, $doc_link, $query->is_new_doc, $query); $hide_sitewide = bp_docs_hide_sitewide_for_doc($doc_id); // Get a canonical name for the component. This is a nightmare because of the way // the current component and root slug relate in BP 1.3+ $component = bp_current_component(); // Temp if (!$component) { $component = $this->id; } // This is only temporary! This item business needs to be component-neutral $item = isset($bp->groups->current_group->id) ? $bp->groups->current_group->id : false; // Set the type, to be used in activity filtering $type = $query->is_new_doc ? 'bp_doc_created' : 'bp_doc_edited'; $args = array('user_id' => $last_editor, 'action' => $action, 'primary_link' => $doc_url, 'component' => $component, 'type' => $type, 'item_id' => $query->item_id, 'secondary_item_id' => $doc_id, 'recorded_time' => bp_core_current_time(), 'hide_sitewide' => apply_filters('bp_docs_hide_sitewide', $hide_sitewide, false, $doc, $item, $component)); do_action('bp_docs_before_activity_save', $args); $activity_id = bp_activity_add(apply_filters('bp_docs_activity_args', $args)); do_action('bp_docs_after_activity_save', $activity_id, $args); return $activity_id; }
/** * Display links to the doc's children * * @package BuddyPress Docs * @since 1.0 */ function show_children() { global $bp; // Get the child posts $child_posts_args = array('post_type' => $bp->bp_docs->post_type_name, 'post_parent' => get_the_ID()); $child_posts = new WP_Query($child_posts_args); // Assemble the link data out of the query $child_data = array(); if ($child_posts->have_posts()) { while ($child_posts->have_posts()) { $child_posts->the_post(); $child_id = get_the_ID(); $child_data[$child_id] = array('post_name' => get_the_title(), 'post_link' => bp_docs_get_doc_link($child_id)); } } $child_data = apply_filters('bp_docs_hierarchy_child_data', $child_data); // Create the HTML $html = ''; if (!empty($child_data)) { $html .= '<p>' . __('Children: ', 'bp-docs'); $children_html = array(); foreach ($child_data as $child) { $children_html[] = '<a href="' . $child['post_link'] . '">' . $child['post_name'] . '</a>'; } $html .= implode(', ', $children_html); $html .= '</p>'; } echo apply_filters('bp_docs_hierarchy_show_children', $html, $child_data); }
" title="<?php if (bp_docs_get_excerpt_length()) { echo get_the_excerpt(); } ?> "><?php the_title(); ?> </a> <span class="bp-docs-trash-notice"><?php bp_docs_doc_trash_notice(); ?> </span> <?php if (current_user_can('bp_docs_edit', get_the_ID())) { echo '<a href="' . bp_docs_get_doc_link() . BP_DOCS_EDIT_SLUG . '" class="bp-docs-edit-link" title="Redigera"><i class="fa fa-pencil-square-o"></i></a>'; } ?> <span class="bp-docs-date">(Senast uppdaterat <?php echo get_the_modified_date(); ?> )</span> </li> <?php } echo '</ul></div>'; ?> <?php } else {
/** * Get the URL to delete the current doc * * @package BuddyPress Docs * @since 1.0.1 * * @return string $delete_link href for the delete doc link */ function bp_docs_get_delete_doc_link() { $doc_permalink = bp_docs_get_doc_link(); $delete_link = wp_nonce_url(add_query_arg(BP_DOCS_DELETE_SLUG, '1', $doc_permalink), 'bp_docs_delete'); return apply_filters('bp_docs_get_delete_doc_link', $delete_link, $doc_permalink); }
/** * Determines what the user is trying to do on this page view. * * This determination is made mostly on the basis of the information passed in the URL * parameters. This function is also responsible for some of the object setup (getting the * revision post(s), etc). * * This is cribbed nearly wholesale from wp-admin/revision.php. In the future I would like * to clean it up to be less WordPressy and more pluginish. * * @package BuddyPress Docs * @since 1.1 */ function setup_action() { global $bp, $post; wp_enqueue_script('list-revisions'); $redirect = false; switch ($this->action) { case 'restore': if (!($this->revision = wp_get_post_revision($this->revision_id))) { break; } if (!bp_docs_current_user_can('edit')) { break; } if (!($post = get_post($this->revision->post_parent))) { break; } // Revisions disabled and we're not looking at an autosave if ((!WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions')) && !wp_is_post_autosave($this->revision)) { $redirect = 'edit.php?post_type=' . $post->post_type; break; } $referer = 'restore-post_' . $post->ID . '|' . $this->revision->ID; check_admin_referer($referer); wp_restore_post_revision($this->revision->ID); bp_core_add_message(sprintf(__('You have successfully restored the Doc to the revision from %s.', 'bp-docs'), $this->revision->post_date)); $redirect = bp_docs_get_doc_link($post->ID) . '/' . BP_DOCS_HISTORY_SLUG . '/'; break; case 'diff': if (!($this->left_revision = get_post($this->left))) { break; } if (!($this->right_revision = get_post($this->right))) { break; } if (!current_user_can('read_post', $this->left_revision->ID) || !current_user_can('read_post', $this->right_revision->ID)) { break; } // If we're comparing a revision to itself, redirect to the 'view' page for that revision or the edit page for that post if ($this->left_revision->ID == $this->right_revision->ID) { $redirect = get_edit_post_link($this->left_revision->ID); break; } // Don't allow reverse diffs? if (strtotime($this->right_revision->post_modified_gmt) < strtotime($this->left_revision->post_modified_gmt)) { $redirect = add_query_arg(array('left' => $this->right, 'right' => $this->left)); break; } if ($this->left_revision->ID == $this->right_revision->post_parent) { // right is a revision of left $post =& $this->left_revision; } elseif ($this->left_revision->post_parent == $this->right_revision->ID) { // left is a revision of right $post =& $this->right_revision; } elseif ($this->left_revision->post_parent == $this->right_revision->post_parent) { // both are revisions of common parent $post = get_post($this->left_revision->post_parent); } else { break; } // Don't diff two unrelated revisions if (!WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions')) { // Revisions disabled if (!wp_is_post_autosave($this->left_revision) && !wp_is_post_autosave($this->right_revision) || $post->ID !== $this->left_revision->ID && $post->ID !== $this->right_revision->ID) { $redirect = 'edit.php?post_type=' . $post->post_type; break; } } if ($this->left_revision->ID == $this->right_revision->ID || !wp_get_post_revision($this->left_revision->ID) && !wp_get_post_revision($this->right_revision->ID)) { break; } $post_title = '<a href="' . get_edit_post_link() . '">' . get_the_title() . '</a>'; $h2 = sprintf(__('Compare Revisions of “%1$s”', 'bp-docs'), $post_title); $title = __('Revisions', 'bp-docs'); $this->left = $this->left_revision->ID; $this->right = $this->right_revision->ID; $redirect = false; break; case 'view': default: if (!($this->revision = wp_get_post_revision($this->revision_id))) { if ($this->revision = get_post($this->revision_id)) { $this->is_latest = true; } else { break; } } if (!($post = get_post($this->revision->post_parent))) { break; } if (!current_user_can('read_post', $this->revision->ID) || !current_user_can('read_post', $post->ID)) { break; } // Revisions disabled and we're not looking at an autosave if ((!WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions')) && !wp_is_post_autosave($this->revision)) { $redirect = 'edit.php?post_type=' . $post->post_type; break; } $post_title = '<a href="' . get_edit_post_link() . '">' . get_the_title() . '</a>'; $revision_title = wp_post_revision_title($this->revision, false); $h2 = sprintf(__('Revision for “%1$s” created on %2$s', 'bp-docs'), $post_title, $revision_title); $title = __('Revisions', 'bp-docs'); // Sets up the diff radio buttons $this->left = $this->revision->ID; $this->right = $post->ID; $redirect = false; break; } if ($redirect) { bp_core_redirect($redirect); } $this->setup_is_identical(); }
/** * Get the URL to delete the current doc * * @package BuddyPress Docs * @since 1.0.1 * * @return string $delete_link href for the delete doc link */ function bp_docs_get_delete_doc_link() { global $bp, $post; $doc_id = !empty($bp->bp_docs->current_post->ID) ? $bp->bp_docs->current_post->ID : false; if (!$doc_id) { return false; } $doc_permalink = bp_docs_get_doc_link($doc_id); $delete_link = wp_nonce_url($doc_permalink . '/' . BP_DOCS_DELETE_SLUG, 'bp_docs_delete'); return apply_filters('bp_docs_get_delete_doc_link', $delete_link, $doc_permalink); }