Esempio n. 1
0
/**
 * Sends a notification email.
 *
 * @param string $type The type of notification to send
 * @param stdObj $post WP Post object
 * @param stdObj $comment WP Comment object
 * @param array $recipients Array of email addresses to send the notification to. This will merge with predetermined values.
 * @param mixed $single_user (id or WP User Object) User in which the notification directly refers to such as the User which was added as a reviewer.
 * @param $data array of supporting data for notifications
 * @return bool true if mail sent successfully, false otherwise.
 */
function annowf_send_notification($type, $post = null, $comment = null, $recipients = null, $single_user = null, $data = false)
{
    // Ensure that workflow notifications are enabled. This is also enforced prior to calls to annowf_send_notification
    if (!anno_workflow_enabled('notifications')) {
        return false;
    } else {
        if (empty($type)) {
            return false;
        }
    }
    $notification = annowf_notification_message($type, $post, $comment, $single_user, $data);
    if (is_null($recipients) || !is_array($recipients)) {
        $recipients = annowf_notification_recipients($type, $post);
    } else {
        if (is_array($recipients)) {
            $recipients = array_merge($recipients, annowf_notification_recipients($type, $post));
        }
    }
    $recipients = apply_filters('annowf_notification_recipients', array_unique($recipients), $type, $post);
    // Sitewide admin should never recieve any workflow notifications.
    $admin_email = get_option('admin_email');
    if ($key = array_search($admin_email, $recipients)) {
        unset($recipients[$key]);
    }
    $headers = array('BCC: ' . implode(', ', array_unique($recipients)));
    return @wp_mail(null, $notification['subject'], $notification['body'], $headers);
}
Esempio n. 2
0
/**
 * Register article post type
 */
function anno_register_post_types()
{
    if (anno_workflow_enabled()) {
        $capability_type = array('article', 'articles');
    } else {
        $capability_type = 'post';
    }
    $labels = array('name' => _x('Articles', 'post type name', 'anno'), 'singular_name' => _x('Article', 'post type singular name', 'anno'), 'add_new_item' => _x('Add New Article', 'post type plural name', 'anno'), 'edit_item' => _x('Edit Article', 'post type label', 'anno'), 'new_item' => _x('New Article', 'post type label', 'anno'), 'view_item' => _x('View Article', 'post type label', 'anno'), 'search_items' => _x('Search Articles', 'post type label', 'anno'), 'not_found' => _x('No Articles found', 'post type label', 'anno'), 'not_found_in_trash' => _x('No Articles found in Trash', 'post type label', 'anno'), 'menu_name' => _x('Articles', 'post type label, noun', 'anno'));
    $args = array('labels' => $labels, 'public' => true, 'show_ui' => true, 'has_archive' => true, 'hierarchical' => false, 'rewrite' => true, 'query_var' => 'articles', 'supports' => array('title', 'thumbnail', 'comments', 'revisions', 'author'), 'taxonomies' => array(), 'menu_position' => 5, 'capability_type' => $capability_type, 'menu_icon' => 'dashicons-welcome-write-blog');
    register_post_type('article', $args);
}
function annowf_setup()
{
    if (anno_workflow_enabled()) {
        // Used in generating save buttons and proccess state changes
        global $anno_post_save;
        $anno_post_save = array('approve' => _x('Approve', 'Publishing box action button text', 'anno'), 'publish' => _x('Publish', 'Publishing box action button text', 'anno'), 'reject' => _x('Reject', 'Publishing box action button text', 'anno'), 'review' => _x('Submit For Review', 'Publishing box action button text', 'anno'), 'revisions' => _x('Request Revisions', 'Publishing box action button text', 'anno'), 'clone' => _x('Clone', 'Publishing box action button text', 'anno'), 'revert' => _x('Revert To Draft', 'Publishing box action button text', 'anno'));
        include_once ANNO_PLUGIN_PATH . '/workflow/users.php';
        include_once ANNO_PLUGIN_PATH . '/workflow/workflow.php';
        include_once ANNO_PLUGIN_PATH . '/workflow/audit.php';
        include_once ANNO_PLUGIN_PATH . '/workflow/internal-comments/internal-comments.php';
        include_once ANNO_PLUGIN_PATH . '/workflow/publishing-meta-box.php';
        include_once ANNO_PLUGIN_PATH . '/workflow/notification.php';
    }
}
Esempio n. 4
0
/**
 * Handles AJAX request for adding a co-author to a post.
 */
function annowf_add_co_author()
{
    $response = annowf_add_user('co_author');
    if ($response['message'] == 'success') {
        // Used for quick access when filtering posts on a post-author page
        $post_id = absint($_POST['post_id']);
        // Send email
        if (anno_workflow_enabled('notifications')) {
            $post = get_post($post_id);
            annowf_send_notification('co_author_added', $post, '', array($response['user']->user_email), $response['user']);
        }
        // Add author to JSON for appending to author dropdown
        $response['author'] = '<option value="' . $response['user']->ID . '">' . $response['user']->user_login . '</option>';
        //Add to the audit log
        $current_user = wp_get_current_user();
        annowf_save_audit_item($post_id, $current_user->ID, 6, array($response['user']->ID));
    }
    unset($response['user']);
    echo json_encode($response);
    die;
}
Esempio n. 5
0
/**
 * Determines whether or not a user has the given abilities for a given post
 *
 * @param string $cap The capability to check
 * @param int $user_id The user id to check for a capability. Defaults to current user (global)
 * @param int $post_id The ID of the post to check Defaults to current post (global)
 * @param int $comment_id the ID of the comment to check
 * @return bool True if user has the given capability for the given post
 */
function anno_user_can($cap, $user_id = null, $post_id = null, $comment_id = null)
{
    if (is_null($user_id)) {
        $current_user = wp_get_current_user();
        $user_id = $current_user->ID;
    }
    if (is_null($post_id)) {
        $post_id = anno_get_post_id();
    }
    if (!empty($_GET['revision'])) {
        $revision = get_post($_GET['revision']);
        $post_id = $revision->post_parent;
    }
    $post_state = annowf_get_post_state($post_id);
    $user_role = anno_role($user_id, $post_id);
    // Number of times this item has gone back to draft state.
    $post_round = get_post_meta($post_id, '_round', true);
    // WP role names
    $admin = 'administrator';
    $editor = 'editor';
    switch ($cap) {
        case 'administrator':
        case 'admin':
            if ($user_role == $admin) {
                return true;
            }
            break;
        case 'editor':
        case 'view_audit':
            if (in_array($user_role, array($admin, $editor))) {
                return true;
            }
            break;
        case 'trash_post':
            // Draft state, author or editor+
            if (in_array($user_role, array($admin, $editor))) {
                return true;
            } else {
                if ($post_round < 1 && $post_state == 'draft' && $user_role == 'author') {
                    return true;
                }
            }
            break;
        case 'view_post':
            // Published post state, or user is associated with the post
            if ($post_state == 'published' || $user_role) {
                return true;
            }
            break;
        case 'edit_slug':
            if ($user_role == $admin) {
                return true;
            }
            if ($user_role == $editor && $post_state == 'draft') {
                return true;
            }
            break;
        case 'edit_post':
            global $pagenow;
            // Allow edits for things such as typos (in any state)
            if ($user_role == $admin) {
                return true;
            } else {
                if ($user_role == $editor && $post_state && !in_array($post_state, array('published', 'rejected'))) {
                    return true;
                } else {
                    if (($user_role == 'author' || $user_role == 'co-author') && $post_state == 'draft') {
                        return true;
                    } else {
                        if ($pagenow == 'post-new.php') {
                            return true;
                        }
                    }
                }
            }
            break;
        case 'leave_review':
            // Only reviewers, and in_review state
            $reviewers = anno_get_reviewers($post_id);
            if (in_array($user_id, $reviewers) && $post_state == 'in_review') {
                return true;
            }
            break;
        case 'edit_comment':
            $comment = get_comment($comment_id);
            if ($user_role && in_array($user_role, array($editor, $admin)) || $user_id == $comment->user_id) {
                return true;
            }
            break;
        case 'add_general_comment':
            // Anyone who isn't a reviewer, attached to the post and not in published state
            if ($user_role && $user_role != 'reviewer') {
                return true;
            }
            break;
        case 'view_general_comment':
        case 'view_general_comments':
            if ($user_role) {
                return true;
            }
            break;
        case 'add_review_comment':
            // if user is reviewer or editor+ and state is in review
            if ($user_role && !in_array($user_role, array('author', 'co-author')) && $post_state == 'in_review') {
                return true;
            }
            break;
        case 'manage_co_authors':
            if ($user_role == $admin) {
                return true;
            } else {
                if ($user_role == $editor && $post_state && !in_array($post_state, array('published', 'rejected'))) {
                    return true;
                } else {
                    if ($user_role == 'author' && $post_state == 'draft') {
                        return true;
                    }
                }
            }
            break;
        case 'manage_public_comments':
            if (in_array($user_role, array($admin, $editor))) {
                return true;
            }
            break;
        case 'view_review_comment':
            // if user is or editor+
            if (in_array($user_role, array($admin, $editor))) {
                return true;
            }
            // if user is reviewer and comment author = reviewer
            $comment = anno_internal_comments_get_comment_root($comment_id);
            if ($user_role == 'reviewer' && $comment && $comment->user_id == $user_id) {
                return true;
            }
            break;
        case 'view_reviewers':
        case 'view_review_comments':
            //Reviewer or editor+
            if ($user_role && !in_array($user_role, array('author', 'co-author'))) {
                return true;
            } else {
                if ($user_role == 'author' && anno_workflow_enabled('author_reviewer')) {
                    return true;
                }
            }
            break;
        case 'manage_reviewers':
            // if in review state and user is editor+
            if (in_array($user_role, array($admin, $editor)) && in_array($post_state, array('submitted', 'in_review'))) {
                return true;
            }
            break;
        case 'alter_post_state':
            switch ($post_state) {
                case 'draft':
                    // If not reviewer, and in draft state
                    if ($user_role && !in_array($user_role, array('reviewer', 'co-author')) && $post_state == 'draft') {
                        return true;
                    }
                    break;
                case 'submitted':
                case 'in_review':
                    // Revert to draft
                // Revert to draft
                case 'rejected':
                    // Must be an editor+
                    if (in_array($user_role, array($admin, $editor))) {
                        return true;
                    }
                    break;
                    // Must be a part of the publishing staff
                // Must be a part of the publishing staff
                case 'approved':
                    if ($user_role == $admin) {
                        return true;
                    }
                    break;
                case 'published':
                    // No one can change a published article's status
                    return false;
                    break;
                default:
                    break;
            }
            break;
        case 'clone_post':
            // Anyone can clone the post when its published
            if ($post_state == 'published' || $post_state == 'rejected') {
                return true;
            }
            break;
        case 'select_author':
            if ($user_role == $admin) {
                return true;
            } else {
                if ($user_role == $editor && !in_array($post_state, array('published', 'rejected'))) {
                    return true;
                } else {
                    if ($user_role == 'author' && $post_state == 'draft') {
                        return true;
                    }
                }
            }
        default:
            break;
    }
    // if we haven't returned, assume false
    return false;
}
Esempio n. 6
0
/**
 * Determines whether or not a user can edit, based on the workflow being active or not
 */
function anno_current_user_can_edit()
{
    // User must have the WP permissions
    if (current_user_can('edit_article')) {
        $post_id = null;
        if (isset($_POST['attachment_id'])) {
            $post = get_post($_POST['attachment_id']);
            $post_id = $post->post_parent;
        }
        // Do an additional check if the workflow is enabled
        if (anno_workflow_enabled()) {
            if (anno_user_can('edit_post', null, $post_id)) {
                return true;
            } else {
                return false;
            }
        }
        return true;
    }
    return false;
}
Esempio n. 7
0
    /**
     * Generate the Front portion of an article XML
     *
     * @param postObject $article Article to generate the XML for.
     * @return string XML generated
     */
    private function xml_front($article)
    {
        // Journal Title
        $journal_title = cfct_get_option('journal_name');
        if (!empty($journal_title)) {
            $journal_title_xml = '<journal-title-group>
					<journal-title>' . esc_html($journal_title) . '</journal-title>
				</journal-title-group>';
        } else {
            $journal_title_xml = '';
        }
        // Journal ID
        $journal_id = cfct_get_option('journal_id');
        if (!empty($journal_id)) {
            $journal_id_type = cfct_get_option('journal_id_type');
            if (!empty($journal_id_type)) {
                $journal_id_type_xml = ' journal-id-type="' . esc_attr($journal_id_type) . '"';
            } else {
                $journal_id_type_xml = '';
            }
            $journal_id_xml = '<journal-id' . $journal_id_type_xml . '>' . esc_html($journal_id) . '</journal-id>';
        } else {
            $journal_id_xml = '';
        }
        // Publisher ISSN
        $pub_issn = cfct_get_option('publisher_issn');
        if (!empty($pub_issn)) {
            $pub_issn_xml = '<issn pub-type="epub">' . esc_html($pub_issn) . '</issn>';
        } else {
            $pub_issn_xml = '';
        }
        // Abstract
        $abstract = $article->post_excerpt;
        if (!empty($abstract)) {
            $abstract_xml = '
			<abstract>' . $abstract . '</abstract>';
        } else {
            $abstract_xml = '';
        }
        // Funding Statement
        $funding = get_post_meta($article->ID, '_anno_funding', true);
        if (!empty($funding)) {
            $funding_xml = '<funding-group>
					<funding-statement>' . esc_html($funding) . '</funding-statement>
			</funding-group>';
        } else {
            $funding_xml = '';
        }
        // DOI
        $doi = get_post_meta($article->ID, '_anno_doi', true);
        if (!empty($doi)) {
            $doi_xml = '<article-id pub-id-type="doi">' . esc_html($doi) . '</article-id>';
        } else {
            $doi_xml = '';
        }
        // Article category. Theoretically, there can only be one!
        $cats = wp_get_object_terms($article->ID, 'article_category');
        if (!empty($cats) && is_array($cats)) {
            $category = get_category($cats[0]);
            if (!empty($category)) {
                $category_xml = '<article-categories>
				<subj-group>
					<subject>' . esc_html($category->name) . '</subject>
				</subj-group>
			</article-categories>';
            } else {
                $category_xml = '';
            }
        } else {
            $category_xml = '';
        }
        // Article Tags
        $tags = wp_get_object_terms($article->ID, 'article_tag');
        if (!empty($tags) && is_array($tags)) {
            $tag_xml = '<kwd-group kwd-group-type="simple">';
            foreach ($tags as $tag) {
                $tag = get_term($tag, 'article_tag');
                $tag_xml .= '<kwd>' . esc_html($tag->name) . '</kwd>';
            }
            $tag_xml .= '
			</kwd-group>';
        } else {
            $tag_xml = '';
        }
        // Article title/subtitle
        $subtitle = get_post_meta($article->ID, '_anno_subtitle', true);
        $title_xml = '<title-group>';
        if (!empty($article->post_title) || !empty($subtitle)) {
            $title_xml = '<title-group>';
            if (!empty($article->post_title)) {
                $title_xml .= '
				<article-title>' . esc_html($article->post_title) . '</article-title>';
            } else {
                $title_xml .= '
				<article-title />';
            }
            if (!empty($subtitle)) {
                $title_xml .= '
				<subtitle>' . esc_html($subtitle) . '</subtitle>';
            }
        }
        $title_xml .= '
			</title-group>';
        // Publisher info
        $pub_name = cfct_get_option('publisher_name');
        $pub_loc = cfct_get_option('publisher_location');
        if (!empty($pub_name) || !empty($pub_loc)) {
            $publisher_xml = '<publisher>';
            if (!empty($pub_name)) {
                $publisher_xml .= '
				<publisher-name>' . esc_html($pub_name) . '</publisher-name>';
            }
            if (!empty($pub_loc)) {
                $publisher_xml .= '
				<publisher-loc>' . esc_html($pub_loc) . '</publisher-loc>';
            }
            $publisher_xml .= '
					</publisher>';
        } else {
            $publisher_xml = '';
        }
        $pub_date_xml = $this->xml_pubdate($article->post_date);
        // Authors
        $authors = get_post_meta($article->ID, '_anno_author_snapshot', true);
        if (!empty($authors) && is_array($authors)) {
            $author_xml = '<contrib-group>';
            foreach ($authors as $author) {
                $author_xml .= '
				<contrib>';
                if (isset($author['surname']) && !empty($author['surname']) || isset($author['given_names']) && !empty($author['given_names']) || isset($author['prefix']) && !empty($author['prefix']) || isset($author['suffix']) && !empty($author['suffix'])) {
                    $author_xml .= '
					<name>';
                    if (isset($author['surname']) && !empty($author['surname'])) {
                        $author_xml .= '
						<surname>' . esc_html($author['surname']) . '</surname>';
                    }
                    if (isset($author['given_names']) && !empty($author['given_names'])) {
                        $author_xml .= '
						<given-names>' . esc_html($author['given_names']) . '</given-names>';
                    }
                    if (isset($author['prefix']) && !empty($author['prefix'])) {
                        $author_xml .= '
						<prefix>' . esc_html($author['prefix']) . '</prefix>';
                    }
                    if (isset($author['suffix']) && !empty($author['suffix'])) {
                        $author_xml .= '
						<suffix>' . esc_html($author['suffix']) . '</suffix>';
                    }
                    $author_xml .= '
					</name>';
                }
                // Affiliation legacy support
                if (!empty($author['affiliation']) || !empty($author['institution'])) {
                    $author_xml .= '
							<aff>';
                    if (!empty($author['affiliation'])) {
                        $author_xml .= esc_html($author['affiliation']);
                    }
                    if (!empty($author['institution'])) {
                        $author_xml .= '<institution>' . esc_html($author['institution']) . '</institution>';
                    }
                    $author_xml .= '</aff>';
                }
                if (isset($author['bio']) && !empty($author['bio'])) {
                    $author_xml .= '
						<bio><p>' . esc_html($author['bio']) . '</p></bio>';
                }
                if (isset($author['link']) && !empty($author['link'])) {
                    $author_xml .= '
						<ext-link ext-link-type="uri" xlink:href="' . esc_url($author['link']) . '">' . esc_html($author['link']) . '</ext-link>';
                }
                $author_xml .= '
				</contrib>';
            }
            $author_xml .= '
			</contrib-group>';
        }
        // Related Articles
        $related_xml = '';
        if (anno_workflow_enabled()) {
            $related_articles = annowf_clone_get_ancestors($article->ID);
        }
        if (!empty($related_articles) && is_array($related_articles)) {
            foreach ($related_articles as $related_article_id) {
                $related_article = get_post($related_article_id);
                if (!empty($related_article) && $related_article->post_status == 'publish') {
                    $related_xml .= '<related-article id="' . esc_attr('a' . $related_article->ID) . '" related-article-type="companion" ext-link-type="uri" xlink:href="' . esc_attr(get_permalink($related_article_id)) . '" ';
                    $related_doi = get_post_meta($related_article_id, '_anno_doi', true);
                    if (!empty($related_doi)) {
                        $related_xml .= 'elocation-id="' . esc_attr($related_doi) . '" ';
                    }
                    // Queried for above
                    if (!empty($journal_id)) {
                        $related_xml .= 'journal_id="' . esc_attr($journal_id) . '" ';
                    }
                    // Queried for above
                    if (!empty($journal_id_type)) {
                        $related_xml .= 'journal_id_type="' . esc_attr($journal_id_type) . '" ';
                    }
                    $related_xml .= ' />';
                }
            }
        }
        return '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD Journal Publishing DTD v3.0 20080202//EN" "journalpublishing3.dtd">
<article article-type="research-article" xml:lang="en" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<?origin annotum?>
	<front>
		<journal-meta>
			' . $journal_id_xml . '
			' . $journal_title_xml . '
			' . $pub_issn_xml . '
			' . $publisher_xml . '
		</journal-meta>
		<article-meta>
			' . $doi_xml . '
			' . $category_xml . '
			' . $title_xml . '
			' . $author_xml . '
			' . $pub_date_xml . '			' . $abstract_xml . '
			' . $tag_xml . '
			' . $funding_xml . '
			' . $related_xml . '
		</article-meta>
	</front>';
    }
/**
 * Enforce general comment capabilities
 */
function anno_internal_comments_capabilities($allcaps, $caps, $args)
{
    // $args are an array => 'capability_name' , 'user_id', 'additional args (obj id)'
    if ($args[0] == 'edit_comment') {
        $comment = get_comment($args[2]);
        if (!empty($comment) && ($comment->comment_type == 'article_general' || $comment->comment_type == 'article_review')) {
            if (anno_workflow_enabled()) {
                if (!anno_user_can('edit_comment', $args[1], '', $args[2])) {
                    $allcaps = array();
                }
            } else {
                $allcaps = array();
            }
        }
    }
    return $allcaps;
}
Esempio n. 9
0
function anno_validate_on_save($post_id, $post)
{
    remove_action('save_post_article', 'anno_validate_on_save', 999, 2);
    $error = false;
    $schema = trailingslashit(get_template_directory()) . 'functions/schema/kipling-jp3-partial.rng';
    $body_content = anno_validation_prep_body($post->post_content_filtered, $post_id);
    $body_validation = anno_validate($body_content, $schema);
    $abstract_content = anno_validation_prep_abstract($post->post_excerpt);
    $abstract_validation = anno_validate($abstract_content, $schema);
    if (isset($body_validation['status']) && $body_validation['status'] == 'error') {
        $error = true;
    }
    if (isset($abstract_validation['status']) && $abstract_validation['status'] == 'error') {
        $error = true;
    }
    if ($error && $post->post_status == 'publish') {
        $post->post_status = 'draft';
        if (anno_workflow_enabled()) {
            $status = 'pending';
            update_post_meta($post_id, '_post_state', 'approved');
        } else {
            $status = 'draft';
        }
        add_filter('redirect_post_location', 'anno_validation_redirect_post_location_message');
        remove_action('post_updated', 'annowf_transistion_state', 10, 3);
        remove_action('add_post_meta', 'anno_save_appendices_xml_as_html', 10, 3);
        remove_filter('wp_insert_post_data', 'anno_insert_post_data', null, 2);
        remove_filter('wp_insert_post_data', 'annowf_insert_post_data', 10, 2);
        wp_update_post(array('ID' => $post_id, 'post_status' => 'draft'));
    }
}