Beispiel #1
0
/**
 * Conditional tag to check if a user can view a specific post.  A user cannot view a post if their
 * user role has not been selected in the 'Content Permissions' meta box on the edit post screen in
 * the admin.  Non-logged in site visitors cannot view posts if roles were selected.  If no roles
 * were selected, all users and site visitors can view the content.
 *
 * There are exceptions to this rule though.  The post author, any user with the `restrict_content`
 * capability, and users that have the ability to edit the post can always view the post, even if
 * their role was not granted permission to view it.
 *
 * @since  0.2.0
 * @access public
 * @param  int     $user_id
 * @param  int     $post_id
 * @return bool
 */
function members_can_user_view_post($user_id, $post_id = '')
{
    // If no post ID is given, assume we're in The Loop and get the current post's ID.
    if (!$post_id) {
        $post_id = get_the_ID();
    }
    // Assume the user can view the post at this point. */
    $can_view = true;
    // The plugin is only going to handle permissions if the 'content permissions' feature
    // is active.  If not active, the user can always view the post.  However, developers
    // can roll their own handling of this and filter `members_can_user_view_post`.
    if (members_content_permissions_enabled()) {
        // Get the roles selected by the user.
        $roles = members_get_post_roles($post_id);
        // Check if there are any old roles with the '_role' meta key.
        if (empty($roles)) {
            $roles = members_convert_old_post_meta($post_id);
        }
        // If we have an array of roles, let's get to work.
        if (!empty($roles) && is_array($roles)) {
            // Since specific roles were given, let's assume the user can't view
            // the post at this point.  The rest of this functionality should try
            // to disprove this.
            $can_view = false;
            // Get the post object.
            $post = get_post($post_id);
            // Get the post type object.
            $post_type = get_post_type_object($post->post_type);
            // If viewing a feed or if the user's not logged in, assume it's blocked at this point.
            if (is_feed() || !is_user_logged_in()) {
                $can_view = false;
            } elseif ($post->post_author == $user_id || user_can($user_id, 'restrict_content') || user_can($user_id, $post_type->cap->edit_post, $post_id)) {
                $can_view = true;
            } else {
                // Loop through each role and set $can_view to true if the user has one of the roles.
                foreach ($roles as $role) {
                    if (members_user_has_role($user_id, $role)) {
                        $can_view = true;
                        break;
                    }
                }
            }
        }
    }
    // Set the check for the parent post based on whether we have permissions for this post.
    $check_parent = empty($roles) && $can_view;
    // Set to `FALSE` to avoid hierarchical checking.
    if (apply_filters('members_check_parent_post_permission', $check_parent, $post_id, $user_id)) {
        $parent_id = get_post($post_id)->post_parent;
        // If the post has a parent, check if the user has permission to view it.
        if (0 < $parent_id) {
            $can_view = members_can_user_view_post($user_id, $parent_id);
        }
    }
    // Allow developers to overwrite the final return value.
    return apply_filters('members_can_user_view_post', $can_view, $user_id, $post_id);
}
Beispiel #2
0
/**
 * Conditional tag to check if a user can view a specific post.  A user cannot view a post if their user role has 
 * not been selected in the 'Content Permissions' meta box on the edit post screen in the admin.  Non-logged in 
 * site visitors cannot view posts if roles were seletected.  If no roles were selected, all users and site visitors 
 * can view the content.
 *
 * There are exceptions to this rule though.  The post author, any user with the 'restrict_content' capability, 
 * and users that have the ability to edit the post can always view the post, even if their role was not granted 
 * permission to view it.
 *
 * @todo See how feasible it is to just use the normal user_can() NXTClass function to check against a meta 
 * capability such as 'members_view_post' while hooking into 'map_meta_cap' or 'user_has_cap' to roll custom 
 * plugin handling for this. This would just be a wrapper tag.
 *
 * @since 0.2.0
 * @param int $user_id The ID of the user to check.
 * @param int $post_id The ID of the post to check.
 * @return bool True if the user can view the post. False if the user cannot view the post.
 */
function members_can_user_view_post($user_id, $post_id = '')
{
    /* If no post ID is given, assume we're in The Loop and get the current post's ID. */
    if (empty($post_id)) {
        $post_id = get_the_ID();
    }
    /* Assume the user can view the post at this point. */
    $can_view = true;
    /**
     * The plugin is only going to handle permissions if the 'content permissions' feature is active.  If 
     * not active, the user can always view the post.  However, developers can roll their own handling of
     * this and filter 'members_can_user_view_post'.
     */
    if (members_get_setting('content_permissions')) {
        /* Get the roles selected by the user. */
        $roles = get_post_meta($post_id, '_members_access_role', false);
        /* Check if there are any old roles with the '_role' meta key. */
        if (empty($roles)) {
            $roles = members_convert_old_post_meta($post_id);
        }
        /* If we have an array of roles, let's get to work. */
        if (!empty($roles) && is_array($roles)) {
            /**
             * Since specific roles were given, let's assume the user can't view the post at 
             * this point.  The rest of this functionality should try to disprove this.
             */
            $can_view = false;
            /* Get the post object. */
            $post = get_post($post_id);
            /* Get the post type object. */
            $post_type = get_post_type_object($post->post_type);
            /* If viewing a feed or if the user's not logged in, assume it's blocked at this point. */
            if (is_feed() || !is_user_logged_in()) {
                $can_view = false;
            } elseif ($post->post_author == $user_id || user_can($user_id, 'restrict_content') || user_can($user_id, $post_type->cap->edit_post, $post_id)) {
                $can_view = true;
            } else {
                /* Loop through each role and set $can_view to true if the user has one of the roles. */
                foreach ($roles as $role) {
                    if (user_can($user_id, $role)) {
                        $can_view = true;
                    }
                }
            }
        }
    }
    /* Allow developers to overwrite the final return value. */
    return apply_filters('members_can_user_view_post', $can_view, $user_id, $post_id);
}
    /**
     * Outputs the meta box HTML.
     *
     * @since  1.0.0
     * @access public
     * @param  object  $post
     * @global object  $wp_roles
     * @return void
     */
    public function meta_box($post)
    {
        global $wp_roles;
        // Get roles and sort.
        $_wp_roles = $wp_roles->role_names;
        asort($_wp_roles);
        // Get the roles saved for the post.
        $roles = get_post_meta($post->ID, '_members_access_role', false);
        // Convert old post meta to the new system if no roles were found.
        if (empty($roles)) {
            $roles = members_convert_old_post_meta($post->ID);
        }
        wp_nonce_field('members_cp_meta_nonce', 'members_cp_meta');
        ?>

		<p>
			<?php 
        esc_html_e("Limit access to this post's content to users of the selected roles.", 'members');
        ?>
		</p>

		<div class="members-cp-role-list-wrap">

			<ul class="members-cp-role-list">

			<?php 
        foreach ($_wp_roles as $role => $name) {
            ?>
				<li>
					<label>
						<input type="checkbox" name="members_access_role[]" <?php 
            checked(is_array($roles) && in_array($role, $roles));
            ?>
 value="<?php 
            echo esc_attr($role);
            ?>
" />
						<?php 
            echo esc_html(translate_user_role($name));
            ?>
					</label>
				</li>
			<?php 
        }
        ?>

			</ul>
		</div>

		<p class="howto">
			<?php 
        printf(esc_html__('If no roles are selected, everyone can view the content. The post author, any users who can edit this post, and users with the %s capability can view the content regardless of role.', 'members'), '<code>restrict_content</code>');
        ?>
		</p>

		<p>
			<label for="members_access_error"><?php 
        esc_html_e('Custom error messsage:', 'members');
        ?>
</label>
			<textarea class="widefat" id="members_access_error" name="members_access_error" rows="6"><?php 
        echo esc_textarea(get_post_meta($post->ID, '_members_access_error', true));
        ?>
</textarea>
			<span class="howto"><?php 
        _e('Message shown to users that do no have permission to view the post.', 'members');
        ?>
</span>
		</p>
	<?php 
    }
/**
 * @since 0.1.0
 */
function members_content_permissions_meta_box($object, $box)
{
    global $wp_roles;
    /* Get the roles saved for the post. */
    $roles = get_post_meta($object->ID, '_members_access_role', false);
    /* Convert old post meta to the new system if no roles were found. */
    if (empty($roles)) {
        $roles = members_convert_old_post_meta($object->ID);
    }
    ?>

	<input type="hidden" name="content_permissions_meta_nonce" value="<?php 
    echo wp_create_nonce(plugin_basename(__FILE__));
    ?>
" />

	<div style="overflow: hidden; margin-left: 5px;">

		<p>
		<?php 
    _e("Limit access to this post's content to users of the selected roles.", 'members');
    ?>
		</p>

		<?php 
    /* Loop through each of the available roles. */
    foreach ($wp_roles->role_names as $role => $name) {
        $checked = false;
        /* If the role has been selected, make sure it's checked. */
        if (is_array($roles) && in_array($role, $roles)) {
            $checked = ' checked="checked" ';
        }
        ?>

			<div style="width: 32%; float: left; margin: 0 0 5px 0;">
				<label for="members_access_role-<?php 
        echo $role;
        ?>
">
					<input type="checkbox" name="members_access_role[<?php 
        echo $role;
        ?>
]" id="members_access_role-<?php 
        echo $role;
        ?>
" <?php 
        echo $checked;
        ?>
 value="<?php 
        echo $role;
        ?>
" /> 
					<?php 
        echo esc_html($name);
        ?>
				</label>
			</div>
		<?php 
    }
    ?>

	</div>

	<p style="clear: left;">
		<span class="howto"><?php 
    printf(__('If no roles are selected, everyone can view the content. The post author, any users who can edit this post, and users with the %s capability can view the content regardless of role.', 'members'), '<code>restrict_content</code>');
    ?>
</span>
	</p>

	<p>
		<label for="members_access_error"><?php 
    _e('Custom error messsage:', 'members');
    ?>
</label>
		<textarea id="members_access_error" name="members_access_error" cols="60" rows="2" tabindex="30" style="width: 99%;"><?php 
    echo esc_html(get_post_meta($object->ID, '_members_access_error', true));
    ?>
</textarea>
		<br />
		<span class="howto"><?php 
    _e('Message shown to users that do no have permission to view the post.', 'members');
    ?>
</span>
	</p>

<?php 
}