status_taxonomy)) register_taxonomy( $this->status_taxonomy, 'post', array('hierarchical' => false, 'update_count_callback' => '_update_post_term_count', 'label' => false, 'query_var' => false, 'rewrite' => false) );
// Hooks to add "status" column to Edit Posts page
// BUT, only add it if not being filtered by post_status
if(!(isset($_GET['post_status'])) && !(isset($_POST['post_status']))) {
add_filter('manage_posts_columns', array('custom_status', '_filter_manage_posts_columns'));
add_action('manage_posts_custom_column', array('custom_status', '_filter_manage_posts_custom_column'));
}
// Add actions and filters for the Edit/Manage Posts page
add_action('load-edit.php', array(&$this, 'load_edit_hooks'));
} // END: __construct()
/**
* Hooks to make modifications to the Manage/Edit Posts
*/
function load_edit_hooks() {
// Add custom stati to Edit/Manage Posts
add_action('admin_notices',array(&$this, 'enable_custom_status_filters'));
// Modify the posts_where query to include custom stati
add_filter('posts_where', array(&$this, 'custom_status_where_filter'));
} // END: load_edit_hooks()
/**
* Adds custom stati to the $post_stati array.
* This is used to generate the list of statuses on the Edit/Manage Posts page.
*
*/
function enable_custom_status_filters() {
// This is the array WP uses to store custom stati (really? stati?)
// The status list at the top of the Manage/Edit Posts page is generated using this array
global $post_stati;
if(is_array($post_stati)) {
// @ TODO Don't return statuses that are empty (i.e. no posts)
// Get a list of ALL the custom statuses
$custom_statuses = $this->get_custom_statuses();
// Alright, now append them to the $post_stati array
foreach($custom_statuses as $status) {
if(!$this->is_restricted_status($status->slug)) {
$slug = $status->slug;
$post_stati[$slug] = array(
$status->name,
$status->description,
array(
$status->name.' (%s)',
$status->name.' (%s)'
)
);
}
}
}
} // END: enable_custom_status_filters()
/**
* Edits the WHERE clause for the the get_post query.
* This is used to show all the posts with custom statuses.
* Why? Because WordPress automatically hides anything without an allowed status (e.g. "publish", "draft",, etc.)
*/
function custom_status_where_filter($where){
global $wpdb;
if(is_admin()) {
if(!(isset($_GET['post_status'])) && !(isset($_POST['post_status']))) {
$custom_statuses = $this->get_custom_statuses();
foreach($custom_statuses as $status) {
$where .= " OR ".$wpdb->posts.".post_status = '".$status->slug."'";
}
} else {
// Okay, we're filtering by statuses
$status = $_GET['post_status'];
// if not one of inbuilt custom statuses, delete query where AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'future' OR wp_posts.post_status = 'draft' OR wp_posts.post_status = 'pending' OR wp_posts.post_status = 'private')
// append status to where
if(is_term($status, $this->status_taxonomy)) {
$where = "AND ".$wpdb->posts.".post_type = 'post' AND (".$wpdb->posts.".post_status = '".$status."')";
}
}
}
return $where;
} // END: custom_status_where_filter()
/**
* Adds a new custom status as a term in the wp_terms table.
* Basically a wrapper for the wp_insert_term class.
*
* The arguments decide how the term is handled based on the $args parameter.
* The following is a list of the available overrides and the defaults.
*
* 'description'. There is no default. If exists, will be added to the database
* along with the term. Expected to be a string.
*
* 'slug'. Expected to be a string. There is no default.
*
* @param int|string $term The status to add or update
* @param array|string $args Change the values of the inserted term
* @return array|WP_Error The Term ID and Term Taxonomy ID
*
*/
function add_custom_status ( $term, $args = array() ) {
// $args = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '');
return wp_insert_term( $term, $this->status_taxonomy, $args );
} // END: add_custom_status
/**
*
* Basically a wrapper for the wp_update_term function
*/
function update_custom_status ( $status_id, $args = array() ) {
// Reassign posts to new status slug
$old_status = get_term($status_id, $this->status_taxonomy)->slug;
// if($old_status != 'draft' || $old_status != 'pending' || $old_status != 'publish') {
if(!$this->is_restricted_status($old_status)) {
// If new status not indicated, set to "draft", else get slug for new status
$new_status = $args['slug'];
$this->reassign_post_status( $old_status, $new_status );
}
return wp_update_term( $status_id, $this->status_taxonomy, $args );
} // END: update_custom_status
/**
* Deletes a custom status from the wp_terms table.
*
* Partly a wrapper for the wp_delete_term function.
* BUT, also reassigns posts that currently have the deleted status assigned.
*/
function delete_custom_status ( $status_id, $args = array(), $reassign = '' ) {
// Reassign posts to alternate status
// Get slug for the old status
$old_status = get_term($status_id, $this->status_taxonomy)->slug;
if(!$this->is_restricted_status($old_status)) {
// If new status not indicated, set to "draft", else get slug for new status
if(!$reassign) $new_status = 'draft';
else $new_status = get_term($reassign, $this->status_taxonomy)->slug;
$this->reassign_post_status( $old_status, $new_status );
}
return wp_delete_term( $status_id, $this->status_taxonomy, $args );
} // END: delete_custom_status
function get_custom_statuses ($statuses = '', $args ='' ) {
// @TODO: implement $args, to allow for pagination, etc.
if(!$statuses) {
// return all stati
$statuses = get_terms( $this->status_taxonomy, array( 'get' => 'all' ) );
} else if (!is_array($statuses)) {
// return a single status
} else {
// return multiple stati
}
return $statuses;
}
function reassign_post_status( $old_status, $new_status = 'draft' ) {
global $wpdb;
// Make the database call
$result = $wpdb->update( $wpdb->posts, array( 'post_status' => $new_status ), array( 'post_status' => $old_status ), array( '%s' ));
}
/**
* Insert new column header for post status
*
* @param array $post_columns
**/
function _filter_manage_posts_columns($posts_columns) {
$result = array();
foreach ($posts_columns as $key => $value) {
if ($key == 'author') {
$result[$key] = $value;
$result['status'] = __('Status', 'edit-flow');
} else $result[$key] = $value;
}
return $result;
} // END: _filter_manage_posts_columns
/**
* Adds a Post's status to its row on the Edit page
*
* @param string $column_name
**/
function _filter_manage_posts_custom_column($column_name) {
if ($column_name == 'status') {
global $post, $custom_status;
echo get_status_name('slug' , $post->post_status);
}
}
/**
* Determines whether the slug indicated belongs to a restricted status or not
* @param string Slug of the status
* @return bool True if restricted, false if not
*/
function is_restricted_status ( $slug ) {
switch($slug) {
case 'publish':
case 'draft':
case 'private':
case 'future':
case 'pending':
case 'new':
case 'inherit':
$return = true;
break;
default:
$return = false;
break;
}
return $return;
}
function admin_page ( ) {
global $wpdb, $edit_flow;
// @TODO JS form validation
$nonce_fail_msg = __('There\'s something fishy going on! We don\'t like this type of nonce-sense. Hmph.');
$msg_class = 'updated';
$action = ($_POST['action']) ? $wpdb->escape($_POST['action']) : $wpdb->escape($_GET['action']);
switch($action) {
case 'add':
// Verfiy nonce
if(wp_verify_nonce($_POST['custom-status-add-nonce'], 'custom-status-add-nonce')) {
// @TODO Make sure content is secure, ie: check inputs so nothing nasty gets through
// Check if name field was filled in
if(!($name = $_POST['status_name'])) {
$error_details = __('Please enter a name for the status');
break;
}
// Check to make sure the name is not restricted
if($this->is_restricted_status(strtolower(trim($name)))) {
$error_details = __('That status name is restricted. Please use another name.');
break;
}
// Check to make sure the status doesn't already exist
if(is_term(sanitize_title($_POST['status_name']))) {
$error_details = __('That status already exists. Please use another name.');
break;
}
$args = array('description' => $_POST['status_description'], 'slug' => sanitize_title($_POST['status_name']) );
// Try to add the status
$return = $this->add_custom_status($name, $args);
if(!is_wp_error($return)) {
$msg = __('Status successfully added.');
} else {
$error_details = __('Could not add the status: ') . $return->get_error_message();
}
} else {
$error_details = $nonce_fail_msg;
}
break;
case 'edit':
$term_id = (int) $_GET['term_id'];
if($term_id && $the_status = get_term($term_id, $this->status_taxonomy)) {
// Stop users from editing restricted statuses
if($this->is_restricted_status($the_status->slug)) {
$error_details = __('That status is restricted and cannot be edited. You are welcome to delete it, however.');
$update = false;
} else {
$update = true;
$edit_status = $the_status;
}
}
break;
case 'update':
// @TODO if updated status is the same as the default_status, update the default
// Verfiy nonce
if(wp_verify_nonce($_POST['custom-status-add-nonce'], 'custom-status-add-nonce')) {
$term_id = (int) $_POST['term_id'];
$status_name = $_POST['status_name'];
$status_description = $_POST['status_description'];
$status_slug = sanitize_title($_POST['status_name']);
// Check to make sure the status doesn't already exist
if(is_term(sanitize_title($_POST['status_name'])) && (get_term($term_id, $this->status_taxonomy)->slug != $status_slug)) {
$error_details = __('That status already exists. Please use another name.');
break;
}
// get status_name & status_description
$args = array( 'name' => $status_name, 'description' => $status_description, 'slug' => $status_slug );
$return = $this->update_custom_status($term_id, $args);
if(!is_wp_error($return)) {
$msg = __('Status successfully updated.');
} else {
$error_details = __('Could not update the status: ') . $return->get_error_message();
}
} else {
$error_details = $nonce_fail_msg;
}
break;
case 'delete':
// @TODO if updated status is the same as the default_status, update the default
// Verfiy nonce
if(wp_verify_nonce($_GET['_wpnonce'], 'custom-status-delete-nonce')) {
$term_id = (int) $_GET['term_id'];
// Check to make sure the status doesn't already exist
if(!is_term($term_id, $this->status_taxonomy)) {
$error_details = __('That status does not exist. Try again?');
break;
}
$return = $this->delete_custom_status($term_id);
if(!is_wp_error($return)) {
$msg = __('Status successfully deleted.');
} else {
$error_details = __('Could not delete the status: ') . $return->get_error_message();
}
} else {
$error_details = $nonce_fail_msg;
}
break;
default:
$update = false;
break;
}
if($error_details) {
$msg = __('There was an error with your request. ');
$msg .= '
'.$error_details.'';
$msg_class = 'error';
}
$statuses = $this->get_custom_statuses();
?>
enable them.') ?>
|
name ?>
|
description ?> |
Note:
Deleting a status does not delete the posts assigned that status. Instead, the posts will be set to the default status: Draft') ?>.