am string $cap Capability name. */ function remove_cap( $cap ) { global $wp_roles; if ( ! isset( $wp_roles ) ) $wp_roles = new WP_Roles(); unset( $this->capabilities[$cap] ); $wp_roles->remove_cap( $this->name, $cap ); } /** * Whether role has capability. * * The capabilities is passed through the 'role_has_cap' filter. The first * parameter for the hook is the list of capabilities the class has * assigned. The second parameter is the capability name to look for. The * third and final parameter for the hook is the role name. * * @since 2.0.0 * @access public * * @param string $cap Capability name. * @return bool True, if user has capability. False, if doesn't have capability. */ function has_cap( $cap ) { $capabilities = apply_filters( 'role_has_cap', $this->capabilities, $cap, $this->name ); if ( !empty( $capabilities[$cap] ) ) return $capabilities[$cap]; else return false; } } /** * WordPress User class. * * @since 2.0.0 * @package WordPress * @subpackage User */ class WP_User { /** * User data container. * * This will be set as properties of the object. * * @since 2.0.0 * @access private * @var array */ var $data; /** * The user's ID. * * @since 2.1.0 * @access public * @var int */ var $ID = 0; /** * The deprecated user's ID. * * @since 2.0.0 * @access public * @deprecated Use WP_User::$ID * @see WP_User::$ID * @var int */ var $id = 0; /** * The individual capabilities the user has been given. * * @since 2.0.0 * @access public * @var array */ var $caps = array(); /** * User metadata option name. * * @since 2.0.0 * @access public * @var string */ var $cap_key; /** * The roles the user is part of. * * @since 2.0.0 * @access public * @var array */ var $roles = array(); /** * All capabilities the user has, including individual and role based. * * @since 2.0.0 * @access public * @var array */ var $allcaps = array(); /** * First name of the user. * * Created to prevent notices. * * @since 2.7.0 * @access public * @var string */ var $first_name = ''; /** * Last name of the user. * * Created to prevent notices. * * @since 2.7.0 * @access public * @var string */ var $last_name = ''; /** * The filter context applied to user data fields. * * @since 2.9.0 * @access private * @var string */ var $filter = null; /** * PHP4 Constructor - Sets up the object properties. * * Retrieves the userdata and then assigns all of the data keys to direct * properties of the object. Calls {@link WP_User::_init_caps()} after * setting up the object's user data properties. * * @since 2.0.0 * @access public * * @param int|string $id User's ID or username * @param int $name Optional. User's username * @return WP_User */ function WP_User( $id, $name = '' ) { if ( empty( $id ) && empty( $name ) ) return; if ( ! is_numeric( $id ) ) { $name = $id; $id = 0; } if ( ! empty( $id ) ) $this->data = get_userdata( $id ); else $this->data = get_userdatabylogin( $name ); if ( empty( $this->data->ID ) ) return; foreach ( get_object_vars( $this->data ) as $key => $value ) { $this->{$key} = $value; } $this->id = $this->ID; $this->_init_caps(); } /** * Set up capability object properties. * * Will set the value for the 'cap_key' property to current database table * prefix, followed by 'capabilities'. Will then check to see if the * property matching the 'cap_key' exists and is an array. If so, it will be * used. * * @since 2.1.0 * * @param string $cap_key Optional capability key * @access protected */ function _init_caps( $cap_key = '' ) { global $wpdb; if ( empty($cap_key) ) $this->cap_key = $wpdb->prefix . 'capabilities'; else $this->cap_key = $cap_key; $this->caps = &$this->{$this->cap_key}; if ( ! is_array( $this->caps ) ) $this->caps = array(); $this->get_role_caps(); } /** * Retrieve all of the role capabilities and merge with individual capabilities. * * All of the capabilities of the roles the user belongs to are merged with * the users individual roles. This also means that the user can be denied * specific roles that their role might have, but the specific user isn't * granted permission to. * * @since 2.0.0 * @uses $wp_roles * @access public */ function get_role_caps() { global $wp_roles; if ( ! isset( $wp_roles ) ) $wp_roles = new WP_Roles(); //Filter out caps that are not role names and assign to $this->roles if ( is_array( $this->caps ) ) $this->roles = array_filter( array_keys( $this->caps ), array( &$wp_roles, 'is_role' ) ); //Build $allcaps from role caps, overlay user's $caps $this->allcaps = array(); foreach ( (array) $this->roles as $role ) { $the_role =& $wp_roles->get_role( $role ); $this->allcaps = array_merge( (array) $this->allcaps, (array) $the_role->capabilities ); } $this->allcaps = array_merge( (array) $this->allcaps, (array) $this->caps ); } /** * Add role to user. * * Updates the user's meta data option with capabilities and roles. * * @since 2.0.0 * @access public * * @param string $role Role name. */ function add_role( $role ) { $this->caps[$role] = true; update_user_meta( $this->ID, $this->cap_key, $this->caps ); $this->get_role_caps(); $this->update_user_level_from_caps(); } /** * Remove role from user. * * @since 2.0.0 * @access public * * @param string $role Role name. */ function remove_role( $role ) { if ( !in_array($role, $this->roles) ) return; unset( $this->caps[$role] ); update_user_meta( $this->ID, $this->cap_key, $this->caps ); $this->get_role_caps(); $this->update_user_level_from_caps(); } /** * Set the role of the user. * * This will remove the previous roles of the user and assign the user the * new one. You can set the role to an empty string and it will remove all * of the roles from the user. * * @since 2.0.0 * @access public * * @param string $role Role name. */ function set_role( $role ) { foreach ( (array) $this->roles as $oldrole ) unset( $this->caps[$oldrole] ); if ( !empty( $role ) ) { $this->caps[$role] = true; $this->roles = array( $role => true ); } else { $this->roles = false; } update_user_meta( $this->ID, $this->cap_key, $this->caps ); $this->get_role_caps(); $this->update_user_level_from_caps(); do_action( 'set_user_role', $this->ID, $role ); } /** * Choose the maximum level the user has. * * Will compare the level from the $item parameter against the $max * parameter. If the item is incorrect, then just the $max parameter value * will be returned. * * Used to get the max level based on the capabilities the user has. This * is also based on roles, so if the user is assigned the Administrator role * then the capability 'level_10' will exist and the user will get that * value. * * @since 2.0.0 * @access public * * @param int $max Max level of user. * @param string $item Level capability name. * @return int Max Level. */ function level_reduction( $max, $item ) { if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) { $level = intval( $matches[1] ); return max( $max, $level ); } else { return $max; } } /** * Update the maximum user level for the user. * * Updates the 'user_level' user metadata (includes prefix that is the * database table prefix) with the maximum user level. Gets the value from * the all of the capabilities that the user has. * * @since 2.0.0 * @access public */ function update_user_level_from_caps() { global $wpdb; $this->user_level = array_reduce( array_keys( $this->allcaps ), array( &$this, 'level_reduction' ), 0 ); update_user_meta( $this->ID, $wpdb->prefix . 'user_level', $this->user_level ); } /** * Add capability and grant or deny access to capability. * * @since 2.0.0 * @access public * * @param string $cap Capability name. * @param bool $grant Whether to grant capability to user. */ function add_cap( $cap, $grant = true ) { $this->caps[$cap] = $grant; update_user_meta( $this->ID, $this->cap_key, $this->caps ); } /** * Remove capability from user. * * @since 2.0.0 * @access public * * @param string $cap Capability name. */ function remove_cap( $cap ) { if ( empty( $this->caps[$cap] ) ) return; unset( $this->caps[$cap] ); update_user_meta( $this->ID, $this->cap_key, $this->caps ); } /** * Remove all of the capabilities of the user. * * @since 2.1.0 * @access public */ function remove_all_caps() { global $wpdb; $this->caps = array(); delete_user_meta( $this->ID, $this->cap_key ); delete_user_meta( $this->ID, $wpdb->prefix . 'user_level' ); $this->get_role_caps(); } /** * Whether user has capability or role name. * * This is useful for looking up whether the user has a specific role * assigned to the user. The second optional parameter can also be used to * check for capabilities against a specfic post. * * @since 2.0.0 * @access public * * @param string|int $cap Capability or role name to search. * @param int $post_id Optional. Post ID to check capability against specific post. * @return bool True, if user has capability; false, if user does not have capability. */ function has_cap( $cap ) { if ( is_numeric( $cap ) ) { _deprecated_argument( __FUNCTION__, '2.0', __('Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead.') ); $cap = $this->translate_level_to_cap( $cap ); } $args = array_slice( func_get_args(), 1 ); $args = array_merge( array( $cap, $this->ID ), $args ); $caps = call_user_func_array( 'map_meta_cap', $args ); // Multisite super admin has all caps by definition, Unless specifically denied. if ( is_multisite() && is_super_admin() ) { if ( in_array('do_not_allow', $caps) ) return false; return true; } // Must have ALL requested caps $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args ); foreach ( (array) $caps as $cap ) { //echo "Checking cap $cap
"; if ( empty( $capabilities[$cap] ) || !$capabilities[$cap] ) return false; } return true; } /** * Convert numeric level to level capability name. * * Prepends 'level_' to level number. * * @since 2.0.0 * @access public * * @param int $level Level number, 1 to 10. * @return string */ function translate_level_to_cap( $level ) { return 'level_' . $level; } /** * Set the blog to operate on. Defaults to the current blog. * * @since 3.0.0 * * @param int $blog_id Optional Blog ID, defaults to current blog. */ function for_blog( $blog_id = '' ) { global $wpdb; if ( ! empty( $blog_id ) ) $cap_key = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; else $cap_key = ''; $this->_init_caps( $cap_key ); } } /** * Map meta capabilities to primitive capabilities. * * This does not actually compare whether the user ID has the actual capability, * just what the capability or capabilities are. Meta capability list value can * be 'delete_user', 'edit_user', 'remove_user', 'promote_user', 'delete_post', * 'delete_page', 'edit_post', 'edit_page', 'read_post', or 'read_page'. * * @since 2.0.0 * * @param string $cap Capability name. * @param int $user_id User ID. * @return array Actual capabilities for meta capability. */ function map_meta_cap( $cap, $user_id ) { $args = array_slice( func_get_args(), 2 ); $caps = array(); switch ( $cap ) { case 'remove_user': $caps[] = 'remove_users'; break; case 'delete_user': $caps[] = 'delete_users'; break; case 'promote_user': $caps[] = 'promote_users'; break; case 'edit_user': // Allow user to edit itself if ( isset( $args[0] ) && $user_id == $args[0] ) break; // Fall through case 'edit_users': // If multisite these caps are allowed only for super admins. if ( is_multisite() && !is_super_admin() ) $caps[] = 'do_not_allow'; else $caps[] = 'edit_users'; // Explicit due to primitive fall through break; case 'delete_post': $author_data = get_userdata( $user_id ); //echo "post ID: {$args[0]}
"; $post = get_post( $args[0] ); $post_type = get_post_type_object( $post->post_type ); if ( $post_type && 'post' != $post_type->capability_type ) { $args = array_merge( array( $post_type->cap->delete_post, $user_id ), $args ); return call_user_func_array( 'map_meta_cap', $args ); } if ( '' != $post->post_author ) { $post_author_data = get_userdata( $post->post_author ); } else { //No author set yet so default to current user for cap checks $post_author_data = $author_data; } // If the user is the author... if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) { // If the post is published... if ( 'publish' == $post->post_status ) { $caps[] = 'delete_published_posts'; } elseif ( 'trash' == $post->post_status ) { if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) ) $caps[] = 'delete_published_posts'; } else { // If the post is draft... $caps[] = 'delete_posts'; } } else { // The user is trying to edit someone else's post. $caps[] = 'delete_others_posts'; // The post is published, extra cap required. if ( 'publish' == $post->post_status ) $caps[] = 'delete_published_posts'; elseif ( 'private' == $post->post_status ) $caps[] = 'delete_private_posts'; } break; case 'delete_page': $author_data = get_userdata( $user_id ); //echo "post ID: {$args[0]}
"; $page = get_page( $args[0] ); $page_author_data = get_userdata( $page->post_author ); //echo "current user id : $user_id, page author id: " . $page_author_data->ID . "
"; // If the user is the author... if ('' != $page->post_author) { $page_author_data = get_userdata( $page->post_author ); } else { //No author set yet so default to current user for cap checks $page_author_data = $author_data; } if ( is_object( $page_author_data ) && $user_id == $page_author_data->ID ) { // If the page is published... if ( $page->post_status == 'publish' ) { $caps[] = 'delete_published_pages'; } elseif ( 'trash' == $page->post_status ) { if ('publish' == get_post_meta($page->ID, '_wp_trash_meta_status', true) ) $caps[] = 'delete_published_pages'; } else { // If the page is draft... $caps[] = 'delete_pages'; } } else { // The user is trying to edit someone else's page. $caps[] = 'delete_others_pages'; // The page is published, extra cap required. if ( $page->post_status == 'publish' ) $caps[] = 'delete_published_pages'; elseif ( $page->post_status == 'private' ) $caps[] = 'delete_private_pages'; } break; // edit_post breaks down to edit_posts, edit_published_posts, or // edit_others_posts case 'edit_post': $author_data = get_userdata( $user_id ); //echo "post ID: {$args[0]}
"; $post = get_post( $args[0] ); $post_type = get_post_type_object( $post->post_type ); if ( $post_type && 'post' != $post_type->capability_type ) { $args = array_merge( array( $post_type->cap->edit_post, $user_id ), $args ); return call_user_func_array( 'map_meta_cap', $args ); } $post_author_data = get_userdata( $post->post_author ); //echo "current user id : $user_id, post author id: " . $post_author_data->ID . "
"; // If the user is the author... if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) { // If the post is published... if ( 'publish' == $post->post_status ) { $caps[] = 'edit_published_posts'; } elseif ( 'trash' == $post->post_status ) { if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) ) $caps[] = 'edit_published_posts'; } else { // If the post is draft... $caps[] = 'edit_posts'; } } else { // The user is trying to edit someone else's post. $caps[] = 'edit_others_posts'; // The post is published, extra cap required. if ( 'publish' == $post->post_status ) $caps[] = 'edit_published_posts'; elseif ( 'private' == $post->post_status ) $caps[] = 'edit_private_posts'; } break; case 'edit_page': $author_data = get_userdata( $user_id ); //echo "post ID: {$args[0]}
"; $page = get_page( $args[0] ); $page_author_data = get_userdata( $page->post_author ); //echo "current user id : $user_id, page author id: " . $page_author_data->ID . "
"; // If the user is the author... if ( is_object( $page_author_data ) && $user_id == $page_author_data->ID ) { // If the page is published... if ( 'publish' == $page->post_status ) { $caps[] = 'edit_published_pages'; } elseif ( 'trash' == $page->post_status ) { if ('publish' == get_post_meta($page->ID, '_wp_trash_meta_status', true) ) $caps[] = 'edit_published_pages'; } else { // If the page is draft... $caps[] = 'edit_pages'; } } else { // The user is trying to edit someone else's page. $caps[] = 'edit_others_pages'; // The page is published, extra cap required. if ( 'publish' == $page->post_status ) $caps[] = 'edit_published_pages'; elseif ( 'private' == $page->post_status ) $caps[] = 'edit_private_pages'; } break; case 'read_post': $post = get_post( $args[0] ); $post_type = get_post_type_object( $post->post_type ); if ( $post_type && 'post' != $post_type->capability_type ) { $args = array_merge( array( $post_type->cap->read_post, $user_id ), $args ); return call_user_func_array( 'map_meta_cap', $args ); } if ( 'private' != $post->post_status ) { $caps[] = 'read'; break; } $author_data = get_userdata( $user_id ); $post_author_data = get_userdata( $post->post_author ); if ( is_object( $post_author_data ) && $user_id == $post_author_data->ID ) $caps[] = 'read'; else $caps[] = 'read_private_posts'; break; case 'read_page': $page = get_page( $args[0] ); if ( 'private' != $page->post_status ) { $caps[] = 'read'; break; } $author_data = get_userdata( $user_id ); $page_author_data = get_userdata( $page->post_author ); if ( is_object( $page_author_data ) && $user_id == $page_author_data->ID ) $caps[] = 'read'; else $caps[] = 'read_private_pages'; break; case 'unfiltered_upload': if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin() ) ) $caps[] = $cap; else $caps[] = 'do_not_allow'; break; case 'edit_files': case 'edit_plugins': case 'edit_themes': if ( defined('DISALLOW_FILE_EDIT') && DISALLOW_FILE_EDIT ) { $caps[] = 'do_not_allow'; break; } // Fall through if not DISALLOW_FILE_EDIT. case 'update_plugins': case 'delete_plugins': case 'install_plugins': case 'update_themes': case 'delete_themes': case 'install_themes': case 'update_core': // Disallow anything that creates, deletes, or edits core, plugin, or theme files. // Files in uploads are excepted. if ( defined('DISALLOW_FILE_MODS') && DISALLOW_FILE_MODS ) { $caps[] = 'do_not_allow'; break; } // Fall through if not DISALLOW_FILE_MODS. case 'unfiltered_html': // Disallow unfiltered_html for all users, even admins and super admins. if ( defined('DISALLOW_UNFILTERED_HTML') && DISALLOW_UNFILTERED_HTML ) { $caps[] = 'do_not_allow'; break; } // Fall through if not DISALLOW_UNFILTERED_HTML case 'delete_user': case 'delete_users': // If multisite these caps are allowed only for super admins. if ( is_multisite() && !is_super_admin() ) $caps[] = 'do_not_allow'; else $caps[] = $cap; break; case 'create_users': if ( is_multisite() && !get_site_option( 'add_new_users' ) ) $caps[] = 'do_not_allow'; else $caps[] = $cap; break; default: // If no meta caps match, return the original cap. $caps[] = $cap; } return apply_filters('map_meta_cap', $caps, $cap, $user_id, $args); } /** * Whether current user has capability or role. * * @since 2.0.0 * * @param string $capability Capability or role name. * @return bool */ function current_user_can( $capability ) { $current_user = wp_get_current_user(); if ( empty( $current_user ) ) return false; $args = array_slice( func_get_args(), 1 ); $args = array_merge( array( $capability ), $args ); return call_user_func_array( array( &$current_user, 'has_cap' ), $args ); } /** * Whether current user has a capability or role for a given blog. * * @since 3.0.0 * * @param int $blog_id Blog ID * @param string $capability Capability or role name. * @return bool */ function current_user_can_for_blog( $blog_id, $capability ) { $current_user = wp_get_current_user(); if ( is_multisite() && is_super_admin() ) return true; if ( empty( $current_user ) ) return false; // Create new object to avoid stomping the global current_user. $user = new WP_User( $current_user->id) ; // Set the blog id. @todo add blog id arg to WP_User constructor? $user->for_blog( $blog_id ); $args = array_slice( func_get_args(), 2 ); $args = array_merge( array( $capability ), $args ); return call_user_func_array( array( &$user, 'has_cap' ), $args ); } /** * Whether author of supplied post has capability or role. * * @since 2.9.0 * * @param int|object $post Post ID or post object. * @param string $capability Capability or role name. * @return bool */ function author_can( $post, $capability ) { if ( !$post = get_post($post) ) return false; $author = new WP_User( $post->post_author ); if ( empty( $author ) ) return false; $args = array_slice( func_get_args(), 2 ); $args = array_merge( array( $capability ), $args ); return call_user_func_array( array( &$author, 'has_cap' ), $args ); } /** * Retrieve role object. * * @see WP_Roles::get_role() Uses method to retrieve role object. * @since 2.0.0 * * @param string $role Role name. * @return object */ function get_role( $role ) { global $wp_roles; if ( ! isset( $wp_roles ) ) $wp_roles = new WP_Roles(); return $wp_roles->get_role( $role ); } /** * Add role, if it does not exist. * * @see WP_Roles::add_role() Uses method to add role. * @since 2.0.0 * * @param string $role Role name. * @param string $display_name Display name for role. * @param array $capabilities List of capabilities. * @return null|WP_Role WP_Role object if role is added, null if already exists. */ function add_role( $role, $display_name, $capabilities = array() ) { global $wp_roles; if ( ! isset( $wp_roles ) ) $wp_roles = new WP_Roles(); return $wp_roles->add_role( $role, $display_name, $capabilities ); } /** * Remove role, if it exists. * * @see WP_Roles::remove_role() Uses method to remove role. * @since 2.0.0 * * @param string $role Role name. * @return null */ function remove_role( $role ) { global $wp_roles; if ( ! isset( $wp_roles ) ) $wp_roles = new WP_Roles(); return $wp_roles->remove_role( $role ); } /** * Retrieve a list of super admins. * * @since 3.0.0 * * @uses $super_admins Super admins global variable, if set. * * @return array List of super admin logins */ function get_super_admins() { global $super_admins; if ( isset($super_admins) ) return $super_admins; else return get_site_option( 'site_admins', array('admin') ); } /** * Determine if user is a site admin. * * @since 3.0.0 * * @param int $user_id (Optional) The ID of a user. Defaults to the current user. * @return bool True if the user is a site admin. */ function is_super_admin( $user_id = false ) { if ( ! $user_id ) { $current_user = wp_get_current_user(); $user_id = ! empty($current_user) ? $current_user->id : 0; } if ( ! $user_id ) return false; $user = new WP_User($user_id); if ( is_multisite() ) { $super_admins = get_super_admins(); if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) ) return true; } else { if ( $user->has_cap('delete_users') ) return true; } return false; } ?> quested or left blank to get the default feed. * * @package WordPress * @subpackage Feed * @since 2.5.0 * * @param int $author_id ID of an author. * @param string $feed Optional. Feed type. * @return string Link to the feed for the author specified by $author_id. */ function get_author_feed_link( $author_id, $feed = '' ) { $author_id = (int) $author_id; $permalink_structure = get_option('permalink_structure'); if ( empty($feed) ) $feed = get_default_feed(); if ( '' == $permalink_structure ) { $link = home_url("?feed=$feed&author=" . $author_id); } else { $link = get_author_posts_url($author_id); if ( $feed == get_default_feed() ) $feed_link = 'feed'; else $feed_link = "feed/$feed"; $link = trailingslashit($link) . user_trailingslashit($feed_link, 'feed'); } $link = apply_filters('author_feed_link', $link, $feed); return $link; } /** * Retrieve the feed link for a category. * * Returns a link to the feed for all post in a given category. A specific feed * can be requested or left blank to get the default feed. * * @package WordPress * @subpackage Feed * @since 2.5.0 * * @param int $cat_id ID of a category. * @param string $feed Optional. Feed type. * @return string Link to the feed for the category specified by $cat_id. */ function get_category_feed_link($cat_id, $feed = '') { return get_term_feed_link($cat_id, 'category', $feed); } /** * Retrieve the feed link for a taxonomy. * * Returns a link to the feed for all post in a given term. A specific feed * can be requested or left blank to get the default feed. * * @since 3.0 * * @param int $term_id ID of a category. * @param string $taxonomy Optional. Taxonomy of $term_id * @param string $feed Optional. Feed type. * @return string Link to the feed for the taxonomy specified by $term_id and $taxonomy. */ function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) { global $wp_rewrite; $term_id = ( int ) $term_id; $term = get_term( $term_id, $taxonomy ); if ( empty( $term ) || is_wp_error( $term ) ) return false; if ( empty( $feed ) ) $feed = get_default_feed(); $permalink_structure = get_option( 'permalink_structure' ); if ( '' == $permalink_structure ) { if ( 'category' == $taxonomy ) { $link = home_url("?feed=$feed&cat=$term_id"); } elseif ( 'post_tag' == $taxonomy ) { $link = home_url("?feed=$feed&tag=$term->slug"); } else { $t = get_taxonomy( $taxonomy ); $link = home_url("?feed=$feed&$t->query_var=$term->slug"); } } else { $link = get_term_link( $term_id, $term->taxonomy ); if ( $feed == get_default_feed() ) $feed_link = 'feed'; else $feed_link = "feed/$feed"; $link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' ); } if ( 'category' == $taxonomy ) $link = apply_filters( 'category_feed_link', $link, $feed ); elseif ( 'post_tag' == $taxonomy ) $link = apply_filters( 'category_feed_link', $link, $feed ); else $link = apply_filters( 'taxonomy_feed_link', $link, $feed, $taxonomy ); return $link; } /** * Retrieve permalink for feed of tag. * * @since 2.3.0 * * @param int $tag_id Tag ID. * @param string $feed Optional. Feed type. * @return string */ function get_tag_feed_link($tag_id, $feed = '') { return get_term_feed_link($tag_id, 'post_tag', $feed); } /** * Retrieve edit tag link. * * @since 2.7.0 * * @param int $tag_id Tag ID * @return string */ function get_edit_tag_link( $tag_id = 0, $taxonomy = 'post_tag' ) { global $post_type; $tax = get_taxonomy($taxonomy); if ( !current_user_can($tax->cap->edit_terms) ) return; $tag = get_term($tag_id, $taxonomy); $location = admin_url('edit-tags.php?action=edit&taxonomy=' . $taxonomy . '&' . (!empty($post_type) ? 'post_type=' . $post_type .'&' : '') .'tag_ID=' . $tag->term_id); return apply_filters( 'get_edit_tag_link', $location ); } /** * Display or retrieve edit tag link with formatting. * * @since 2.7.0 * * @param string $link Optional. Anchor text. * @param string $before Optional. Display before edit link. * @param string $after Optional. Display after edit link. * @param int|object $tag Tag object or ID * @return string|null HTML content, if $echo is set to false. */ function edit_tag_link( $link = '', $before = '', $after = '', $tag = null ) { $tax = get_taxonomy('post_tag'); if ( !current_user_can($tax->cap->edit_terms) ) return; $tag = get_term($tag, 'post_tag'); if ( empty($link) ) $link = __('Edit This'); $link = '' . $link . ''; echo $before . apply_filters( 'edit_tag_link', $link, $tag->term_id ) . $after; } /** * Retrieve permalink for search. * * @since 3.0.0 * @param string $query Optional. The query string to use. If empty the current query is used. * @return string */ function get_search_link( $query = '' ) { global $wp_rewrite; if ( empty($query) ) $search = get_search_query( false ); else $search = stripslashes($query); $permastruct = $wp_rewrite->get_search_permastruct(); if ( empty( $permastruct ) ) { $link = home_url('?s=' . urlencode($search) ); } else { $search = urlencode($search); $search = str_replace('%2F', '/', $search); // %2F(/) is not valid within a URL, send it unencoded. $link = str_replace( '%search%', $search, $permastruct ); $link = home_url( user_trailingslashit( $link, 'search' ) ); } return apply_filters( 'search_link', $link, $search ); } /** * Retrieve the permalink for the feed of the search results. * * @since 2.5.0 * * @param string $search_query Optional. Search query. * @param string $feed Optional. Feed type. * @return string */ function get_search_feed_link($search_query = '', $feed = '') { global $wp_rewrite; $link = get_search_link($search_query); if ( empty($feed) ) $feed = get_default_feed(); $permastruct = $wp_rewrite->get_search_permastruct(); if ( empty($permastruct) ) { $link = add_query_arg('feed', $feed, $link); } else { $link = trailingslashit($link); $link .= "feed/$feed/"; } $link = apply_filters('search_feed_link', $link, $feed, 'posts'); return $link; } /** * Retrieve the permalink for the comments feed of the search results. * * @since 2.5.0 * * @param string $search_query Optional. Search query. * @param string $feed Optional. Feed type. * @return string */ function get_search_comments_feed_link($search_query = '', $feed = '') { global $wp_rewrite; if ( empty($feed) ) $feed = get_default_feed(); $link = get_search_feed_link($search_query, $feed); $permastruct = $wp_rewrite->get_search_permastruct(); if ( empty($permastruct) ) $link = add_query_arg('feed', 'comments-' . $feed, $link); else $link = add_query_arg('withcomments', 1, $link); $link = apply_filters('search_feed_link', $link, $feed, 'comments'); return $link; } /** * Retrieve edit posts link for post. * * Can be used within the WordPress loop or outside of it. Can be used with * pages, posts, attachments, and revisions. * * @since 2.3.0 * * @param int $id Optional. Post ID. * @param string $context Optional, default to display. How to write the '&', defaults to '&'. * @return string */ function get_edit_post_link( $id = 0, $context = 'display' ) { if ( !$post = &get_post( $id ) ) return; if ( 'display' == $context ) $action = '&action=edit'; else $action = '&action=edit'; $post_type_object = get_post_type_object( $post->post_type ); if ( !$post_type_object ) return; if ( !current_user_can( $post_type_object->cap->edit_post, $post->ID ) ) return; return apply_filters( 'get_edit_post_link', admin_url( sprintf($post_type_object->_edit_link . $action, $post->ID) ), $post->ID, $context ); } /** * Display edit post link for post. * * @since 1.0.0 * * @param string $link Optional. Anchor text. * @param string $before Optional. Display before edit link. * @param string $after Optional. Display after edit link. * @param int $id Optional. Post ID. */ function edit_post_link( $link = null, $before = '', $after = '', $id = 0 ) { if ( !$post = &get_post( $id ) ) return; if ( !$url = get_edit_post_link( $post->ID ) ) return; if ( null === $link ) $link = __('Edit This'); $post_type_obj = get_post_type_object( $post->post_type ); $link = '' . $link . ''; echo $before . apply_filters( 'edit_post_link', $link, $post->ID ) . $after; } /** * Retrieve delete posts link for post. * * Can be used within the WordPress loop or outside of it, with any post type. * * @since 2.9.0 * * @param int $id Optional. Post ID. * @param string $deprecated Not used. * @param bool $force_delete Whether to bypass trash and force deletion. Default is false. * @return string */ function get_delete_post_link( $id = 0, $deprecated = '', $force_delete = false ) { if ( ! empty( $deprecated ) ) _deprecated_argument( __FUNCTION__, '3.0.0' ); if ( !$post = &get_post( $id ) ) return; $post_type_object = get_post_type_object( $post->post_type ); if ( !$post_type_object ) return; if ( !current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) return; $action = ( $force_delete || !EMPTY_TRASH_DAYS ) ? 'delete' : 'trash'; $delete_link = add_query_arg( 'action', $action, admin_url( sprintf( $post_type_object->_edit_link, $post->ID ) ) ); return apply_filters( 'get_delete_post_link', wp_nonce_url( $delete_link, "$action-{$post->post_type}_{$post->ID}" ), $post->ID, $force_delete ); } /** * Retrieve edit comment link. * * @since 2.3.0 * * @param int $comment_id Optional. Comment ID. * @return string */ function get_edit_comment_link( $comment_id = 0 ) { $comment = &get_comment( $comment_id ); $post = &get_post( $comment->comment_post_ID ); if ( $post->post_type == 'page' ) { if ( !current_user_can( 'edit_page', $post->ID ) ) return; } else { if ( !current_user_can( 'edit_post', $post->ID ) ) return; } $location = admin_url('comment.php?action=editcomment&c=') . $comment->comment_ID; return apply_filters( 'get_edit_comment_link', $location ); } /** * Display or retrieve edit comment link with formatting. * * @since 1.0.0 * * @param string $link Optional. Anchor text. * @param string $before Optional. Display before edit link. * @param string $after Optional. Display after edit link. * @return string|null HTML content, if $echo is set to false. */ function edit_comment_link( $link = null, $before = '', $after = '' ) { global $comment, $post; if ( $post->post_type == 'page' ) { if ( !current_user_can( 'edit_page', $post->ID ) ) return; } else { if ( !current_user_can( 'edit_post', $post->ID ) ) return; } if ( null === $link ) $link = __('Edit This'); $link = '' . $link . ''; echo $before . apply_filters( 'edit_comment_link', $link, $comment->comment_ID ) . $after; } /** * Display edit bookmark (literally a URL external to blog) link. * * @since 2.7.0 * * @param int $link Optional. Bookmark ID. * @return string */ function get_edit_bookmark_link( $link = 0 ) { $link = get_bookmark( $link ); if ( !current_user_can('manage_links') ) return; $location = admin_url('link.php?action=edit&link_id=') . $link->link_id; return apply_filters( 'get_edit_bookmark_link', $location, $link->link_id ); } /** * Display edit bookmark (literally a URL external to blog) link anchor content. * * @since 2.7.0 * * @param string $link Optional. Anchor text. * @param string $before Optional. Display before edit link. * @param string $after Optional. Display after edit link. * @param int $bookmark Optional. Bookmark ID. */ function edit_bookmark_link( $link = '', $before = '', $after = '', $bookmark = null ) { $bookmark = get_bookmark($bookmark); if ( !current_user_can('manage_links') ) return; if ( empty($link) ) $link = __('Edit This'); $link = '' . $link . ''; echo $before . apply_filters( 'edit_bookmark_link', $link, $bookmark->link_id ) . $after; } // Navigation links /** * Retrieve previous post link that is adjacent to current post. * * @since 1.5.0 * * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. * @return string */ function get_previous_post($in_same_cat = false, $excluded_categories = '') { return get_adjacent_post($in_same_cat, $excluded_categories); } /** * Retrieve next post link that is adjacent to current post. * * @since 1.5.0 * * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. * @return string */ function get_next_post($in_same_cat = false, $excluded_categories = '') { return get_adjacent_post($in_same_cat, $excluded_categories, false); } /** * Retrieve adjacent post link. * * Can either be next or previous post link. * * @since 2.5.0 * * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. * @param bool $previous Optional. Whether to retrieve previous post. * @return string */ function get_adjacent_post($in_same_cat = false, $excluded_categories = '', $previous = true) { global $post, $wpdb; if ( empty( $post ) ) return null; $current_post_date = $post->post_date; $join = ''; $posts_in_ex_cats_sql = ''; if ( $in_same_cat || !empty($excluded_categories) ) { $join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id"; if ( $in_same_cat ) { $cat_array = wp_get_object_terms($post->ID, 'category', array('fields' => 'ids')); $join .= " AND tt.taxonomy = 'category' AND tt.term_id IN (" . implode(',', $cat_array) . ")"; } $posts_in_ex_cats_sql = "AND tt.taxonomy = 'category'"; if ( !empty($excluded_categories) ) { $excluded_categories = array_map('intval', explode(' and ', $excluded_categories)); if ( !empty($cat_array) ) { $excluded_categories = array_diff($excluded_categories, $cat_array); $posts_in_ex_cats_sql = ''; } if ( !empty($excluded_categories) ) { $posts_in_ex_cats_sql = " AND tt.taxonomy = 'category' AND tt.term_id NOT IN (" . implode($excluded_categories, ',') . ')'; } } } $adjacent = $previous ? 'previous' : 'next'; $op = $previous ? '<' : '>'; $order = $previous ? 'DESC' : 'ASC'; $join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_cat, $excluded_categories ); $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare("WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $posts_in_ex_cats_sql", $current_post_date, $post->post_type), $in_same_cat, $excluded_categories ); $sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" ); $query = "SELECT p.* FROM $wpdb->posts AS p $join $where $sort"; $query_key = 'adjacent_post_' . md5($query); $result = wp_cache_get($query_key, 'counts'); if ( false !== $result ) return $result; $result = $wpdb->get_row("SELECT p.* FROM $wpdb->posts AS p $join $where $sort"); if ( null === $result ) $result = ''; wp_cache_set($query_key, $result, 'counts'); return $result; } /** * Get adjacent post relational link. * * Can either be next or previous post relational link. * * @since 2.8.0 * * @param string $title Optional. Link title format. * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. * @param bool $previous Optional, default is true. Whether display link to previous post. * @return string */ function get_adjacent_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '', $previous = true) { if ( $previous && is_attachment() && is_object( $GLOBALS['post'] ) ) $post = & get_post($GLOBALS['post']->post_parent); else $post = get_adjacent_post($in_same_cat,$excluded_categories,$previous); if ( empty($post) ) return; if ( empty($post->post_title) ) $post->post_title = $previous ? __('Previous Post') : __('Next Post'); $date = mysql2date(get_option('date_format'), $post->post_date); $title = str_replace('%title', $post->post_title, $title); $title = str_replace('%date', $date, $title); $title = apply_filters('the_title', $title, $post->ID); $link = $previous ? "\n"; $adjacent = $previous ? 'previous' : 'next'; return apply_filters( "{$adjacent}_post_rel_link", $link ); } /** * Display relational links for the posts adjacent to the current post. * * @since 2.8.0 * * @param string $title Optional. Link title format. * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. */ function adjacent_posts_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') { echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', true); echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', false); } /** * Display relational links for the posts adjacent to the current post for single post pages. * * This is meant to be attached to actions like 'wp_head'. Do not call this directly in plugins or theme templates. * @since 3.0.0 * */ function adjacent_posts_rel_link_wp_head() { if ( !is_singular() || is_attachment() ) return; adjacent_posts_rel_link(); } /** * Display relational link for the next post adjacent to the current post. * * @since 2.8.0 * * @param string $title Optional. Link title format. * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. */ function next_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') { echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', false); } /** * Display relational link for the previous post adjacent to the current post. * * @since 2.8.0 * * @param string $title Optional. Link title format. * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. */ function prev_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') { echo get_adjacent_post_rel_link($title, $in_same_cat, $excluded_categories = '', true); } /** * Retrieve boundary post. * * Boundary being either the first or last post by publish date within the contraitns specified * by in same category or excluded categories. * * @since 2.8.0 * * @param bool $in_same_cat Optional. Whether returned post should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. * @param bool $previous Optional. Whether to retrieve first post. * @return object */ function get_boundary_post($in_same_cat = false, $excluded_categories = '', $start = true) { global $post; if ( empty($post) || !is_single() || is_attachment() ) return null; $cat_array = array(); $excluded_categories = array(); if ( !empty($in_same_cat) || !empty($excluded_categories) ) { if ( !empty($in_same_cat) ) { $cat_array = wp_get_object_terms($post->ID, 'category', array('fields' => 'ids')); } if ( !empty($excluded_categories) ) { $excluded_categories = array_map('intval', explode(',', $excluded_categories)); if ( !empty($cat_array) ) $excluded_categories = array_diff($excluded_categories, $cat_array); $inverse_cats = array(); foreach ( $excluded_categories as $excluded_category) $inverse_cats[] = $excluded_category * -1; $excluded_categories = $inverse_cats; } } $categories = implode(',', array_merge($cat_array, $excluded_categories) ); $order = $start ? 'ASC' : 'DESC'; return get_posts( array('numberposts' => 1, 'no_found_rows' => true, 'order' => $order, 'orderby' => 'ID', 'category' => $categories) ); } /** * Get boundary post relational link. * * Can either be start or end post relational link. * * @since 2.8.0 * * @param string $title Optional. Link title format. * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. * @param bool $start Optional, default is true. Whether display link to first post. * @return string */ function get_boundary_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '', $start = true) { $posts = get_boundary_post($in_same_cat,$excluded_categories,$start); // If there is no post stop. if ( empty($posts) ) return; // Even though we limited get_posts to return only 1 item it still returns an array of objects. $post = $posts[0]; if ( empty($post->post_title) ) $post->post_title = $start ? __('First Post') : __('Last Post'); $date = mysql2date(get_option('date_format'), $post->post_date); $title = str_replace('%title', $post->post_title, $title); $title = str_replace('%date', $date, $title); $title = apply_filters('the_title', $title, $post->ID); $link = $start ? "\n"; $boundary = $start ? 'start' : 'end'; return apply_filters( "{$boundary}_post_rel_link", $link ); } /** * Display relational link for the first post. * * @since 2.8.0 * * @param string $title Optional. Link title format. * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. */ function start_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') { echo get_boundary_post_rel_link($title, $in_same_cat, $excluded_categories, true); } /** * Get site index relational link. * * @since 2.8.0 * * @return string */ function get_index_rel_link() { $link = "\n"; return apply_filters( "index_rel_link", $link ); } /** * Display relational link for the site index. * * @since 2.8.0 */ function index_rel_link() { echo get_index_rel_link(); } /** * Get parent post relational link. * * @since 2.8.0 * * @param string $title Optional. Link title format. * @return string */ function get_parent_post_rel_link($title = '%title') { if ( ! empty( $GLOBALS['post'] ) && ! empty( $GLOBALS['post']->post_parent ) ) $post = & get_post($GLOBALS['post']->post_parent); if ( empty($post) ) return; $date = mysql2date(get_option('date_format'), $post->post_date); $title = str_replace('%title', $post->post_title, $title); $title = str_replace('%date', $date, $title); $title = apply_filters('the_title', $title, $post->ID); $link = "\n"; return apply_filters( "parent_post_rel_link", $link ); } /** * Display relational link for parent item * * @since 2.8.0 */ function parent_post_rel_link($title = '%title') { echo get_parent_post_rel_link($title); } /** * Display previous post link that is adjacent to the current post. * * @since 1.5.0 * * @param string $format Optional. Link anchor format. * @param string $link Optional. Link permalink format. * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. */ function previous_post_link($format='« %link', $link='%title', $in_same_cat = false, $excluded_categories = '') { adjacent_post_link($format, $link, $in_same_cat, $excluded_categories, true); } /** * Display next post link that is adjacent to the current post. * * @since 1.5.0 * * @param string $format Optional. Link anchor format. * @param string $link Optional. Link permalink format. * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. */ function next_post_link($format='%link »', $link='%title', $in_same_cat = false, $excluded_categories = '') { adjacent_post_link($format, $link, $in_same_cat, $excluded_categories, false); } /** * Display adjacent post link. * * Can be either next post link or previous. * * @since 2.5.0 * * @param string $format Link anchor format. * @param string $link Link permalink format. * @param bool $in_same_cat Optional. Whether link should be in same category. * @param string $excluded_categories Optional. Excluded categories IDs. * @param bool $previous Optional, default is true. Whether display link to previous post. */ function adjacent_post_link($format, $link, $in_same_cat = false, $excluded_categories = '', $previous = true) { if ( $previous && is_attachment() ) $post = & get_post($GLOBALS['post']->post_parent); else $post = get_adjacent_post($in_same_cat, $excluded_categories, $previous); if ( !$post ) return; $title = $post->post_title; if ( empty($post->post_title) ) $title = $previous ? __('Previous Post') : __('Next Post'); $title = apply_filters('the_title', $title, $post->ID); $date = mysql2date(get_option('date_format'), $post->post_date); $rel = $previous ? 'prev' : 'next'; $string = ''; $link = str_replace('%title', $title, $link); $link = str_replace('%date', $date, $link); $link = $string . $link . ''; $format = str_replace('%link', $link, $format); $adjacent = $previous ? 'previous' : 'next'; echo apply_filters( "{$adjacent}_post_link", $format, $link ); } /** * Retrieve get links for page numbers. * * @since 1.5.0 * * @param int $pagenum Optional. Page ID. * @return string */ function get_pagenum_link($pagenum = 1) { global $wp_rewrite; $pagenum = (int) $pagenum; $request = remove_query_arg( 'paged' ); $home_root = parse_url(home_url()); $home_root = ( isset($home_root['path']) ) ? $home_root['path'] : ''; $home_root = preg_quote( trailingslashit( $home_root ), '|' ); $request = preg_replace('|^'. $home_root . '|', '', $request); $request = preg_replace('|^/+|', '', $request); if ( !$wp_rewrite->using_permalinks() || is_admin() ) { $base = trailingslashit( get_bloginfo( 'url' ) ); if ( $pagenum > 1 ) { $result = add_query_arg( 'paged', $pagenum, $base . $request ); } else { $result = $base . $request; } } else { $qs_regex = '|\?.*?$|'; preg_match( $qs_regex, $request, $qs_match ); if ( !empty( $qs_match[0] ) ) { $query_string = $qs_match[0]; $request = preg_replace( $qs_regex, '', $request ); } else { $query_string = ''; } $request = preg_replace( '|page/\d+/?$|', '', $request); $request = preg_replace( '|^index\.php|', '', $request); $request = ltrim($request, '/'); $base = trailingslashit( get_bloginfo( 'url' ) ); if ( $wp_rewrite->using_index_permalinks() && ( $pagenum > 1 || '' != $request ) ) $base .= 'index.php/'; if ( $pagenum > 1 ) { $request = ( ( !empty( $request ) ) ? trailingslashit( $request ) : $request ) . user_trailingslashit( 'page/' . $pagenum, 'paged' ); } $result = $base . $request . $query_string; } $result = apply_filters('get_pagenum_link', $result); return $result; } /** * Retrieve next posts pages link. * * Backported from 2.1.3 to 2.0.10. * * @since 2.0.10 * * @param int $max_page Optional. Max pages. * @return string */ function get_next_posts_page_link($max_page = 0) { global $paged; if ( !is_single() ) { if ( !$paged ) $paged = 1; $nextpage = intval($paged) + 1; if ( !$max_page || $max_page >= $nextpage ) return get_pagenum_link($nextpage); } } /** * Display or return the next posts pages link. * * @since 0.71 * * @param int $max_page Optional. Max pages. * @param boolean $echo Optional. Echo or return; */ function next_posts( $max_page = 0, $echo = true ) { $output = esc_url( get_next_posts_page_link( $max_page ) ); if ( $echo ) echo $output; else return $output; } /** * Return the next posts pages link. * * @since 2.7.0 * * @param string $label Content for link text. * @param int $max_page Optional. Max pages. * @return string|null */ function get_next_posts_link( $label = 'Next Page »', $max_page = 0 ) { global $paged, $wp_query; if ( !$max_page ) $max_page = $wp_query->max_num_pages; if ( !$paged ) $paged = 1; $nextpage = intval($paged) + 1; if ( !is_single() && ( empty($paged) || $nextpage <= $max_page) ) { $attr = apply_filters( 'next_posts_link_attributes', '' ); return '" . preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&$1', $label) . ''; } } /** * Display the next posts pages link. * * @since 0.71 * @uses get_next_posts_link() * * @param string $label Content for link text. * @param int $max_page Optional. Max pages. */ function next_posts_link( $label = 'Next Page »', $max_page = 0 ) { echo get_next_posts_link( $label, $max_page ); } /** * Retrieve previous post pages link. * * Will only return string, if not on a single page or post. * * Backported to 2.0.10 from 2.1.3. * * @since 2.0.10 * * @return string|null */ function get_previous_posts_page_link() { global $paged; if ( !is_single() ) { $nextpage = intval($paged) - 1; if ( $nextpage < 1 ) $nextpage = 1; return get_pagenum_link($nextpage); } } /** * Display or return the previous posts pages link. * * @since 0.71 * * @param boolean $echo Optional. Echo or return; */ function previous_posts( $echo = true ) { $output = esc_url( get_previous_posts_page_link() ); if ( $echo ) echo $output; else return $output; } /** * Return the previous posts pages link. * * @since 2.7.0 * * @param string $label Optional. Previous page link text. * @return string|null */ function get_previous_posts_link( $label = '« Previous Page' ) { global $paged; if ( !is_single() && $paged > 1 ) { $attr = apply_filters( 'previous_posts_link_attributes', '' ); return '". preg_replace( '/&([^#])(?![a-z]{1,8};)/', '&$1', $label ) .''; } } /** * Display the previous posts page link. * * @since 0.71 * @uses get_previous_posts_link() * * @param string $label Optional. Previous page link text. */ function previous_posts_link( $label = '« Previous Page' ) { echo get_previous_posts_link( $label ); } /** * Return post pages link navigation for previous and next pages. * * @since 2.8 * * @param string|array $args Optional args. * @return string The posts link navigation. */ function get_posts_nav_link( $args = array() ) { global $wp_query; $return = ''; if ( !is_singular() ) { $defaults = array( 'sep' => ' — ', 'prelabel' => __('« Previous Page'), 'nxtlabel' => __('Next Page »'), ); $args = wp_parse_args( $args, $defaults ); $max_num_pages = $wp_query->max_num_pages; $paged = get_query_var('paged'); //only have sep if there's both prev and next results if ($paged < 2 || $paged >= $max_num_pages) { $args['sep'] = ''; } if ( $max_num_pages > 1 ) { $return = get_previous_posts_link($args['prelabel']); $return .= preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&$1', $args['sep']); $return .= get_next_posts_link($args['nxtlabel']); } } return $return; } /** * Display post pages link navigation for previous and next pages. * * @since 0.71 * * @param string $sep Optional. Separator for posts navigation links. * @param string $prelabel Optional. Label for previous pages. * @param string $nxtlabel Optional Label for next pages. */ function posts_nav_link( $sep = '', $prelabel = '', $nxtlabel = '' ) { $args = array_filter( compact('sep', 'prelabel', 'nxtlabel') ); echo get_posts_nav_link($args); } /** * Retrieve page numbers links. * * @since 2.7.0 * * @param int $pagenum Optional. Page number. * @return string */ function get_comments_pagenum_link( $pagenum = 1, $max_page = 0 ) { global $post, $wp_rewrite; $pagenum = (int) $pagenum; $result = get_permalink( $post->ID ); if ( 'newest' == get_option('default_comments_page') ) { if ( $pagenum != $max_page ) { if ( $wp_rewrite->using_permalinks() ) $result = user_trailingslashit( trailingslashit($result) . 'comment-page-' . $pagenum, 'commentpaged'); else $result = add_query_arg( 'cpage', $pagenum, $result ); } } elseif ( $pagenum > 1 ) { if ( $wp_rewrite->using_permalinks() ) $result = user_trailingslashit( trailingslashit($result) . 'comment-page-' . $pagenum, 'commentpaged'); else $result = add_query_arg( 'cpage', $pagenum, $result ); } $result .= '#comments'; $result = apply_filters('get_comments_pagenum_link', $result); return $result; } /** * Return the link to next comments pages. * * @since 2.7.1 * * @param string $label Optional. Label for link text. * @param int $max_page Optional. Max page. * @return string|null */ function get_next_comments_link( $label = '', $max_page = 0 ) { global $wp_query; if ( !is_singular() || !get_option('page_comments') ) return; $page = get_query_var('cpage'); $nextpage = intval($page) + 1; if ( empty($max_page) ) $max_page = $wp_query->max_num_comment_pages; if ( empty($max_page) ) $max_page = get_comment_pages_count(); if ( $nextpage > $max_page ) return; if ( empty($label) ) $label = __('Newer Comments »'); return ''. preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&$1', $label) .''; } /** * Display the link to next comments pages. * * @since 2.7.0 * * @param string $label Optional. Label for link text. * @param int $max_page Optional. Max page. */ function next_comments_link( $label = '', $max_page = 0 ) { echo get_next_comments_link( $label, $max_page ); } /** * Return the previous comments page link. * * @since 2.7.1 * * @param string $label Optional. Label for comments link text. * @return string|null */ function get_previous_comments_link( $label = '' ) { if ( !is_singular() || !get_option('page_comments') ) return; $page = get_query_var('cpage'); if ( intval($page) <= 1 ) return; $prevpage = intval($page) - 1; if ( empty($label) ) $label = __('« Older Comments'); return '' . preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&$1', $label) .''; } /** * Display the previous comments page link. * * @since 2.7.0 * * @param string $label Optional. Label for comments link text. */ function previous_comments_link( $label = '' ) { echo get_previous_comments_link( $label ); } /** * Create pagination links for the comments on the current post. * * @see paginate_links() * @since 2.7.0 * * @param string|array $args Optional args. See paginate_links. * @return string Markup for pagination links. */ function paginate_comments_links($args = array()) { global $wp_rewrite; if ( !is_singular() || !get_option('page_comments') ) return; $page = get_query_var('cpage'); if ( !$page ) $page = 1; $max_page = get_comment_pages_count(); $defaults = array( 'base' => add_query_arg( 'cpage', '%#%' ), 'format' => '', 'total' => $max_page, 'current' => $page, 'echo' => true, 'add_fragment' => '#comments' ); if ( $wp_rewrite->using_permalinks() ) $defaults['base'] = user_trailingslashit(trailingslashit(get_permalink()) . 'comment-page-%#%', 'commentpaged'); $args = wp_parse_args( $args, $defaults ); $page_links = paginate_links( $args ); if ( $args['echo'] ) echo $page_links; else return $page_links; } /** * Retrieve shortcut link. * * Use this in 'a' element 'href' attribute. * * @since 2.6.0 * * @return string */ function get_shortcut_link() { $link = "javascript: var d=document, w=window, e=w.getSelection, k=d.getSelection, x=d.selection, s=(e?e():(k)?k():(x?x.createRange().text:0)), f='" . admin_url('press-this.php') . "', l=d.location, e=encodeURIComponent, u=f+'?u='+e(l.href)+'&t='+e(d.title)+'&s='+e(s)+'&v=4'; a=function(){if(!w.open(u,'t','toolbar=0,resizable=1,scrollbars=1,status=1,width=720,height=570'))l.href=u;}; if (/Firefox/.test(navigator.userAgent)) setTimeout(a, 0); else a(); void(0)"; $link = str_replace(array("\r", "\n", "\t"), '', $link); return apply_filters('shortcut_link', $link); } /** * Retrieve the home url for the current site. * * Returns the 'home' option with the appropriate protocol, 'https' if * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is * overridden. * * @package WordPress * @since 3.0.0 * * @uses get_home_url() * * @param string $path (optional) Path relative to the home url. * @param string $scheme (optional) Scheme to give the home url context. Currently 'http','https' * @return string Home url link with optional path appended. */ function home_url( $path = '', $scheme = null ) { return get_home_url(null, $path, $scheme); } /** * Retrieve the home url for a given site. * * Returns the 'home' option with the appropriate protocol, 'https' if * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is * overridden. * * @package WordPress * @since 3.0.0 * * @param int $blog_id (optional) Blog ID. Defaults to current blog. * @param string $path (optional) Path relative to the home url. * @param string $scheme (optional) Scheme to give the home url context. Currently 'http','https' * @return string Home url link with optional path appended. */ function get_home_url( $blog_id = null, $path = '', $scheme = null ) { $orig_scheme = $scheme; if ( !in_array( $scheme, array( 'http', 'https' ) ) ) $scheme = is_ssl() && !is_admin() ? 'https' : 'http'; if ( empty( $blog_id ) || !is_multisite() ) $home = get_option( 'home' ); else $home = get_blog_option( $blog_id, 'home' ); $url = str_replace( 'http://', "$scheme://", $home ); if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) $url .= '/' . ltrim( $path, '/' ); return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id ); } /** * Retrieve the site url for the current site. * * Returns the 'site_url' option with the appropriate protocol, 'https' if * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is * overridden. * * @package WordPress * @since 2.6.0 * * @uses get_site_url() * * @param string $path Optional. Path relative to the site url. * @param string $scheme Optional. Scheme to give the site url context. Currently 'http','https', 'login', 'login_post', or 'admin'. * @return string Site url link with optional path appended. */ function site_url( $path = '', $scheme = null ) { return get_site_url(null, $path, $scheme); } /** * Retrieve the site url for a given site. * * Returns the 'site_url' option with the appropriate protocol, 'https' if * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is * overridden. * * @package WordPress * @since 3.0.0 * * @param int $blog_id (optional) Blog ID. Defaults to current blog. * @param string $path Optional. Path relative to the site url. * @param string $scheme Optional. Scheme to give the site url context. Currently 'http','https', 'login', 'login_post', or 'admin'. * @return string Site url link with optional path appended. */ function get_site_url( $blog_id = null, $path = '', $scheme = null ) { // should the list of allowed schemes be maintained elsewhere? $orig_scheme = $scheme; if ( !in_array( $scheme, array( 'http', 'https' ) ) ) { if ( ( 'login_post' == $scheme || 'rpc' == $scheme ) && ( force_ssl_login() || force_ssl_admin() ) ) $scheme = 'https'; elseif ( ( 'login' == $scheme ) && force_ssl_admin() ) $scheme = 'https'; elseif ( ( 'admin' == $scheme ) && force_ssl_admin() ) $scheme = 'https'; else $scheme = ( is_ssl() ? 'https' : 'http' ); } if ( empty( $blog_id ) || !is_multisite() ) $url = get_option( 'siteurl' ); else $url = get_blog_option( $blog_id, 'siteurl' ); $url = str_replace( 'http://', "{$scheme}://", $url ); if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) $url .= '/' . ltrim( $path, '/' ); return apply_filters( 'site_url', $url, $path, $orig_scheme, $blog_id ); } /** * Retrieve the url to the admin area for the current site. * * @package WordPress * @since 2.6.0 * * @param string $path Optional path relative to the admin url * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. * @return string Admin url link with optional path appended */ function admin_url( $path = '', $scheme = 'admin' ) { return get_admin_url(null, $path, $scheme); } /** * Retrieve the url to the admin area for a given site. * * @package WordPress * @since 3.0.0 * * @param int $blog_id (optional) Blog ID. Defaults to current blog. * @param string $path Optional path relative to the admin url * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. * @return string Admin url link with optional path appended */ function get_admin_url( $blog_id = null, $path = '', $scheme = 'admin' ) { $url = get_site_url($blog_id, 'wp-admin/', $scheme); if ( !empty($path) && is_string($path) && strpos($path, '..') === false ) $url .= ltrim($path, '/'); return apply_filters('admin_url', $url, $path, $blog_id); } /** * Retrieve the url to the includes directory. * * @package WordPress * @since 2.6.0 * * @param string $path Optional. Path relative to the includes url. * @return string Includes url link with optional path appended. */ function includes_url($path = '') { $url = site_url() . '/' . WPINC . '/'; if ( !empty($path) && is_string($path) && strpos($path, '..') === false ) $url .= ltrim($path, '/'); return apply_filters('includes_url', $url, $path); } /** * Retrieve the url to the content directory. * * @package WordPress * @since 2.6.0 * * @param string $path Optional. Path relative to the content url. * @return string Content url link with optional path appended. */ function content_url($path = '') { $url = WP_CONTENT_URL; if ( 0 === strpos($url, 'http') && is_ssl() ) $url = str_replace( 'http://', 'https://', $url ); if ( !empty($path) && is_string($path) && strpos($path, '..') === false ) $url .= '/' . ltrim($path, '/'); return apply_filters('content_url', $url, $path); } /** * Retrieve the url to the plugins directory or to a specific file within that directory. * You can hardcode the plugin slug in $path or pass __FILE__ as a second argument to get the correct folder name. * * @package WordPress * @since 2.6.0 * * @param string $path Optional. Path relative to the plugins url. * @param string $plugin Optional. The plugin file that you want to be relative to - i.e. pass in __FILE__ * @return string Plugins url link with optional path appended. */ function plugins_url($path = '', $plugin = '') { $mu_plugin_dir = WPMU_PLUGIN_DIR; foreach ( array('path', 'plugin', 'mu_plugin_dir') as $var ) { $$var = str_replace('\\' ,'/', $$var); // sanitize for Win32 installs $$var = preg_replace('|/+|', '/', $$var); } if ( !empty($plugin) && 0 === strpos($plugin, $mu_plugin_dir) ) $url = WPMU_PLUGIN_URL; else $url = WP_PLUGIN_URL; if ( 0 === strpos($url, 'http') && is_ssl() ) $url = str_replace( 'http://', 'https://', $url ); if ( !empty($plugin) && is_string($plugin) ) { $folder = dirname(plugin_basename($plugin)); if ( '.' != $folder ) $url .= '/' . ltrim($folder, '/'); } if ( !empty($path) && is_string($path) && strpos($path, '..') === false ) $url .= '/' . ltrim($path, '/'); return apply_filters('plugins_url', $url, $path, $plugin); } /** * Retrieve the site url for the current network. * * Returns the site url with the appropriate protocol, 'https' if * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is * overridden. * * @package WordPress * @since 3.0.0 * * @param string $path Optional. Path relative to the site url. * @param string $scheme Optional. Scheme to give the site url context. Currently 'http','https', 'login', 'login_post', or 'admin'. * @return string Site url link with optional path appended. */ function network_site_url( $path = '', $scheme = null ) { global $current_site; if ( !is_multisite() ) return site_url($path, $scheme); $orig_scheme = $scheme; if ( !in_array($scheme, array('http', 'https')) ) { if ( ( 'login_post' == $scheme || 'rpc' == $scheme ) && ( force_ssl_login() || force_ssl_admin() ) ) $scheme = 'https'; elseif ( ('login' == $scheme) && ( force_ssl_admin() ) ) $scheme = 'https'; elseif ( ('admin' == $scheme) && force_ssl_admin() ) $scheme = 'https'; else $scheme = ( is_ssl() ? 'https' : 'http' ); } $url = 'http://' . $current_site->domain . $current_site->path; $url = str_replace( 'http://', "{$scheme}://", $url ); if ( !empty($path) && is_string($path) && strpos($path, '..') === false ) $url .= ltrim($path, '/'); return apply_filters('network_site_url', $url, $path, $orig_scheme); } /** * Retrieve the home url for the current network. * * Returns the home url with the appropriate protocol, 'https' if * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is * overridden. * * @package WordPress * @since 3.0.0 * * @param string $path (optional) Path relative to the home url. * @param string $scheme (optional) Scheme to give the home url context. Currently 'http','https' * @return string Home url link with optional path appended. */ function network_home_url( $path = '', $scheme = null ) { global $current_site; if ( !is_multisite() ) return home_url($path, $scheme); $orig_scheme = $scheme; if ( !in_array($scheme, array('http', 'https')) ) $scheme = is_ssl() && !is_admin() ? 'https' : 'http'; $url = 'http://' . $current_site->domain . $current_site->path; $url = str_replace( 'http://', "$scheme://", $url ); if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) $url .= ltrim( $path, '/' ); return apply_filters( 'network_home_url', $url, $path, $orig_scheme); } /** * Retrieve the url to the admin area for the network. * * @package WordPress * @since 3.0.0 * * @param string $path Optional path relative to the admin url * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. * @return string Admin url link with optional path appended */ function network_admin_url( $path = '', $scheme = 'admin' ) { $url = network_site_url('wp-admin/', $scheme); if ( !empty($path) && is_string($path) && strpos($path, '..') === false ) $url .= ltrim($path, '/'); return apply_filters('network_admin_url', $url, $path); } /** * Output rel=canonical for singular queries * * @package WordPress * @since 2.9.0 */ function rel_canonical() { if ( !is_singular() ) return; global $wp_the_query; if ( !$id = $wp_the_query->get_queried_object_id() ) return; $link = get_permalink( $id ); echo "\n"; } /** * Return a shortlink for a post, page, attachment, or blog. * * This function exists to provide a shortlink tag that all themes and plugins can target. A plugin must hook in to * provide the actual shortlinks. Default shortlink support is limited to providing ?p= style links for posts. * Plugins can short circuit this function via the pre_get_shortlink filter or filter the output * via the get_shortlink filter. * * @since 3.0.0. * * @param int $id A post or blog id. Default is 0, which means the current post or blog. * @param string $contex Whether the id is a 'blog' id, 'post' id, or 'media' id. If 'post', the post_type of the post is consulted. If 'query', the current query is consulted to determine the id and context. Default is 'post'. * @param bool $allow_slugs Whether to allow post slugs in the shortlink. It is up to the plugin how and whether to honor this. * @return string A shortlink or an empty string if no shortlink exists for the requested resource or if shortlinks are not enabled. */ function wp_get_shortlink($id = 0, $context = 'post', $allow_slugs = true) { // Allow plugins to short-circuit this function. $shortlink = apply_filters('pre_get_shortlink', false, $id, $context, $allow_slugs); if ( false !== $shortlink ) return $shortlink; global $wp_query; $post_id = 0; if ( 'query' == $context && is_single() ) { $post_id = $wp_query->get_queried_object_id(); } elseif ( 'post' == $context ) { $post = get_post($id); $post_id = $post->ID; } $shortlink = ''; // Return p= link for posts. if ( !empty($post_id) && '' != get_option('permalink_structure') ) { $post = get_post($post_id); if ( isset($post->post_type) && 'post' == $post->post_type ) $shortlink = home_url('?p=' . $post->ID); } return apply_filters('get_shortlink', $shortlink, $id, $context, $allow_slugs); } /** * Inject rel=sortlink into head if a shortlink is defined for the current page. * * Attached to the wp_head action. * * @since 3.0.0 * * @uses wp_get_shortlink() */ function wp_shortlink_wp_head() { $shortlink = wp_get_shortlink( 0, 'query' ); if ( empty( $shortlink ) ) return; echo "\n"; } /** * Send a Link: rel=shortlink header if a shortlink is defined for the current page. * * Attached to the wp action. * * @since 3.0.0 * * @uses wp_get_shortlink() */ function wp_shortlink_header() { if ( headers_sent() ) return; $shortlink = wp_get_shortlink(0, 'query'); if ( empty($shortlink) ) return; header('Link: <' . $shortlink . '>; rel=shortlink', false); } /** * Display the Short Link for a Post * * Must be called from inside "The Loop" * * Call like the_shortlink(__('Shortlinkage FTW')) * * @since 3.0.0 * * @param string $text Optional The link text or HTML to be displayed. Defaults to 'This is the short link.' * @param string $title Optional The tooltip for the link. Must be sanitized. Defaults to the sanitized post title. * @param string $before Optional HTML to display before the link. * @param string $before Optional HTML to display after the link. */ function the_shortlink( $text = '', $title = '', $before = '', $after = '' ) { global $post; if ( empty( $text ) ) $text = __('This is the short link.'); if ( empty( $title ) ) $title = the_title_attribute( array( 'echo' => FALSE ) ); $shortlink = wp_get_shortlink( $post->ID ); if ( !empty( $shortlink ) ) { $link = '' . $text . ''; $link = apply_filters( 'the_shortlink', $link, $shortlink, $text, $title ); echo $before, $link, $after; } } ?>