get_permalink

The timeline below displays how wordpress function get_permalink has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.3

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL. False if the post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' === $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ('page' === $post->post_type) {
        return get_page_link($post, $leavename, $sample);
    } elseif ('attachment' === $post->post_type) {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)), true)) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ($permalink && !wp_force_plain_post_permalink($post)) {
        $category = '';
        if (str_contains($permalink, '%category%')) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($category_object->parent) {
                    $category = get_category_parents($category_object->parent, false, '/', true) . $category;
                }
            }
            /*
             * Show default category in permalinks,
             * without having to assign it explicitly.
             */
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (str_contains($permalink, '%author%')) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        /*
         * This is not an API call because the permalink is based on the stored post_date value,
         * which should be parsed as local time regardless of the default PHP timezone.
         */
        $date = explode(' ', str_replace(array('-', ':'), ' ', $post->post_date));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // If they're not using the fancy permalink option.
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 6.1

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL. False if the post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' === $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ('page' === $post->post_type) {
        return get_page_link($post, $leavename, $sample);
    } elseif ('attachment' === $post->post_type) {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)), true)) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ($permalink && !wp_force_plain_post_permalink($post)) {
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($category_object->parent) {
                    $category = get_category_parents($category_object->parent, false, '/', true) . $category;
                }
            }
            // Show default category in permalinks,
            // without having to assign it explicitly.
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        // This is not an API call because the permalink is based on the stored post_date value,
        // which should be parsed as local time regardless of the default PHP timezone.
        $date = explode(' ', str_replace(array('-', ':'), ' ', $post->post_date));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // If they're not using the fancy permalink option.
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 5.7

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' === $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ('page' === $post->post_type) {
        return get_page_link($post, $leavename, $sample);
    } elseif ('attachment' === $post->post_type) {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)), true)) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ($permalink && !wp_force_plain_post_permalink($post)) {
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($category_object->parent) {
                    $category = get_category_parents($category_object->parent, false, '/', true) . $category;
                }
            }
            // Show default category in permalinks,
            // without having to assign it explicitly.
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        // This is not an API call because the permalink is based on the stored post_date value,
        // which should be parsed as local time regardless of the default PHP timezone.
        $date = explode(' ', str_replace(array('-', ':'), ' ', $post->post_date));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // If they're not using the fancy permalink option.
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 5.6

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' === $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ('page' === $post->post_type) {
        return get_page_link($post, $leavename, $sample);
    } elseif ('attachment' === $post->post_type) {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)), true)) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ($permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future', 'trash'), true)) {
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($category_object->parent) {
                    $category = get_category_parents($category_object->parent, false, '/', true) . $category;
                }
            }
            // Show default category in permalinks,
            // without having to assign it explicitly.
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        // This is not an API call because the permalink is based on the stored post_date value,
        // which should be parsed as local time regardless of the default PHP timezone.
        $date = explode(' ', str_replace(array('-', ':'), ' ', $post->post_date));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // If they're not using the fancy permalink option.
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 5.5

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' === $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ('page' === $post->post_type) {
        return get_page_link($post, $leavename, $sample);
    } elseif ('attachment' === $post->post_type) {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)), true)) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ($permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'), true)) {
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($category_object->parent) {
                    $category = get_category_parents($category_object->parent, false, '/', true) . $category;
                }
            }
            // Show default category in permalinks,
            // without having to assign it explicitly.
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        // This is not an API call because the permalink is based on the stored post_date value,
        // which should be parsed as local time regardless of the default PHP timezone.
        $date = explode(' ', str_replace(array('-', ':'), ' ', $post->post_date));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // If they're not using the fancy permalink option.
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 5.4

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' == $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ('page' === $post->post_type) {
        return get_page_link($post, $leavename, $sample);
    } elseif ('attachment' === $post->post_type) {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($category_object->parent) {
                    $category = get_category_parents($category_object->parent, false, '/', true) . $category;
                }
            }
            // Show default category in permalinks,
            // without having to assign it explicitly.
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        // This is not an API call because the permalink is based on the stored post_date value,
        // which should be parsed as local time regardless of the default PHP timezone.
        $date = explode(' ', str_replace(array('-', ':'), ' ', $post->post_date));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // If they're not using the fancy permalink option.
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 3.1

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' == $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($category_object->parent) {
                    $category = get_category_parents($category_object->parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        // This is not an API call because the permalink is based on the stored post_date value,
        // which should be parsed as local time regardless of the default PHP timezone.
        $date = explode(' ', str_replace(array('-', ':'), ' ', $post->post_date));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 5.3

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' == $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($category_object->parent) {
                    $category = get_category_parents($category_object->parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(' ', gmdate('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 5.1

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' == $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($category_object->parent) {
                    $category = get_category_parents($category_object->parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(' ', date('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 4.7

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' == $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                $cats = wp_list_sort($cats, array('term_id' => 'ASC'));
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param WP_Term  $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories (WP_Term objects) associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($parent = $category_object->parent) {
                    $category = get_category_parents($parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(" ", date('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 4.6

/**
 * Retrieves the full permalink for the current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' == $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filters the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                usort($cats, '_usort_terms_by_ID');
                // order by ID
                /**
                 * Filters the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param stdClass $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($parent = $category_object->parent) {
                    $category = get_category_parents($parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                if ($default_category && !is_wp_error($default_category)) {
                    $category = $default_category->slug;
                }
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(" ", date('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filters the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 4.4

/**
 * Retrieve full permalink for current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $post      Optional. Post ID or post object. Default is the global `$post`.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($post = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($post) && isset($post->filter) && 'sample' == $post->filter) {
        $sample = true;
    } else {
        $post = get_post($post);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filter the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                usort($cats, '_usort_terms_by_ID');
                // order by ID
                /**
                 * Filter the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param stdClass $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($parent = $category_object->parent) {
                    $category = get_category_parents($parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                $category = is_wp_error($default_category) ? '' : $default_category->slug;
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(" ", date('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filter the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 4.3

/**
 * Retrieve full permalink for current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $id        Optional. Post ID or post object. Default current post.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|false The permalink URL or false if post does not exist.
 */
function get_permalink($id = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($id) && isset($id->filter) && 'sample' == $id->filter) {
        $post = $id;
        $sample = true;
    } else {
        $post = get_post($id);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filter the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                usort($cats, '_usort_terms_by_ID');
                // order by ID
                /**
                 * Filter the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param stdClass $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($parent = $category_object->parent) {
                    $category = get_category_parents($parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                $category = is_wp_error($default_category) ? '' : $default_category->slug;
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(" ", date('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filter the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 4.2

/**
 * Retrieve full permalink for current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $id        Optional. Post ID or post object. Default current post.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|bool The permalink URL or false if post does not exist.
 */
function get_permalink($id = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($id) && isset($id->filter) && 'sample' == $id->filter) {
        $post = $id;
        $sample = true;
    } else {
        $post = get_post($id);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filter the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft', 'future'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                usort($cats, '_usort_terms_by_ID');
                // order by ID
                /**
                 * Filter the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param stdClass $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($parent = $category_object->parent) {
                    $category = get_category_parents($parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                $category = is_wp_error($default_category) ? '' : $default_category->slug;
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(" ", date('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filter the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 4.0

/**
 * Retrieve full permalink for current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $id        Optional. Post ID or post object. Default current post.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|bool The permalink URL or false if post does not exist.
 */
function get_permalink($id = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($id) && isset($id->filter) && 'sample' == $id->filter) {
        $post = $id;
        $sample = true;
    } else {
        $post = get_post($id);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filter the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                usort($cats, '_usort_terms_by_ID');
                // order by ID
                /**
                 * Filter the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param stdClass $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($parent = $category_object->parent) {
                    $category = get_category_parents($parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                $category = is_wp_error($default_category) ? '' : $default_category->slug;
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(" ", date('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filter the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 3.9

/**
 * Retrieve full permalink for current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $id        Optional. Post ID or post object. Default current post.
 * @param bool        $leavename Optional. Whether to keep post name or page name. Default false.
 * @return string|bool The permalink URL or false if post does not exist.
 */
function get_permalink($id = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($id) && isset($id->filter) && 'sample' == $id->filter) {
        $post = $id;
        $sample = true;
    } else {
        $post = get_post($id);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post->ID, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post->ID, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post->ID, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    /**
     * Filter the permalink structure for a post before token replacement occurs.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 3.0.0
     *
     * @param string  $permalink The site's permalink structure.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                usort($cats, '_usort_terms_by_ID');
                // order by ID
                /**
                 * Filter the category that gets used in the %category% permalink token.
                 *
                 * @since 3.5.0
                 *
                 * @param stdClass $cat  The category to use in the permalink.
                 * @param array    $cats Array of all categories associated with the post.
                 * @param WP_Post  $post The post in question.
                 */
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($parent = $category_object->parent) {
                    $category = get_category_parents($parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                $category = is_wp_error($default_category) ? '' : $default_category->slug;
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(" ", date('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    /**
     * Filter the permalink for a post.
     *
     * Only applies to posts with post_type of 'post'.
     *
     * @since 1.5.0
     *
     * @param string  $permalink The post's permalink.
     * @param WP_Post $post      The post in question.
     * @param bool    $leavename Whether to keep the post name.
     */
    return apply_filters('post_link', $permalink, $post, $leavename);
}

WordPress Version: 3.7

/**
 * Retrieve full permalink for current post or post ID.
 *
 * @since 1.0.0
 *
 * @param int|WP_Post $id Optional. Post ID or post object, defaults to the current post.
 * @param bool $leavename Optional. Whether to keep post name or page name, defaults to false.
 * @return string|bool The permalink URL or false if post does not exist.
 */
function get_permalink($id = 0, $leavename = false)
{
    $rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename ? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename ? '' : '%pagename%');
    if (is_object($id) && isset($id->filter) && 'sample' == $id->filter) {
        $post = $id;
        $sample = true;
    } else {
        $post = get_post($id);
        $sample = false;
    }
    if (empty($post->ID)) {
        return false;
    }
    if ($post->post_type == 'page') {
        return get_page_link($post->ID, $leavename, $sample);
    } elseif ($post->post_type == 'attachment') {
        return get_attachment_link($post->ID, $leavename);
    } elseif (in_array($post->post_type, get_post_types(array('_builtin' => false)))) {
        return get_post_permalink($post->ID, $leavename, $sample);
    }
    $permalink = get_option('permalink_structure');
    $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
    if ('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft'))) {
        $unixtime = strtotime($post->post_date);
        $category = '';
        if (strpos($permalink, '%category%') !== false) {
            $cats = get_the_category($post->ID);
            if ($cats) {
                usort($cats, '_usort_terms_by_ID');
                // order by ID
                $category_object = apply_filters('post_link_category', $cats[0], $cats, $post);
                $category_object = get_term($category_object, 'category');
                $category = $category_object->slug;
                if ($parent = $category_object->parent) {
                    $category = get_category_parents($parent, false, '/', true) . $category;
                }
            }
            // show default category in permalinks, without
            // having to assign it explicitly
            if (empty($category)) {
                $default_category = get_term(get_option('default_category'), 'category');
                $category = is_wp_error($default_category) ? '' : $default_category->slug;
            }
        }
        $author = '';
        if (strpos($permalink, '%author%') !== false) {
            $authordata = get_userdata($post->post_author);
            $author = $authordata->user_nicename;
        }
        $date = explode(" ", date('Y m d H i s', $unixtime));
        $rewritereplace = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name);
        $permalink = home_url(str_replace($rewritecode, $rewritereplace, $permalink));
        $permalink = user_trailingslashit($permalink, 'single');
    } else {
        // if they're not using the fancy permalink option
        $permalink = home_url('?p=' . $post->ID);
    }
    return apply_filters('post_link', $permalink, $post, $leavename);
}