Example #1
1
/**
 * Register a post type. Do not use before init.
 *
 * A function for creating or modifying a post type based on the
 * parameters given. The function will accept an array (second optional
 * parameter), along with a string for the post type name.
 *
 * @since 2.9.0
 * @since 3.0.0 The `show_ui` argument is now enforced on the new post screen.
 * @since 4.4.0 The `show_ui` argument is now enforced on the post type listing screen and post editing screen.
 *
 * @global array      $wp_post_types List of post types.
 * @global WP_Rewrite $wp_rewrite    Used for default feeds.
 * @global WP         $wp            Used to add query vars.
 *
 * @param string $post_type Post type key, must not exceed 20 characters.
 * @param array|string $args {
 *     Array or string of arguments for registering a post type.
 *
 *     @type string      $label                Name of the post type shown in the menu. Usually plural.
 *                                             Default is value of $labels['name'].
 *     @type array       $labels               An array of labels for this post type. If not set, post
 *                                             labels are inherited for non-hierarchical types and page
 *                                             labels for hierarchical ones. {@see get_post_type_labels()}.
 *     @type string      $description          A short descriptive summary of what the post type is.
 *                                             Default empty.
 *     @type bool        $public               Whether a post type is intended for use publicly either via
 *                                             the admin interface or by front-end users. While the default
 *                                             settings of $exclude_from_search, $publicly_queryable, $show_ui,
 *                                             and $show_in_nav_menus are inherited from public, each does not
 *                                             rely on this relationship and controls a very specific intention.
 *                                             Default false.
 *     @type bool        $hierarchical         Whether the post type is hierarchical (e.g. page). Default false.
 *     @type bool        $exclude_from_search  Whether to exclude posts with this post type from front end search
 *                                             results. Default is the opposite value of $public.
 *     @type bool        $publicly_queryable   Whether queries can be performed on the front end for the post type
 *                                             as part of {@see parse_request()}. Endpoints would include:
 *                                             * ?post_type={post_type_key}
 *                                             * ?{post_type_key}={single_post_slug}
 *                                             * ?{post_type_query_var}={single_post_slug}
 *                                             If not set, the default is inherited from $public.
 *     @type bool        $show_ui              Whether to generate and allow a UI for managing this post type in the
 *                                             admin. Default is value of $public.
 *     @type bool        $show_in_menu         Where to show the post type in the admin menu. To work, $show_ui
 *                                             must be true. If true, the post type is shown in its own top level
 *                                             menu. If false, no menu is shown. If a string of an existing top
 *                                             level menu (eg. 'tools.php' or 'edit.php?post_type=page'), the post
 *                                             type will be placed as a sub-menu of that.
 *                                             Default is value of $show_ui.
 *     @type bool        $show_in_nav_menus    Makes this post type available for selection in navigation menus.
 *                                             Default is value $public.
 *     @type bool        $show_in_admin_bar    Makes this post type available via the admin bar. Default is value
 *                                             of $show_in_menu.
 *     @type int         $menu_position        The position in the menu order the post type should appear. To work,
 *                                             $show_in_menu must be true. Default null (at the bottom).
 *     @type string      $menu_icon            The url to the icon to be used for this menu. Pass a base64-encoded
 *                                             SVG using a data URI, which will be colored to match the color scheme
 *                                             -- this should begin with 'data:image/svg+xml;base64,'. Pass the name
 *                                             of a Dashicons helper class to use a font icon, e.g.
 *                                             'dashicons-chart-pie'. Pass 'none' to leave div.wp-menu-image empty
 *                                             so an icon can be added via CSS. Defaults to use the posts icon.
 *     @type string      $capability_type      The string to use to build the read, edit, and delete capabilities.
 *                                             May be passed as an array to allow for alternative plurals when using
 *                                             this argument as a base to construct the capabilities, e.g.
 *                                             array('story', 'stories'). Default 'post'.
 *     @type array       $capabilities         Array of capabilities for this post type. $capability_type is used
 *                                             as a base to construct capabilities by default.
 *                                             {@see get_post_type_capabilities()}.
 *     @type bool        $map_meta_cap         Whether to use the internal default meta capability handling.
 *                                             Default false.
 *     @type array       $supports             An alias for calling {@see add_post_type_support()} directly.
 *                                             Defaults to array containing 'title' & 'editor'.
 *     @type callable    $register_meta_box_cb Provide a callback function that sets up the meta boxes for the
 *                                             edit form. Do remove_meta_box() and add_meta_box() calls in the
 *                                             callback. Default null.
 *     @type array       $taxonomies           An array of taxonomy identifiers that will be registered for the
 *                                             post type. Taxonomies can be registered later with
 *                                             {@see register_taxonomy()} or {@see register_taxonomy_for_object_type()}.
 *                                             Default empty array.
 *     @type bool|string $has_archive          Whether there should be post type archives, or if a string, the
 *                                             archive slug to use. Will generate the proper rewrite rules if
 *                                             $rewrite is enabled. Default false.
 *     @type bool|array  $rewrite              {
 *         Triggers the handling of rewrites for this post type. To prevent rewrite, set to false.
 *         Defaults to true, using $post_type as slug. To specify rewrite rules, an array can be
 *         passed with any of these keys:
 *
 *         @type string $slug       Customize the permastruct slug. Defaults to $post_type key.
 *         @type bool   $with_front Whether the permastruct should be prepended with WP_Rewrite::$front.
 *                                  Default true.
 *         @type bool   $feeds      Whether the feed permastruct should be built for this post type.
 *                                  Default is value of $has_archive.
 *         @type bool   $pages      Whether the permastruct should provide for pagination. Default true.
 *         @type const  $ep_mask    Endpoint mask to assign. If not specified and permalink_epmask is set,
 *                                  inherits from $permalink_epmask. If not specified and permalink_epmask
 *                                  is not set, defaults to EP_PERMALINK.
 *     }
 *     @type string|bool $query_var            Sets the query_var key for this post type. Defaults to $post_type
 *                                             key. If false, a post type cannot be loaded at
 *                                             ?{query_var}={post_slug}. If specified as a string, the query
 *                                             ?{query_var_string}={post_slug} will be valid.
 *     @type bool        $can_export           Whether to allow this post type to be exported. Default true.
 *     @type bool        $delete_with_user     Whether to delete posts of this type when deleting a user. If true,
 *                                             posts of this type belonging to the user will be moved to trash
 *                                             when then user is deleted. If false, posts of this type belonging
 *                                             to the user will *not* be trashed or deleted. If not set (the default),
 *                                             posts are trashed if post_type_supports('author'). Otherwise posts
 *                                             are not trashed or deleted. Default null.
 *     @type bool        $_builtin             FOR INTERNAL USE ONLY! True if this post type is a native or
 *                                             "built-in" post_type. Default false.
 *     @type string      $_edit_link           FOR INTERNAL USE ONLY! URL segment to use for edit link of
 *                                             this post type. Default 'post.php?post=%d'.
 * }
 * @return object|WP_Error The registered post type object, or an error object.
 */
function register_post_type($post_type, $args = array())
{
    global $wp_post_types, $wp_rewrite, $wp;
    if (!is_array($wp_post_types)) {
        $wp_post_types = array();
    }
    // Sanitize post type name
    $post_type = sanitize_key($post_type);
    $args = wp_parse_args($args);
    /**
     * Filter the arguments for registering a post type.
     *
     * @since 4.4.0
     *
     * @param array  $args      Array of arguments for registering a post type.
     * @param string $post_type Post type key.
     */
    $args = apply_filters('register_post_type_args', $args, $post_type);
    $has_edit_link = !empty($args['_edit_link']);
    // Args prefixed with an underscore are reserved for internal use.
    $defaults = array('labels' => array(), 'description' => '', 'public' => false, 'hierarchical' => false, 'exclude_from_search' => null, 'publicly_queryable' => null, 'show_ui' => null, 'show_in_menu' => null, 'show_in_nav_menus' => null, 'show_in_admin_bar' => null, 'menu_position' => null, 'menu_icon' => null, 'capability_type' => 'post', 'capabilities' => array(), 'map_meta_cap' => null, 'supports' => array(), 'register_meta_box_cb' => null, 'taxonomies' => array(), 'has_archive' => false, 'rewrite' => true, 'query_var' => true, 'can_export' => true, 'delete_with_user' => null, '_builtin' => false, '_edit_link' => 'post.php?post=%d');
    $args = array_merge($defaults, $args);
    $args = (object) $args;
    $args->name = $post_type;
    if (empty($post_type) || strlen($post_type) > 20) {
        _doing_it_wrong(__FUNCTION__, __('Post type names must be between 1 and 20 characters in length.'), '4.2');
        return new WP_Error('post_type_length_invalid', __('Post type names must be between 1 and 20 characters in length.'));
    }
    // If not set, default to the setting for public.
    if (null === $args->publicly_queryable) {
        $args->publicly_queryable = $args->public;
    }
    // If not set, default to the setting for public.
    if (null === $args->show_ui) {
        $args->show_ui = $args->public;
    }
    // If not set, default to the setting for show_ui.
    if (null === $args->show_in_menu || !$args->show_ui) {
        $args->show_in_menu = $args->show_ui;
    }
    // If not set, default to the whether the full UI is shown.
    if (null === $args->show_in_admin_bar) {
        $args->show_in_admin_bar = (bool) $args->show_in_menu;
    }
    // If not set, default to the setting for public.
    if (null === $args->show_in_nav_menus) {
        $args->show_in_nav_menus = $args->public;
    }
    // If not set, default to true if not public, false if public.
    if (null === $args->exclude_from_search) {
        $args->exclude_from_search = !$args->public;
    }
    // Back compat with quirky handling in version 3.0. #14122.
    if (empty($args->capabilities) && null === $args->map_meta_cap && in_array($args->capability_type, array('post', 'page'))) {
        $args->map_meta_cap = true;
    }
    // If not set, default to false.
    if (null === $args->map_meta_cap) {
        $args->map_meta_cap = false;
    }
    // If there's no specified edit link and no UI, remove the edit link.
    if (!$args->show_ui && !$has_edit_link) {
        $args->_edit_link = '';
    }
    $args->cap = get_post_type_capabilities($args);
    unset($args->capabilities);
    if (is_array($args->capability_type)) {
        $args->capability_type = $args->capability_type[0];
    }
    if (!empty($args->supports)) {
        add_post_type_support($post_type, $args->supports);
        unset($args->supports);
    } elseif (false !== $args->supports) {
        // Add default features
        add_post_type_support($post_type, array('title', 'editor'));
    }
    if (false !== $args->query_var) {
        if (true === $args->query_var) {
            $args->query_var = $post_type;
        } else {
            $args->query_var = sanitize_title_with_dashes($args->query_var);
        }
        if ($wp && is_post_type_viewable($args)) {
            $wp->add_query_var($args->query_var);
        }
    }
    if (false !== $args->rewrite && (is_admin() || '' != get_option('permalink_structure'))) {
        if (!is_array($args->rewrite)) {
            $args->rewrite = array();
        }
        if (empty($args->rewrite['slug'])) {
            $args->rewrite['slug'] = $post_type;
        }
        if (!isset($args->rewrite['with_front'])) {
            $args->rewrite['with_front'] = true;
        }
        if (!isset($args->rewrite['pages'])) {
            $args->rewrite['pages'] = true;
        }
        if (!isset($args->rewrite['feeds']) || !$args->has_archive) {
            $args->rewrite['feeds'] = (bool) $args->has_archive;
        }
        if (!isset($args->rewrite['ep_mask'])) {
            if (isset($args->permalink_epmask)) {
                $args->rewrite['ep_mask'] = $args->permalink_epmask;
            } else {
                $args->rewrite['ep_mask'] = EP_PERMALINK;
            }
        }
        if ($args->hierarchical) {
            add_rewrite_tag("%{$post_type}%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type={$post_type}&pagename=");
        } else {
            add_rewrite_tag("%{$post_type}%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type={$post_type}&name=");
        }
        if ($args->has_archive) {
            $archive_slug = $args->has_archive === true ? $args->rewrite['slug'] : $args->has_archive;
            if ($args->rewrite['with_front']) {
                $archive_slug = substr($wp_rewrite->front, 1) . $archive_slug;
            } else {
                $archive_slug = $wp_rewrite->root . $archive_slug;
            }
            add_rewrite_rule("{$archive_slug}/?\$", "index.php?post_type={$post_type}", 'top');
            if ($args->rewrite['feeds'] && $wp_rewrite->feeds) {
                $feeds = '(' . trim(implode('|', $wp_rewrite->feeds)) . ')';
                add_rewrite_rule("{$archive_slug}/feed/{$feeds}/?\$", "index.php?post_type={$post_type}" . '&feed=$matches[1]', 'top');
                add_rewrite_rule("{$archive_slug}/{$feeds}/?\$", "index.php?post_type={$post_type}" . '&feed=$matches[1]', 'top');
            }
            if ($args->rewrite['pages']) {
                add_rewrite_rule("{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?\$", "index.php?post_type={$post_type}" . '&paged=$matches[1]', 'top');
            }
        }
        $permastruct_args = $args->rewrite;
        $permastruct_args['feed'] = $permastruct_args['feeds'];
        add_permastruct($post_type, "{$args->rewrite['slug']}/%{$post_type}%", $permastruct_args);
    }
    // Register the post type meta box if a custom callback was specified.
    if ($args->register_meta_box_cb) {
        add_action('add_meta_boxes_' . $post_type, $args->register_meta_box_cb, 10, 1);
    }
    $args->labels = get_post_type_labels($args);
    $args->label = $args->labels->name;
    $wp_post_types[$post_type] = $args;
    add_action('future_' . $post_type, '_future_post_hook', 5, 2);
    foreach ($args->taxonomies as $taxonomy) {
        register_taxonomy_for_object_type($taxonomy, $post_type);
    }
    /**
     * Fires after a post type is registered.
     *
     * @since 3.3.0
     *
     * @param string $post_type Post type.
     * @param object $args      Arguments used to register the post type.
     */
    do_action('registered_post_type', $post_type, $args);
    return $args;
}
 /**
  * Generates and displays row action links.
  *
  * @since 4.3.0
  * @access protected
  *
  * @param object $post        Post being acted upon.
  * @param string $column_name Current column name.
  * @param string $primary     Primary column name.
  * @return string Row actions output for posts.
  */
 protected function handle_row_actions($post, $column_name, $primary)
 {
     if ($primary !== $column_name) {
         return '';
     }
     $post_type_object = get_post_type_object($post->post_type);
     $can_edit_post = current_user_can('edit_post', $post->ID);
     $actions = array();
     if ($can_edit_post && 'trash' != $post->post_status) {
         $actions['edit'] = '<a href="' . get_edit_post_link($post->ID) . '" title="' . esc_attr__('Edit this item') . '">' . __('Edit') . '</a>';
         $actions['inline hide-if-no-js'] = '<a href="#" class="editinline" title="' . esc_attr__('Edit this item inline') . '">' . __('Quick&nbsp;Edit') . '</a>';
     }
     if (current_user_can('delete_post', $post->ID)) {
         if ('trash' == $post->post_status) {
             $actions['untrash'] = "<a title='" . esc_attr__('Restore this item from the Trash') . "' href='" . wp_nonce_url(admin_url(sprintf($post_type_object->_edit_link . '&amp;action=untrash', $post->ID)), 'untrash-post_' . $post->ID) . "'>" . __('Restore') . "</a>";
         } elseif (EMPTY_TRASH_DAYS) {
             $actions['trash'] = "<a class='submitdelete' title='" . esc_attr__('Move this item to the Trash') . "' href='" . get_delete_post_link($post->ID) . "'>" . __('Trash') . "</a>";
         }
         if ('trash' == $post->post_status || !EMPTY_TRASH_DAYS) {
             $actions['delete'] = "<a class='submitdelete' title='" . esc_attr__('Delete this item permanently') . "' href='" . get_delete_post_link($post->ID, '', true) . "'>" . __('Delete Permanently') . "</a>";
         }
     }
     if (is_post_type_viewable($post_type_object)) {
         $title = _draft_or_post_title();
         if (in_array($post->post_status, array('pending', 'draft', 'future'))) {
             if ($can_edit_post) {
                 $preview_link = set_url_scheme(get_permalink($post->ID));
                 /** This filter is documented in wp-admin/includes/meta-boxes.php */
                 $preview_link = apply_filters('preview_post_link', add_query_arg('preview', 'true', $preview_link), $post);
                 $actions['view'] = '<a href="' . esc_url($preview_link) . '" title="' . esc_attr(sprintf(__('Preview &#8220;%s&#8221;'), $title)) . '" rel="permalink">' . __('Preview') . '</a>';
             }
         } elseif ('trash' != $post->post_status) {
             $actions['view'] = '<a href="' . get_permalink($post->ID) . '" title="' . esc_attr(sprintf(__('View &#8220;%s&#8221;'), $title)) . '" rel="permalink">' . __('View') . '</a>';
         }
     }
     if (is_post_type_hierarchical($post->post_type)) {
         /**
          * Filter the array of row action links on the Pages list table.
          *
          * The filter is evaluated only for hierarchical post types.
          *
          * @since 2.8.0
          *
          * @param array $actions An array of row action links. Defaults are
          *                         'Edit', 'Quick Edit', 'Restore, 'Trash',
          *                         'Delete Permanently', 'Preview', and 'View'.
          * @param WP_Post $post The post object.
          */
         $actions = apply_filters('page_row_actions', $actions, $post);
     } else {
         /**
          * Filter the array of row action links on the Posts list table.
          *
          * The filter is evaluated only for non-hierarchical post types.
          *
          * @since 2.8.0
          *
          * @param array $actions An array of row action links. Defaults are
          *                         'Edit', 'Quick Edit', 'Restore, 'Trash',
          *                         'Delete Permanently', 'Preview', and 'View'.
          * @param WP_Post $post The post object.
          */
         $actions = apply_filters('post_row_actions', $actions, $post);
     }
     return $this->row_actions($actions);
 }
 /**
  * Generates and displays row action links.
  *
  * @since 4.3.0
  * @access protected
  *
  * @param object $post        Post being acted upon.
  * @param string $column_name Current column name.
  * @param string $primary     Primary column name.
  * @return string Row actions output for posts.
  */
 protected function handle_row_actions($post, $column_name, $primary)
 {
     if ($primary !== $column_name) {
         return '';
     }
     $post_type_object = get_post_type_object($post->post_type);
     $can_edit_post = current_user_can('edit_post', $post->ID);
     $actions = array();
     $title = _draft_or_post_title();
     if ($can_edit_post && 'trash' != $post->post_status) {
         $actions['edit'] = sprintf('<a href="%s" aria-label="%s">%s</a>', get_edit_post_link($post->ID), esc_attr(sprintf(__('Edit &#8220;%s&#8221;'), $title)), __('Edit'));
         $actions['inline hide-if-no-js'] = sprintf('<a href="#" class="editinline" aria-label="%s">%s</a>', esc_attr(sprintf(__('Quick edit &#8220;%s&#8221; inline'), $title)), __('Quick&nbsp;Edit'));
     }
     if (current_user_can('delete_post', $post->ID)) {
         if ('trash' === $post->post_status) {
             $actions['untrash'] = sprintf('<a href="%s" aria-label="%s">%s</a>', wp_nonce_url(admin_url(sprintf($post_type_object->_edit_link . '&amp;action=untrash', $post->ID)), 'untrash-post_' . $post->ID), esc_attr(sprintf(__('Restore &#8220;%s&#8221; from the Trash'), $title)), __('Restore'));
         } elseif (EMPTY_TRASH_DAYS) {
             $actions['trash'] = sprintf('<a href="%s" class="submitdelete" aria-label="%s">%s</a>', get_delete_post_link($post->ID), esc_attr(sprintf(__('Move &#8220;%s&#8221; to the Trash'), $title)), _x('Trash', 'verb'));
         }
         if ('trash' === $post->post_status || !EMPTY_TRASH_DAYS) {
             $actions['delete'] = sprintf('<a href="%s" class="submitdelete" aria-label="%s">%s</a>', get_delete_post_link($post->ID, '', true), esc_attr(sprintf(__('Delete &#8220;%s&#8221; permanently'), $title)), __('Delete Permanently'));
         }
     }
     if (is_post_type_viewable($post_type_object)) {
         if (in_array($post->post_status, array('pending', 'draft', 'future'))) {
             if ($can_edit_post) {
                 $unpublished_link = set_url_scheme(get_permalink($post));
                 $preview_link = get_preview_post_link($post, array(), $unpublished_link);
                 $actions['view'] = sprintf('<a href="%s" rel="permalink" aria-label="%s">%s</a>', esc_url($preview_link), esc_attr(sprintf(__('Preview &#8220;%s&#8221;'), $title)), __('Preview'));
             }
         } elseif ('trash' != $post->post_status) {
             $actions['view'] = sprintf('<a href="%s" rel="permalink" aria-label="%s">%s</a>', get_permalink($post->ID), esc_attr(sprintf(__('View &#8220;%s&#8221;'), $title)), __('View'));
         }
     }
     if (is_post_type_hierarchical($post->post_type)) {
         /**
          * Filter the array of row action links on the Pages list table.
          *
          * The filter is evaluated only for hierarchical post types.
          *
          * @since 2.8.0
          *
          * @param array $actions An array of row action links. Defaults are
          *                         'Edit', 'Quick Edit', 'Restore, 'Trash',
          *                         'Delete Permanently', 'Preview', and 'View'.
          * @param WP_Post $post The post object.
          */
         $actions = apply_filters('page_row_actions', $actions, $post);
     } else {
         /**
          * Filter the array of row action links on the Posts list table.
          *
          * The filter is evaluated only for non-hierarchical post types.
          *
          * @since 2.8.0
          *
          * @param array $actions An array of row action links. Defaults are
          *                         'Edit', 'Quick Edit', 'Restore, 'Trash',
          *                         'Delete Permanently', 'Preview', and 'View'.
          * @param WP_Post $post The post object.
          */
         $actions = apply_filters('post_row_actions', $actions, $post);
     }
     return $this->row_actions($actions);
 }
Example #4
0
/**
 * Retrieve URL used for the post preview.
 *
 * Get the preview post URL. Allows additional query args to be appended.
 *
 * @since 4.4.0
 *
 * @param int|WP_Post $post         Optional. Post ID or `WP_Post` object. Defaults to global post.
 * @param array       $query_args   Optional. Array of additional query args to be appended to the link.
 * @param string      $preview_link Optional. Base preview link to be used if it should differ from the post permalink.
 * @return string URL used for the post preview.
 */
function get_preview_post_link($post = null, $query_args = array(), $preview_link = '')
{
    $post = get_post($post);
    if (!$post) {
        return;
    }
    $post_type_object = get_post_type_object($post->post_type);
    if (is_post_type_viewable($post_type_object)) {
        if (!$preview_link) {
            $preview_link = get_permalink($post);
        }
        $query_args['preview'] = 'true';
        $preview_link = add_query_arg($query_args, $preview_link);
    }
    /**
     * Filter the URL used for a post preview.
     *
     * @since 2.0.5
     * @since 4.0.0 Added the `$post` parameter.
     *
     * @param string  $preview_link URL used for the post preview.
     * @param WP_Post $post         Post object.
     */
    return apply_filters('preview_post_link', $preview_link, $post);
}
    wp_enqueue_media(array('post' => $post_ID));
}
// Add the local autosave notice HTML
add_action('admin_footer', '_local_storage_notice');
/*
 * @todo Document the $messages array(s).
 */
$permalink = get_permalink($post_ID);
if (!$permalink) {
    $permalink = '';
}
$messages = array();
$preview_post_link_html = $scheduled_post_link_html = $view_post_link_html = '';
$preview_page_link_html = $scheduled_page_link_html = $view_page_link_html = '';
$preview_url = get_preview_post_link($post);
$viewable = is_post_type_viewable($post_type_object);
if ($viewable) {
    // Preview post link.
    $preview_post_link_html = sprintf(' <a target="_blank" href="%1$s">%2$s</a>', esc_url($preview_url), __('Preview post'));
    // Scheduled post preview link.
    $scheduled_post_link_html = sprintf(' <a target="_blank" href="%1$s">%2$s</a>', esc_url($permalink), __('Preview post'));
    // View post link.
    $view_post_link_html = sprintf(' <a href="%1$s">%2$s</a>', esc_url($permalink), __('View post'));
    // Preview page link.
    $preview_page_link_html = sprintf(' <a target="_blank" href="%1$s">%2$s</a>', esc_url($preview_url), __('Preview page'));
    // Scheduled page preview link.
    $scheduled_page_link_html = sprintf(' <a target="_blank" href="%1$s">%2$s</a>', esc_url($permalink), __('Preview page'));
    // View page link.
    $view_page_link_html = sprintf(' <a href="%1$s">%2$s</a>', esc_url($permalink), __('View page'));
}
/* translators: Publish box date format, see https://secure.php.net/date */
Example #6
0
/**
 * Displays post submit form fields.
 *
 * @since 2.7.0
 *
 * @global string $action
 *
 * @param WP_Post  $post Current post object.
 * @param array    $args {
 *     Array of arguments for building the post submit meta box.
 *
 *     @type string   $id       Meta box ID.
 *     @type string   $title    Meta box title.
 *     @type callable $callback Meta box display callback.
 *     @type array    $args     Extra meta box arguments.
 * }
 */
function post_submit_meta_box($post, $args = array())
{
    global $action;
    $post_type = $post->post_type;
    $post_type_object = get_post_type_object($post_type);
    $can_publish = current_user_can($post_type_object->cap->publish_posts);
    ?>
<div class="submitbox" id="submitpost">

<div id="minor-publishing">

<?php 
    // Hidden submit button early on so that the browser chooses the right button when form is submitted with Return key
    ?>
<div style="display:none;">
<?php 
    submit_button(__('Save'), 'button', 'save');
    ?>
</div>

<div id="minor-publishing-actions">
<div id="save-action">
<?php 
    if ('publish' != $post->post_status && 'future' != $post->post_status && 'pending' != $post->post_status) {
        ?>
<input <?php 
        if ('private' == $post->post_status) {
            ?>
style="display:none"<?php 
        }
        ?>
 type="submit" name="save" id="save-post" value="<?php 
        esc_attr_e('Save Draft');
        ?>
" class="button" />
<span class="spinner"></span>
<?php 
    } elseif ('pending' == $post->post_status && $can_publish) {
        ?>
<input type="submit" name="save" id="save-post" value="<?php 
        esc_attr_e('Save as Pending');
        ?>
" class="button" />
<span class="spinner"></span>
<?php 
    }
    ?>
</div>
<?php 
    if (is_post_type_viewable($post_type_object)) {
        ?>
<div id="preview-action">
<?php 
        $preview_link = esc_url(get_preview_post_link($post));
        if ('publish' == $post->post_status) {
            $preview_button = __('Preview Changes');
        } else {
            $preview_button = __('Preview');
        }
        ?>
<a class="preview button" href="<?php 
        echo $preview_link;
        ?>
" target="wp-preview-<?php 
        echo (int) $post->ID;
        ?>
" id="post-preview"><?php 
        echo $preview_button;
        ?>
</a>
<input type="hidden" name="wp-preview" id="wp-preview" value="" />
</div>
<?php 
    }
    // public post type
    /**
     * Fires before the post time/date setting in the Publish meta box.
     *
     * @since 4.4.0
     *
     * @param WP_Post $post WP_Post object for the current post.
     */
    do_action('post_submitbox_minor_actions', $post);
    ?>
<div class="clear"></div>
</div><!-- #minor-publishing-actions -->

<div id="misc-publishing-actions">

<div class="misc-pub-section misc-pub-post-status"><label for="post_status"><?php 
    _e('Status:');
    ?>
</label>
<span id="post-status-display">
<?php 
    switch ($post->post_status) {
        case 'private':
            _e('Privately Published');
            break;
        case 'publish':
            _e('Published');
            break;
        case 'future':
            _e('Scheduled');
            break;
        case 'pending':
            _e('Pending Review');
            break;
        case 'draft':
        case 'auto-draft':
            _e('Draft');
            break;
    }
    ?>
</span>
<?php 
    if ('publish' == $post->post_status || 'private' == $post->post_status || $can_publish) {
        ?>
<a href="#post_status" <?php 
        if ('private' == $post->post_status) {
            ?>
style="display:none;" <?php 
        }
        ?>
class="edit-post-status hide-if-no-js"><span aria-hidden="true"><?php 
        _e('Edit');
        ?>
</span> <span class="screen-reader-text"><?php 
        _e('Edit status');
        ?>
</span></a>

<div id="post-status-select" class="hide-if-js">
<input type="hidden" name="hidden_post_status" id="hidden_post_status" value="<?php 
        echo esc_attr('auto-draft' == $post->post_status ? 'draft' : $post->post_status);
        ?>
" />
<select name='post_status' id='post_status'>
<?php 
        if ('publish' == $post->post_status) {
            ?>
<option<?php 
            selected($post->post_status, 'publish');
            ?>
 value='publish'><?php 
            _e('Published');
            ?>
</option>
<?php 
        } elseif ('private' == $post->post_status) {
            ?>
<option<?php 
            selected($post->post_status, 'private');
            ?>
 value='publish'><?php 
            _e('Privately Published');
            ?>
</option>
<?php 
        } elseif ('future' == $post->post_status) {
            ?>
<option<?php 
            selected($post->post_status, 'future');
            ?>
 value='future'><?php 
            _e('Scheduled');
            ?>
</option>
<?php 
        }
        ?>
<option<?php 
        selected($post->post_status, 'pending');
        ?>
 value='pending'><?php 
        _e('Pending Review');
        ?>
</option>
<?php 
        if ('auto-draft' == $post->post_status) {
            ?>
<option<?php 
            selected($post->post_status, 'auto-draft');
            ?>
 value='draft'><?php 
            _e('Draft');
            ?>
</option>
<?php 
        } else {
            ?>
<option<?php 
            selected($post->post_status, 'draft');
            ?>
 value='draft'><?php 
            _e('Draft');
            ?>
</option>
<?php 
        }
        ?>
</select>
 <a href="#post_status" class="save-post-status hide-if-no-js button"><?php 
        _e('OK');
        ?>
</a>
 <a href="#post_status" class="cancel-post-status hide-if-no-js button-cancel"><?php 
        _e('Cancel');
        ?>
</a>
</div>

<?php 
    }
    ?>
</div><!-- .misc-pub-section -->

<div class="misc-pub-section misc-pub-visibility" id="visibility">
<?php 
    _e('Visibility:');
    ?>
 <span id="post-visibility-display"><?php 
    if ('private' == $post->post_status) {
        $post->post_password = '';
        $visibility = 'private';
        $visibility_trans = __('Private');
    } elseif (!empty($post->post_password)) {
        $visibility = 'password';
        $visibility_trans = __('Password protected');
    } elseif ($post_type == 'post' && is_sticky($post->ID)) {
        $visibility = 'public';
        $visibility_trans = __('Public, Sticky');
    } else {
        $visibility = 'public';
        $visibility_trans = __('Public');
    }
    echo esc_html($visibility_trans);
    ?>
</span>
<?php 
    if ($can_publish) {
        ?>
<a href="#visibility" class="edit-visibility hide-if-no-js"><span aria-hidden="true"><?php 
        _e('Edit');
        ?>
</span> <span class="screen-reader-text"><?php 
        _e('Edit visibility');
        ?>
</span></a>

<div id="post-visibility-select" class="hide-if-js">
<input type="hidden" name="hidden_post_password" id="hidden-post-password" value="<?php 
        echo esc_attr($post->post_password);
        ?>
" />
<?php 
        if ($post_type == 'post') {
            ?>
<input type="checkbox" style="display:none" name="hidden_post_sticky" id="hidden-post-sticky" value="sticky" <?php 
            checked(is_sticky($post->ID));
            ?>
 />
<?php 
        }
        ?>
<input type="hidden" name="hidden_post_visibility" id="hidden-post-visibility" value="<?php 
        echo esc_attr($visibility);
        ?>
" />
<input type="radio" name="visibility" id="visibility-radio-public" value="public" <?php 
        checked($visibility, 'public');
        ?>
 /> <label for="visibility-radio-public" class="selectit"><?php 
        _e('Public');
        ?>
</label><br />
<?php 
        if ($post_type == 'post' && current_user_can('edit_others_posts')) {
            ?>
<span id="sticky-span"><input id="sticky" name="sticky" type="checkbox" value="sticky" <?php 
            checked(is_sticky($post->ID));
            ?>
 /> <label for="sticky" class="selectit"><?php 
            _e('Stick this post to the front page');
            ?>
</label><br /></span>
<?php 
        }
        ?>
<input type="radio" name="visibility" id="visibility-radio-password" value="password" <?php 
        checked($visibility, 'password');
        ?>
 /> <label for="visibility-radio-password" class="selectit"><?php 
        _e('Password protected');
        ?>
</label><br />
<span id="password-span"><label for="post_password"><?php 
        _e('Password:'******'private');
        ?>
 /> <label for="visibility-radio-private" class="selectit"><?php 
        _e('Private');
        ?>
</label><br />

<p>
 <a href="#visibility" class="save-post-visibility hide-if-no-js button"><?php 
        _e('OK');
        ?>
</a>
 <a href="#visibility" class="cancel-post-visibility hide-if-no-js button-cancel"><?php 
        _e('Cancel');
        ?>
</a>
</p>
</div>
<?php 
    }
    ?>

</div><!-- .misc-pub-section -->

<?php 
    /* translators: Publish box date format, see http://php.net/date */
    $datef = __('M j, Y @ H:i');
    if (0 != $post->ID) {
        if ('future' == $post->post_status) {
            // scheduled for publishing at a future date
            $stamp = __('Scheduled for: <b>%1$s</b>');
        } elseif ('publish' == $post->post_status || 'private' == $post->post_status) {
            // already published
            $stamp = __('Published on: <b>%1$s</b>');
        } elseif ('0000-00-00 00:00:00' == $post->post_date_gmt) {
            // draft, 1 or more saves, no date specified
            $stamp = __('Publish <b>immediately</b>');
        } elseif (time() < strtotime($post->post_date_gmt . ' +0000')) {
            // draft, 1 or more saves, future date specified
            $stamp = __('Schedule for: <b>%1$s</b>');
        } else {
            // draft, 1 or more saves, date specified
            $stamp = __('Publish on: <b>%1$s</b>');
        }
        $date = date_i18n($datef, strtotime($post->post_date));
    } else {
        // draft (no saves, and thus no date specified)
        $stamp = __('Publish <b>immediately</b>');
        $date = date_i18n($datef, strtotime(current_time('mysql')));
    }
    if (!empty($args['args']['revisions_count'])) {
        $revisions_to_keep = wp_revisions_to_keep($post);
        ?>
<div class="misc-pub-section misc-pub-revisions">
<?php 
        if ($revisions_to_keep > 0 && $revisions_to_keep <= $args['args']['revisions_count']) {
            echo '<span title="' . esc_attr(sprintf(__('Your site is configured to keep only the last %s revisions.'), number_format_i18n($revisions_to_keep))) . '">';
            printf(__('Revisions: %s'), '<b>' . number_format_i18n($args['args']['revisions_count']) . '+</b>');
            echo '</span>';
        } else {
            printf(__('Revisions: %s'), '<b>' . number_format_i18n($args['args']['revisions_count']) . '</b>');
        }
        ?>
	<a class="hide-if-no-js" href="<?php 
        echo esc_url(get_edit_post_link($args['args']['revision_id']));
        ?>
"><span aria-hidden="true"><?php 
        _ex('Browse', 'revisions');
        ?>
</span> <span class="screen-reader-text"><?php 
        _e('Browse revisions');
        ?>
</span></a>
</div>
<?php 
    }
    if ($can_publish) {
        // Contributors don't get to choose the date of publish
        ?>
<div class="misc-pub-section curtime misc-pub-curtime">
	<span id="timestamp">
	<?php 
        printf($stamp, $date);
        ?>
</span>
	<a href="#edit_timestamp" class="edit-timestamp hide-if-no-js"><span aria-hidden="true"><?php 
        _e('Edit');
        ?>
</span> <span class="screen-reader-text"><?php 
        _e('Edit date and time');
        ?>
</span></a>
	<fieldset id="timestampdiv" class="hide-if-js">
	<legend class="screen-reader-text"><?php 
        _e('Date and time');
        ?>
</legend>
	<?php 
        touch_time($action === 'edit', 1);
        ?>
	</fieldset>
</div><?php 
        // /misc-pub-section
    }
    ?>

<?php 
    /**
     * Fires after the post time/date setting in the Publish meta box.
     *
     * @since 2.9.0
     * @since 4.4.0 Added the `$post` parameter.
     *
     * @param WP_Post $post WP_Post object for the current post.
     */
    do_action('post_submitbox_misc_actions', $post);
    ?>
</div>
<div class="clear"></div>
</div>

<div id="major-publishing-actions">
<?php 
    /**
     * Fires at the beginning of the publishing actions section of the Publish meta box.
     *
     * @since 2.7.0
     */
    do_action('post_submitbox_start');
    ?>
<div id="delete-action">
<?php 
    if (current_user_can("delete_post", $post->ID)) {
        if (!EMPTY_TRASH_DAYS) {
            $delete_text = __('Delete Permanently');
        } else {
            $delete_text = __('Move to Trash');
        }
        ?>
<a class="submitdelete deletion" href="<?php 
        echo get_delete_post_link($post->ID);
        ?>
"><?php 
        echo $delete_text;
        ?>
</a><?php 
    }
    ?>
</div>

<div id="publishing-action">
<span class="spinner"></span>
<?php 
    if (!in_array($post->post_status, array('publish', 'future', 'private')) || 0 == $post->ID) {
        if ($can_publish) {
            if (!empty($post->post_date_gmt) && time() < strtotime($post->post_date_gmt . ' +0000')) {
                ?>
		<input name="original_publish" type="hidden" id="original_publish" value="<?php 
                esc_attr_e('Schedule');
                ?>
" />
		<?php 
                submit_button(__('Schedule'), 'primary button-large', 'publish', false);
            } else {
                ?>
		<input name="original_publish" type="hidden" id="original_publish" value="<?php 
                esc_attr_e('Publish');
                ?>
" />
		<?php 
                submit_button(__('Publish'), 'primary button-large', 'publish', false);
            }
        } else {
            ?>
		<input name="original_publish" type="hidden" id="original_publish" value="<?php 
            esc_attr_e('Submit for Review');
            ?>
" />
		<?php 
            submit_button(__('Submit for Review'), 'primary button-large', 'publish', false);
        }
    } else {
        ?>
		<input name="original_publish" type="hidden" id="original_publish" value="<?php 
        esc_attr_e('Update');
        ?>
" />
		<input name="save" type="submit" class="button button-primary button-large" id="publish" value="<?php 
        esc_attr_e('Update');
        ?>
" />
<?php 
    }
    ?>
</div>
<div class="clear"></div>
</div>
</div>

<?php 
}
function _cleanup_query_vars()
{
    // clean out globals to stop them polluting wp and wp_query
    foreach ($GLOBALS['wp']->public_query_vars as $v) {
        unset($GLOBALS[$v]);
    }
    foreach ($GLOBALS['wp']->private_query_vars as $v) {
        unset($GLOBALS[$v]);
    }
    foreach (get_taxonomies(array(), 'objects') as $t) {
        if ($t->publicly_queryable && !empty($t->query_var)) {
            $GLOBALS['wp']->add_query_var($t->query_var);
        }
    }
    foreach (get_post_types(array(), 'objects') as $t) {
        if (is_post_type_viewable($t) && !empty($t->query_var)) {
            $GLOBALS['wp']->add_query_var($t->query_var);
        }
    }
}
Example #8
0
/**
 * Display archive links based on type and format.
 *
 * @since 1.2.0
 * @since 4.4.0 $post_type arg was added.
 *
 * @see get_archives_link()
 *
 * @global wpdb      $wpdb
 * @global WP_Locale $wp_locale
 *
 * @param string|array $args {
 *     Default archive links arguments. Optional.
 *
 *     @type string     $type            Type of archive to retrieve. Accepts 'daily', 'weekly', 'monthly',
 *                                       'yearly', 'postbypost', or 'alpha'. Both 'postbypost' and 'alpha'
 *                                       display the same archive link list as well as post titles instead
 *                                       of displaying dates. The difference between the two is that 'alpha'
 *                                       will order by post title and 'postbypost' will order by post date.
 *                                       Default 'monthly'.
 *     @type string|int $limit           Number of links to limit the query to. Default empty (no limit).
 *     @type string     $format          Format each link should take using the $before and $after args.
 *                                       Accepts 'link' (`<link>` tag), 'option' (`<option>` tag), 'html'
 *                                       (`<li>` tag), or a custom format, which generates a link anchor
 *                                       with $before preceding and $after succeeding. Default 'html'.
 *     @type string     $before          Markup to prepend to the beginning of each link. Default empty.
 *     @type string     $after           Markup to append to the end of each link. Default empty.
 *     @type bool       $show_post_count Whether to display the post count alongside the link. Default false.
 *     @type bool|int   $echo            Whether to echo or return the links list. Default 1|true to echo.
 *     @type string     $order           Whether to use ascending or descending order. Accepts 'ASC', or 'DESC'.
 *                                       Default 'DESC'.
 *     @type string     $post_type       Post type. Default 'post'.
 * }
 * @return string|void String when retrieving.
 */
function wp_get_archives($args = '')
{
    global $wpdb, $wp_locale;
    $defaults = array('type' => 'monthly', 'limit' => '', 'format' => 'html', 'before' => '', 'after' => '', 'show_post_count' => false, 'echo' => 1, 'order' => 'DESC', 'post_type' => 'post');
    $r = wp_parse_args($args, $defaults);
    $post_type_object = get_post_type_object($r['post_type']);
    if (!is_post_type_viewable($post_type_object)) {
        return;
    }
    $r['post_type'] = $post_type_object->name;
    if ('' == $r['type']) {
        $r['type'] = 'monthly';
    }
    if (!empty($r['limit'])) {
        $r['limit'] = absint($r['limit']);
        $r['limit'] = ' LIMIT ' . $r['limit'];
    }
    $order = strtoupper($r['order']);
    if ($order !== 'ASC') {
        $order = 'DESC';
    }
    // this is what will separate dates on weekly archive links
    $archive_week_separator = '&#8211;';
    // over-ride general date format ? 0 = no: use the date format set in Options, 1 = yes: over-ride
    $archive_date_format_over_ride = 0;
    // options for daily archive (only if you over-ride the general date format)
    $archive_day_date_format = 'Y/m/d';
    // options for weekly archive (only if you over-ride the general date format)
    $archive_week_start_date_format = 'Y/m/d';
    $archive_week_end_date_format = 'Y/m/d';
    if (!$archive_date_format_over_ride) {
        $archive_day_date_format = get_option('date_format');
        $archive_week_start_date_format = get_option('date_format');
        $archive_week_end_date_format = get_option('date_format');
    }
    $sql_where = $wpdb->prepare("WHERE post_type = %s AND post_status = 'publish'", $r['post_type']);
    /**
     * Filter the SQL WHERE clause for retrieving archives.
     *
     * @since 2.2.0
     *
     * @param string $sql_where Portion of SQL query containing the WHERE clause.
     * @param array  $r         An array of default arguments.
     */
    $where = apply_filters('getarchives_where', $sql_where, $r);
    /**
     * Filter the SQL JOIN clause for retrieving archives.
     *
     * @since 2.2.0
     *
     * @param string $sql_join Portion of SQL query containing JOIN clause.
     * @param array  $r        An array of default arguments.
     */
    $join = apply_filters('getarchives_join', '', $r);
    $output = '';
    $last_changed = wp_cache_get('last_changed', 'posts');
    if (!$last_changed) {
        $last_changed = microtime();
        wp_cache_set('last_changed', $last_changed, 'posts');
    }
    $limit = $r['limit'];
    if ('monthly' == $r['type']) {
        $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM {$wpdb->posts} {$join} {$where} GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date {$order} {$limit}";
        $key = md5($query);
        $key = "wp_get_archives:{$key}:{$last_changed}";
        if (!($results = wp_cache_get($key, 'posts'))) {
            $results = $wpdb->get_results($query);
            wp_cache_set($key, $results, 'posts');
        }
        if ($results) {
            $after = $r['after'];
            foreach ((array) $results as $result) {
                $url = get_month_link($result->year, $result->month);
                if ('post' !== $r['post_type']) {
                    $url = add_query_arg('post_type', $r['post_type'], $url);
                }
                /* translators: 1: month name, 2: 4-digit year */
                $text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($result->month), $result->year);
                if ($r['show_post_count']) {
                    $r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
                }
                $output .= get_archives_link($url, $text, $r['format'], $r['before'], $r['after']);
            }
        }
    } elseif ('yearly' == $r['type']) {
        $query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM {$wpdb->posts} {$join} {$where} GROUP BY YEAR(post_date) ORDER BY post_date {$order} {$limit}";
        $key = md5($query);
        $key = "wp_get_archives:{$key}:{$last_changed}";
        if (!($results = wp_cache_get($key, 'posts'))) {
            $results = $wpdb->get_results($query);
            wp_cache_set($key, $results, 'posts');
        }
        if ($results) {
            $after = $r['after'];
            foreach ((array) $results as $result) {
                $url = get_year_link($result->year);
                if ('post' !== $r['post_type']) {
                    $url = add_query_arg('post_type', $r['post_type'], $url);
                }
                $text = sprintf('%d', $result->year);
                if ($r['show_post_count']) {
                    $r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
                }
                $output .= get_archives_link($url, $text, $r['format'], $r['before'], $r['after']);
            }
        }
    } elseif ('daily' == $r['type']) {
        $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM {$wpdb->posts} {$join} {$where} GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date {$order} {$limit}";
        $key = md5($query);
        $key = "wp_get_archives:{$key}:{$last_changed}";
        if (!($results = wp_cache_get($key, 'posts'))) {
            $results = $wpdb->get_results($query);
            wp_cache_set($key, $results, 'posts');
        }
        if ($results) {
            $after = $r['after'];
            foreach ((array) $results as $result) {
                $url = get_day_link($result->year, $result->month, $result->dayofmonth);
                if ('post' !== $r['post_type']) {
                    $url = add_query_arg('post_type', $r['post_type'], $url);
                }
                $date = sprintf('%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth);
                $text = mysql2date($archive_day_date_format, $date);
                if ($r['show_post_count']) {
                    $r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
                }
                $output .= get_archives_link($url, $text, $r['format'], $r['before'], $r['after']);
            }
        }
    } elseif ('weekly' == $r['type']) {
        $week = _wp_mysql_week('`post_date`');
        $query = "SELECT DISTINCT {$week} AS `week`, YEAR( `post_date` ) AS `yr`, DATE_FORMAT( `post_date`, '%Y-%m-%d' ) AS `yyyymmdd`, count( `ID` ) AS `posts` FROM `{$wpdb->posts}` {$join} {$where} GROUP BY {$week}, YEAR( `post_date` ) ORDER BY `post_date` {$order} {$limit}";
        $key = md5($query);
        $key = "wp_get_archives:{$key}:{$last_changed}";
        if (!($results = wp_cache_get($key, 'posts'))) {
            $results = $wpdb->get_results($query);
            wp_cache_set($key, $results, 'posts');
        }
        $arc_w_last = '';
        if ($results) {
            $after = $r['after'];
            foreach ((array) $results as $result) {
                if ($result->week != $arc_w_last) {
                    $arc_year = $result->yr;
                    $arc_w_last = $result->week;
                    $arc_week = get_weekstartend($result->yyyymmdd, get_option('start_of_week'));
                    $arc_week_start = date_i18n($archive_week_start_date_format, $arc_week['start']);
                    $arc_week_end = date_i18n($archive_week_end_date_format, $arc_week['end']);
                    $url = sprintf('%1$s/%2$s%3$sm%4$s%5$s%6$sw%7$s%8$d', home_url(), '', '?', '=', $arc_year, '&amp;', '=', $result->week);
                    if ('post' !== $r['post_type']) {
                        $url = add_query_arg('post_type', $r['post_type'], $url);
                    }
                    $text = $arc_week_start . $archive_week_separator . $arc_week_end;
                    if ($r['show_post_count']) {
                        $r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
                    }
                    $output .= get_archives_link($url, $text, $r['format'], $r['before'], $r['after']);
                }
            }
        }
    } elseif ('postbypost' == $r['type'] || 'alpha' == $r['type']) {
        $orderby = 'alpha' == $r['type'] ? 'post_title ASC ' : 'post_date DESC, ID DESC ';
        $query = "SELECT * FROM {$wpdb->posts} {$join} {$where} ORDER BY {$orderby} {$limit}";
        $key = md5($query);
        $key = "wp_get_archives:{$key}:{$last_changed}";
        if (!($results = wp_cache_get($key, 'posts'))) {
            $results = $wpdb->get_results($query);
            wp_cache_set($key, $results, 'posts');
        }
        if ($results) {
            foreach ((array) $results as $result) {
                if ($result->post_date != '0000-00-00 00:00:00') {
                    $url = get_permalink($result);
                    if ($result->post_title) {
                        /** This filter is documented in wp-includes/post-template.php */
                        $text = strip_tags(apply_filters('the_title', $result->post_title, $result->ID));
                    } else {
                        $text = $result->ID;
                    }
                    $output .= get_archives_link($url, $text, $r['format'], $r['before'], $r['after']);
                }
            }
        }
    }
    if ($r['echo']) {
        echo $output;
    } else {
        return $output;
    }
}
Example #9
0
 /**
  * Parse request to find correct WordPress query.
  *
  * Sets up the query variables based on the request. There are also many
  * filters and actions that can be used to further manipulate the result.
  *
  * @since 2.0.0
  * @access public
  *
  * @global WP_Rewrite $wp_rewrite
  *
  * @param array|string $extra_query_vars Set the extra query variables.
  */
 public function parse_request($extra_query_vars = '')
 {
     global $wp_rewrite;
     /**
      * Filter whether to parse the request.
      *
      * @since 3.5.0
      *
      * @param bool         $bool             Whether or not to parse the request. Default true.
      * @param WP           $this             Current WordPress environment instance.
      * @param array|string $extra_query_vars Extra passed query variables.
      */
     if (!apply_filters('do_parse_request', true, $this, $extra_query_vars)) {
         return;
     }
     $this->query_vars = array();
     $post_type_query_vars = array();
     if (is_array($extra_query_vars)) {
         $this->extra_query_vars =& $extra_query_vars;
     } elseif (!empty($extra_query_vars)) {
         parse_str($extra_query_vars, $this->extra_query_vars);
     }
     // Process PATH_INFO, REQUEST_URI, and 404 for permalinks.
     // Fetch the rewrite rules.
     $rewrite = $wp_rewrite->wp_rewrite_rules();
     if (!empty($rewrite)) {
         // If we match a rewrite rule, this will be cleared.
         $error = '404';
         $this->did_permalink = true;
         $pathinfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
         list($pathinfo) = explode('?', $pathinfo);
         $pathinfo = str_replace("%", "%25", $pathinfo);
         list($req_uri) = explode('?', $_SERVER['REQUEST_URI']);
         $self = $_SERVER['PHP_SELF'];
         $home_path = trim(parse_url(home_url(), PHP_URL_PATH), '/');
         $home_path_regex = sprintf('|^%s|i', preg_quote($home_path, '|'));
         // Trim path info from the end and the leading home path from the
         // front. For path info requests, this leaves us with the requesting
         // filename, if any. For 404 requests, this leaves us with the
         // requested permalink.
         $req_uri = str_replace($pathinfo, '', $req_uri);
         $req_uri = trim($req_uri, '/');
         $req_uri = preg_replace($home_path_regex, '', $req_uri);
         $req_uri = trim($req_uri, '/');
         $pathinfo = trim($pathinfo, '/');
         $pathinfo = preg_replace($home_path_regex, '', $pathinfo);
         $pathinfo = trim($pathinfo, '/');
         $self = trim($self, '/');
         $self = preg_replace($home_path_regex, '', $self);
         $self = trim($self, '/');
         // The requested permalink is in $pathinfo for path info requests and
         //  $req_uri for other requests.
         if (!empty($pathinfo) && !preg_match('|^.*' . $wp_rewrite->index . '$|', $pathinfo)) {
             $requested_path = $pathinfo;
         } else {
             // If the request uri is the index, blank it out so that we don't try to match it against a rule.
             if ($req_uri == $wp_rewrite->index) {
                 $req_uri = '';
             }
             $requested_path = $req_uri;
         }
         $requested_file = $req_uri;
         $this->request = $requested_path;
         // Look for matches.
         $request_match = $requested_path;
         if (empty($request_match)) {
             // An empty request could only match against ^$ regex
             if (isset($rewrite['$'])) {
                 $this->matched_rule = '$';
                 $query = $rewrite['$'];
                 $matches = array('');
             }
         } else {
             foreach ((array) $rewrite as $match => $query) {
                 // If the requested file is the anchor of the match, prepend it to the path info.
                 if (!empty($requested_file) && strpos($match, $requested_file) === 0 && $requested_file != $requested_path) {
                     $request_match = $requested_file . '/' . $requested_path;
                 }
                 if (preg_match("#^{$match}#", $request_match, $matches) || preg_match("#^{$match}#", urldecode($request_match), $matches)) {
                     if ($wp_rewrite->use_verbose_page_rules && preg_match('/pagename=\\$matches\\[([0-9]+)\\]/', $query, $varmatch)) {
                         // This is a verbose page match, let's check to be sure about it.
                         $page = get_page_by_path($matches[$varmatch[1]]);
                         if (!$page) {
                             continue;
                         }
                         $post_status_obj = get_post_status_object($page->post_status);
                         if (!$post_status_obj->public && !$post_status_obj->protected && !$post_status_obj->private && $post_status_obj->exclude_from_search) {
                             continue;
                         }
                     }
                     // Got a match.
                     $this->matched_rule = $match;
                     break;
                 }
             }
         }
         if (isset($this->matched_rule)) {
             // Trim the query of everything up to the '?'.
             $query = preg_replace("!^.+\\?!", '', $query);
             // Substitute the substring matches into the query.
             $query = addslashes(WP_MatchesMapRegex::apply($query, $matches));
             $this->matched_query = $query;
             // Parse the query.
             parse_str($query, $perma_query_vars);
             // If we're processing a 404 request, clear the error var since we found something.
             if ('404' == $error) {
                 unset($error, $_GET['error']);
             }
         }
         // If req_uri is empty or if it is a request for ourself, unset error.
         if (empty($requested_path) || $requested_file == $self || strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false) {
             unset($error, $_GET['error']);
             if (isset($perma_query_vars) && strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false) {
                 unset($perma_query_vars);
             }
             $this->did_permalink = false;
         }
     }
     /**
      * Filter the query variables whitelist before processing.
      *
      * Allows (publicly allowed) query vars to be added, removed, or changed prior
      * to executing the query. Needed to allow custom rewrite rules using your own arguments
      * to work, or any other custom query variables you want to be publicly available.
      *
      * @since 1.5.0
      *
      * @param array $public_query_vars The array of whitelisted query variables.
      */
     $this->public_query_vars = apply_filters('query_vars', $this->public_query_vars);
     foreach (get_post_types(array(), 'objects') as $post_type => $t) {
         if (is_post_type_viewable($t) && $t->query_var) {
             $post_type_query_vars[$t->query_var] = $post_type;
         }
     }
     foreach ($this->public_query_vars as $wpvar) {
         if (isset($this->extra_query_vars[$wpvar])) {
             $this->query_vars[$wpvar] = $this->extra_query_vars[$wpvar];
         } elseif (isset($_POST[$wpvar])) {
             $this->query_vars[$wpvar] = $_POST[$wpvar];
         } elseif (isset($_GET[$wpvar])) {
             $this->query_vars[$wpvar] = $_GET[$wpvar];
         } elseif (isset($perma_query_vars[$wpvar])) {
             $this->query_vars[$wpvar] = $perma_query_vars[$wpvar];
         }
         if (!empty($this->query_vars[$wpvar])) {
             if (!is_array($this->query_vars[$wpvar])) {
                 $this->query_vars[$wpvar] = (string) $this->query_vars[$wpvar];
             } else {
                 foreach ($this->query_vars[$wpvar] as $vkey => $v) {
                     if (!is_object($v)) {
                         $this->query_vars[$wpvar][$vkey] = (string) $v;
                     }
                 }
             }
             if (isset($post_type_query_vars[$wpvar])) {
                 $this->query_vars['post_type'] = $post_type_query_vars[$wpvar];
                 $this->query_vars['name'] = $this->query_vars[$wpvar];
             }
         }
     }
     // Convert urldecoded spaces back into +
     foreach (get_taxonomies(array(), 'objects') as $taxonomy => $t) {
         if ($t->query_var && isset($this->query_vars[$t->query_var])) {
             $this->query_vars[$t->query_var] = str_replace(' ', '+', $this->query_vars[$t->query_var]);
         }
     }
     // Don't allow non-publicly queryable taxonomies to be queried from the front end.
     if (!is_admin()) {
         foreach (get_taxonomies(array('publicly_queryable' => false), 'objects') as $taxonomy => $t) {
             /*
              * Disallow when set to the 'taxonomy' query var.
              * Non-publicly queryable taxonomies cannot register custom query vars. See register_taxonomy().
              */
             if (isset($this->query_vars['taxonomy']) && $taxonomy === $this->query_vars['taxonomy']) {
                 unset($this->query_vars['taxonomy'], $this->query_vars['term']);
             }
         }
     }
     // Limit publicly queried post_types to those that are publicly_queryable
     if (isset($this->query_vars['post_type'])) {
         $queryable_post_types = get_post_types(array('publicly_queryable' => true));
         if (!is_array($this->query_vars['post_type'])) {
             if (!in_array($this->query_vars['post_type'], $queryable_post_types)) {
                 unset($this->query_vars['post_type']);
             }
         } else {
             $this->query_vars['post_type'] = array_intersect($this->query_vars['post_type'], $queryable_post_types);
         }
     }
     // Resolve conflicts between posts with numeric slugs and date archive queries.
     $this->query_vars = wp_resolve_numeric_slug_conflicts($this->query_vars);
     foreach ((array) $this->private_query_vars as $var) {
         if (isset($this->extra_query_vars[$var])) {
             $this->query_vars[$var] = $this->extra_query_vars[$var];
         }
     }
     if (isset($error)) {
         $this->query_vars['error'] = $error;
     }
     /**
      * Filter the array of parsed query variables.
      *
      * @since 2.1.0
      *
      * @param array $query_vars The array of requested query variables.
      */
     $this->query_vars = apply_filters('request', $this->query_vars);
     /**
      * Fires once all query variables for the current request have been parsed.
      *
      * @since 2.1.0
      *
      * @param WP &$this Current WordPress environment instance (passed by reference).
      */
     do_action_ref_array('parse_request', array(&$this));
 }
 /**
  * @ticket 35609
  */
 public function test_should_return_false_for_bad_post_type_name()
 {
     $this->assertFalse(is_post_type_viewable('foo'));
 }
 /**
  * Retrieves a single post.
  *
  * @since 4.7.0
  * @access public
  *
  * @param WP_REST_Request $request Full details about the request.
  * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
  */
 public function get_item($request)
 {
     $id = (int) $request['id'];
     $post = get_post($id);
     if (empty($id) || empty($post->ID) || $this->post_type !== $post->post_type) {
         return new WP_Error('rest_post_invalid_id', __('Invalid post ID.'), array('status' => 404));
     }
     $data = $this->prepare_item_for_response($post, $request);
     $response = rest_ensure_response($data);
     if (is_post_type_viewable(get_post_type_object($post->post_type))) {
         $response->link_header('alternate', get_permalink($id), array('type' => 'text/html'));
     }
     return $response;
 }
 /**
  * Adds the necessary rewrite rules for the post type.
  *
  * @since 4.6.0
  * @access public
  *
  * @global WP_Rewrite $wp_rewrite WordPress Rewrite Component.
  * @global WP         $wp         Current WordPress environment instance.
  */
 public function add_rewrite_rules()
 {
     global $wp_rewrite, $wp;
     if (false !== $this->query_var && $wp && is_post_type_viewable($this)) {
         $wp->add_query_var($this->query_var);
     }
     if (false !== $this->rewrite && (is_admin() || '' != get_option('permalink_structure'))) {
         if ($this->hierarchical) {
             add_rewrite_tag("%{$this->name}%", '(.+?)', $this->query_var ? "{$this->query_var}=" : "post_type={$this->name}&pagename=");
         } else {
             add_rewrite_tag("%{$this->name}%", '([^/]+)', $this->query_var ? "{$this->query_var}=" : "post_type={$this->name}&name=");
         }
         if ($this->has_archive) {
             $archive_slug = true === $this->has_archive ? $this->rewrite['slug'] : $this->has_archive;
             if ($this->rewrite['with_front']) {
                 $archive_slug = substr($wp_rewrite->front, 1) . $archive_slug;
             } else {
                 $archive_slug = $wp_rewrite->root . $archive_slug;
             }
             add_rewrite_rule("{$archive_slug}/?\$", "index.php?post_type={$this->name}", 'top');
             if ($this->rewrite['feeds'] && $wp_rewrite->feeds) {
                 $feeds = '(' . trim(implode('|', $wp_rewrite->feeds)) . ')';
                 add_rewrite_rule("{$archive_slug}/feed/{$feeds}/?\$", "index.php?post_type={$this->name}" . '&feed=$matches[1]', 'top');
                 add_rewrite_rule("{$archive_slug}/{$feeds}/?\$", "index.php?post_type={$this->name}" . '&feed=$matches[1]', 'top');
             }
             if ($this->rewrite['pages']) {
                 add_rewrite_rule("{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?\$", "index.php?post_type={$this->name}" . '&paged=$matches[1]', 'top');
             }
         }
         $permastruct_args = $this->rewrite;
         $permastruct_args['feed'] = $permastruct_args['feeds'];
         add_permastruct($this->name, "{$this->rewrite['slug']}/%{$this->name}%", $permastruct_args);
     }
 }
Example #13
0
 /**
  * Get the formatted date & time for the activity
  *
  * @since 0.1.0
  *
  * @param   int  $post_id
  *
  * @return  string
  */
 protected function get_how_long_ago($post_id = 0)
 {
     // Get the post
     $post = get_post($post_id);
     $date = get_the_date(get_option('date_format'), $post->ID);
     $time = get_the_time(get_option('time_format'), $post->ID);
     $both = "{$date} {$time}";
     // Get the human readable difference
     $pt = strtotime($post->post_date_gmt);
     $human = wp_user_activity_human_diff_time($pt, current_time('timestamp', true));
     // Start with the timestamp
     $classes = get_post_class('wp-user-activity', $post->ID);
     $url = false;
     $retval = '<time class="diff-time" pubdate datetime="' . esc_attr($both) . '" title="' . esc_attr($both) . '">' . sprintf('%s ago', $human) . '</time>';
     // Edit link
     if (is_admin() && current_user_can('edit_activity', $post->ID)) {
         $classes[] = 'edit-link';
         $url = get_edit_post_link($post->ID);
         // View link
     } elseif (is_post_type_viewable(get_post_type_object($post->post_type))) {
         $classes[] = 'view-link';
         $url = get_post_permalink($post->ID);
     }
     // Wrap time in anchor tag
     if (!empty($url)) {
         $retval = '<a href="' . esc_url($url) . '" class="' . join(' ', $classes) . '">' . $retval . '</a>';
     }
     return $retval;
 }
Example #14
0
     $post->post_type = $post_type;
     $post->post_parent = $post_parent;
 }
 $post->post_status = 'publish';
 $post->post_name = $slug;
 if ($post->post_type === 'page') {
 }
 $desired_permalink = get_permalink($post);
 $parsed = parse_url($desired_permalink);
 $desired_path = trim($parsed['path'], '/');
 /*
  * Copied from $wp->parse_request(). This function seems to do a lot of housekeeping
  * which should probably be accessible if other things should be able to mock out and fake requests.
  */
 foreach (get_post_types(array(), 'objects') as $post_type => $t) {
     if (is_post_type_viewable($t) && $t->query_var) {
         $post_type_query_vars[$t->query_var] = $post_type;
     }
 }
 // Find a rewrite. Depends on #18877.
 $rewrite = $wp_rewrite->wp_rewrite_rules();
 $found_rewrite_match = $wp_rewrite->find_match($desired_path, $desired_path, $rewrite);
 if ($found_rewrite_match) {
     $query_string = $found_rewrite_match[1];
     parse_str($query_string, $query_args);
     foreach ($wp->public_query_vars as $wpvar) {
         if (!empty($query_args[$wpvar])) {
             if (isset($post_type_query_vars[$wpvar])) {
                 $query_args['post_type'] = $post_type_query_vars[$wpvar];
                 $query_args['name'] = $query_args[$wpvar];
                 // Unset the `{post_type_name}` query variable, as the `name` qv will suffice.
 public function queue_post_purge($post_id)
 {
     if ($this->site_cache_purged) {
         return false;
     }
     if (defined('WP_IMPORTING')) {
         $this->purge_site_cache();
         return false;
     }
     $post = get_post($post_id);
     if (empty($post) || 'revision' === $post->post_type || !in_array(get_post_status($post_id), array('publish', 'inherit', 'trash'), true)) {
         return false;
     }
     if (!is_post_type_viewable($post->post_type)) {
         return;
     }
     $post_purge_urls = array();
     $post_purge_urls[] = get_permalink($post_id);
     $post_purge_urls[] = home_url('/');
     // Don't just purge the attachment page, but also include the file itself
     if ('attachment' === $post->post_type) {
         $this->purge_urls[] = wp_get_attachment_url($post_id);
     }
     $taxonomies = get_object_taxonomies($post, 'object');
     foreach ($taxonomies as $taxonomy) {
         if (true !== $taxonomy->public) {
             continue;
         }
         $taxonomy_name = $taxonomy->name;
         $terms = get_the_terms($post_id, $taxonomy_name);
         if (false === $terms) {
             continue;
         }
         foreach ($terms as $term) {
             $post_purge_urls = array_merge($post_purge_urls, $this->get_purge_urls_for_term($term));
         }
     }
     // Purge the standard site feeds
     // @TODO Do we need to PURGE the comment feeds if the post_status is publish?
     $site_feeds = array(get_bloginfo('rdf_url'), get_bloginfo('rss_url'), get_bloginfo('rss2_url'), get_bloginfo('atom_url'), get_bloginfo('comments_atom_url'), get_bloginfo('comments_rss2_url'), get_post_comments_feed_link($post_id));
     $post_purge_urls = array_merge($post_purge_urls, $site_feeds);
     /**
      * Allows adding URLs to be PURGEd from cache when a given post ID is PURGEd
      *
      * Developers can hook this filter and check the post being purged in order
      * to also purge related URLs, e.g. feeds.
      *
      * Related category archives, tag archives, generic feeds, etc, are already
      * included to be purged (see code above).
      *
      * PLEASE NOTE: Your site benefits from the performance that our HTTP
      * Reverse Proxy Caching provides, and purging URLs from that cache
      * should be done cautiously. VIP may push back on use of this filter
      * during initial code review and pre-deployment review where we
      * see issues.
      *
      * @deprecated 1.1 Use `wpcom_vip_cache_purge_{post_type}_urls` instead
      * @param array $this->purge_urls {
      *     An array of URLs for you to add to
      * }
      * @param type  $post_id The ID of the post which is the primary reason for the purge
      */
     $post_purge_urls = apply_filters('wpcom_vip_cache_purge_urls', $post_purge_urls, $post_id);
     $this->purge_urls = array_merge($this->purge_urls, $post_purge_urls);
     /**
      * Allows adding URLs to be PURGEd from cache when a given post ID is PURGEd
      *
      * Developers can hook this filter and check the post being purged in order
      * to also purge related URLs, e.g. feeds.
      *
      * Related category archives, tag archives, generic feeds, etc, are already
      * included to be purged (see code above).
      *
      * PLEASE NOTE: Your site benefits from the performance that our HTTP
      * Reverse Proxy Caching provides, and purging URLs from that cache
      * should be done cautiously. VIP may push back on use of this filter
      * during initial code review and pre-deployment review where we
      * see issues.
      *
      * @param array $this->purge_urls {
      *     An array of URLs for you to add to
      * }
      * @param type  $post_id The ID of the post which is the primary reason for the purge
      */
     $this->purge_urls = apply_filters("wpcom_vip_cache_purge_{$post->post_type}_post_urls", $this->purge_urls, $post_id);
     $this->purge_urls = array_unique($this->purge_urls);
     return true;
 }