+/**
+ * Returns the list of classes to be used by a metabox
+ *
+ * @since 2.5.0
+ *
+ * @param string $id
+ * @param string $page
+ * @return string
+ */
+function postbox_classes( $id, $page ) {
+ if ( isset( $_GET['edit'] ) && $_GET['edit'] == $id ) {
+ $classes = array( '' );
+ } elseif ( $closed = get_user_option('closedpostboxes_'.$page ) ) {
+ if ( !is_array( $closed ) ) {
+ $classes = array( '' );
+ } else {
+ $classes = in_array( $id, $closed ) ? array( 'closed' ) : array( '' );
+ }
+ } else {
+ $classes = array( '' );
+ }
+
+ /**
+ * Filter the postbox classes for a specific screen and screen ID combo.
+ *
+ * The dynamic portions of the hook name, `$page` and `$id`, refer to
+ * the screen and screen ID, respectively.
+ *
+ * @since 3.2.0
+ *
+ * @param array $classes An array of postbox classes.
+ */
+ $classes = apply_filters( "postbox_classes_{$page}_{$id}", $classes );
+ return implode( ' ', $classes );
+}
+
+/**
+ * Get a sample permalink based off of the post name.
+ *
+ * @since 2.5.0
+ *
+ * @param int $id Post ID or post object.
+ * @param string $title Optional. Title. Default null.
+ * @param string $name Optional. Name. Default null.
+ * @return array Array with two entries of type string.
+ */
+function get_sample_permalink($id, $title = null, $name = null) {
+ $post = get_post( $id );
+ if ( ! $post )
+ return array( '', '' );
+
+ $ptype = get_post_type_object($post->post_type);
+
+ $original_status = $post->post_status;
+ $original_date = $post->post_date;
+ $original_name = $post->post_name;
+
+ // Hack: get_permalink() would return ugly permalink for drafts, so we will fake that our post is published.
+ if ( in_array( $post->post_status, array( 'draft', 'pending' ) ) ) {
+ $post->post_status = 'publish';
+ $post->post_name = sanitize_title($post->post_name ? $post->post_name : $post->post_title, $post->ID);
+ }
+
+ // If the user wants to set a new name -- override the current one
+ // Note: if empty name is supplied -- use the title instead, see #6072
+ if ( !is_null($name) )
+ $post->post_name = sanitize_title($name ? $name : $title, $post->ID);
+
+ $post->post_name = wp_unique_post_slug($post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent);
+
+ $post->filter = 'sample';
+
+ $permalink = get_permalink($post, true);
+
+ // Replace custom post_type Token with generic pagename token for ease of use.
+ $permalink = str_replace("%$post->post_type%", '%pagename%', $permalink);
+
+ // Handle page hierarchy
+ if ( $ptype->hierarchical ) {
+ $uri = get_page_uri($post);
+ $uri = untrailingslashit($uri);
+ $uri = strrev( stristr( strrev( $uri ), '/' ) );
+ $uri = untrailingslashit($uri);
+
+ /** This filter is documented in wp-admin/edit-tag-form.php */
+ $uri = apply_filters( 'editable_slug', $uri );
+ if ( !empty($uri) )
+ $uri .= '/';
+ $permalink = str_replace('%pagename%', "{$uri}%pagename%", $permalink);
+ }
+
+ /** This filter is documented in wp-admin/edit-tag-form.php */
+ $permalink = array( $permalink, apply_filters( 'editable_slug', $post->post_name ) );
+ $post->post_status = $original_status;
+ $post->post_date = $original_date;
+ $post->post_name = $original_name;
+ unset($post->filter);
+
+ return $permalink;
+}
+
+/**
+ * Returns the HTML of the sample permalink slug editor.
+ *
+ * @since 2.5.0
+ *
+ * @param int $id Post ID or post object.
+ * @param string $new_title Optional. New title. Default null.
+ * @param string $new_slug Optional. New slug. Default null.
+ * @return string The HTML of the sample permalink slug editor.
+ */
+function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) {
+ $post = get_post( $id );
+ if ( ! $post )
+ return '';
+
+ list($permalink, $post_name) = get_sample_permalink($post->ID, $new_title, $new_slug);
+
+ if ( current_user_can( 'read_post', $post->ID ) ) {
+ $ptype = get_post_type_object( $post->post_type );
+ $view_post = $ptype->labels->view_item;
+ }
+
+ if ( 'publish' == get_post_status( $post ) ) {
+ $title = __('Click to edit this part of the permalink');
+ } else {
+ $title = __('Temporary permalink. Click to edit this part.');
+ }
+
+ if ( false === strpos( $permalink, '%postname%' ) && false === strpos( $permalink, '%pagename%' ) ) {
+ $return = '<strong>' . __('Permalink:') . "</strong>\n" . '<span id="sample-permalink" tabindex="-1">' . $permalink . "</span>\n";
+ if ( '' == get_option( 'permalink_structure' ) && current_user_can( 'manage_options' ) && !( 'page' == get_option('show_on_front') && $id == get_option('page_on_front') ) ) {
+ $return .= '<span id="change-permalinks"><a href="options-permalink.php" class="button button-small" target="_blank">' . __('Change Permalinks') . "</a></span>\n";
+ }
+ } else {
+ if ( function_exists( 'mb_strlen' ) ) {
+ if ( mb_strlen( $post_name ) > 30 ) {
+ $post_name_abridged = mb_substr( $post_name, 0, 14 ) . '…' . mb_substr( $post_name, -14 );
+ } else {
+ $post_name_abridged = $post_name;
+ }
+ } else {
+ if ( strlen( $post_name ) > 30 ) {
+ $post_name_abridged = substr( $post_name, 0, 14 ) . '…' . substr( $post_name, -14 );
+ } else {
+ $post_name_abridged = $post_name;
+ }
+ }
+
+ $post_name_html = '<span id="editable-post-name" title="' . $title . '">' . $post_name_abridged . '</span>';
+ $display_link = str_replace( array( '%pagename%', '%postname%' ), $post_name_html, urldecode( $permalink ) );
+
+ $return = '<strong>' . __( 'Permalink:' ) . "</strong>\n";
+ $return .= '<span id="sample-permalink" tabindex="-1">' . $display_link . "</span>\n";
+ $return .= '‎'; // Fix bi-directional text display defect in RTL languages.
+ $return .= '<span id="edit-slug-buttons"><a href="#post_name" class="edit-slug button button-small hide-if-no-js" onclick="editPermalink(' . $id . '); return false;">' . __( 'Edit' ) . "</a></span>\n";
+ $return .= '<span id="editable-post-name-full">' . $post_name . "</span>\n";
+ }