From 339e87dc5ce233330b4f8ba8990337733ffe2afc Mon Sep 17 00:00:00 2001 From: azaozz Date: Thu, 25 Sep 2008 13:42:34 +0000 Subject: [PATCH] Batch editing, first cut, see #6815 git-svn-id: http://svn.automattic.com/wordpress/trunk@8973 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/admin-ajax.php | 9 +- wp-admin/categories.php | 2 +- wp-admin/css/global.css | 3 +- wp-admin/edit-comments.php | 2 +- wp-admin/edit-link-categories.php | 2 +- wp-admin/edit-pages.php | 86 +++++++++++----- wp-admin/edit-post-rows.php | 2 - wp-admin/edit-tags.php | 2 +- wp-admin/edit.php | 52 +++++++--- wp-admin/inbox.php | 2 +- wp-admin/includes/post.php | 62 ++++++++++++ wp-admin/includes/template.php | 152 ++++++++++++++++++---------- wp-admin/js/inline-edit.js | 162 ++++++++++++++++++++---------- wp-admin/link-manager.php | 2 +- wp-admin/plugins.php | 4 +- wp-admin/upload.php | 2 +- wp-admin/users.php | 2 +- wp-admin/wp-admin.css | 41 +++++++- 18 files changed, 422 insertions(+), 167 deletions(-) diff --git a/wp-admin/admin-ajax.php b/wp-admin/admin-ajax.php index 62346c649f..4af1775b81 100644 --- a/wp-admin/admin-ajax.php +++ b/wp-admin/admin-ajax.php @@ -731,8 +731,15 @@ break; case 'inline-save': check_ajax_referer( 'inlineeditnonce', '_inline_edit' ); - if ( ! isset($_POST['post_ID']) ) + if ( ! isset($_POST['post_ID']) || ! ( $id = (int) $_POST['post_ID'] ) ) exit; + + if ( $last = wp_check_post_lock( $id ) ) { + $last_user = get_userdata( $last ); + $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' ); + echo '

' . sprintf( $_POST['post_type'] == 'page' ? __( 'Saving is disabled: %s is currently editing this page.' ) : __( 'Saving is disabled: %s is currently editing this post.' ), wp_specialchars( $last_user_name ) ) . '

'; + exit; + } inline_save_row( $_POST ); diff --git a/wp-admin/categories.php b/wp-admin/categories.php index c75bbf95b4..091c580173 100644 --- a/wp-admin/categories.php +++ b/wp-admin/categories.php @@ -178,7 +178,7 @@ if ( $page_links ) - + diff --git a/wp-admin/css/global.css b/wp-admin/css/global.css index 854e72160d..feaaede747 100644 --- a/wp-admin/css/global.css +++ b/wp-admin/css/global.css @@ -204,7 +204,8 @@ th.check-column + th, th.check-column + td { padding-left: 5px; } */ -.widefat .num { +.widefat .num, +.widefat .column-comments { text-align: center; } diff --git a/wp-admin/edit-comments.php b/wp-admin/edit-comments.php index 66817495c5..e582bd0127 100644 --- a/wp-admin/edit-comments.php +++ b/wp-admin/edit-comments.php @@ -195,7 +195,7 @@ if ( $page_links ) - + diff --git a/wp-admin/edit-link-categories.php b/wp-admin/edit-link-categories.php index 29fcbb1076..d189e0dc10 100644 --- a/wp-admin/edit-link-categories.php +++ b/wp-admin/edit-link-categories.php @@ -118,7 +118,7 @@ if ( $page_links ) - + diff --git a/wp-admin/edit-pages.php b/wp-admin/edit-pages.php index a4f641a24f..bee05d91fc 100644 --- a/wp-admin/edit-pages.php +++ b/wp-admin/edit-pages.php @@ -9,33 +9,52 @@ /** WordPress Administration Bootstrap */ require_once('admin.php'); -// Handle bulk deletes -if ( isset($_GET['action']) && isset($_GET['post']) && isset($_GET['doaction']) ) { - check_admin_referer('bulk-pages'); - if ( $_GET['action'] == 'delete' ) { - foreach( (array) $_GET['post'] as $post_id_del ) { - $post_del = & get_post($post_id_del); - - if ( !current_user_can('delete_page', $post_id_del) ) - wp_die( __('You are not allowed to delete this page.') ); - - if ( $post_del->post_type == 'attachment' ) { - if ( ! wp_delete_attachment($post_id_del) ) - wp_die( __('Error in deleting...') ); - } else { - if ( !wp_delete_post($post_id_del) ) - wp_die( __('Error in deleting...') ); +// Handle bulk actions +if ( isset($_GET['action']) && $_GET['action'] != -1 ) { + switch ( $_GET['action'] ) { + case 'delete': + if ( isset($_GET['post']) && isset($_GET['doaction']) ) { + check_admin_referer('bulk-pages'); + foreach( (array) $_GET['post'] as $post_id_del ) { + $post_del = & get_post($post_id_del); + + if ( !current_user_can('delete_page', $post_id_del) ) + wp_die( __('You are not allowed to delete this page.') ); + + if ( $post_del->post_type == 'attachment' ) { + if ( ! wp_delete_attachment($post_id_del) ) + wp_die( __('Error in deleting...') ); + } else { + if ( !wp_delete_post($post_id_del) ) + wp_die( __('Error in deleting...') ); + } + } } - } - - $sendback = wp_get_referer(); - if (strpos($sendback, 'page.php') !== false) $sendback = admin_url('page-new.php'); - elseif (strpos($sendback, 'attachments.php') !== false) $sendback = admin_url('attachments.php'); - $sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback); - - wp_redirect($sendback); - exit(); + break; + case 'edit': + if ( isset($_GET['post']) ) { + check_admin_referer('bulk-pages'); + $_GET['post_status'] = $_GET['_status']; + + if ( -1 == $_GET['post_author'] ) + unset($_GET['post_author']); + + $done = bulk_edit_posts($_GET); + } + break; } + $sendback = wp_get_referer(); + if (strpos($sendback, 'page.php') !== false) $sendback = admin_url('page-new.php'); + elseif (strpos($sendback, 'attachments.php') !== false) $sendback = admin_url('attachments.php'); + $sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback); + if ( isset($done) ) { + $done['upd'] = count( $done['upd'] ); + $done['skip'] = count( $done['skip'] ); + $sendback = add_query_arg( $done, $sendback ); + unset($done); + } + wp_redirect($sendback); + exit(); } elseif ( !empty($_GET['_wp_http_referer']) ) { wp_redirect(remove_query_arg(array('_wp_http_referer', '_wpnonce'), stripslashes($_SERVER['REQUEST_URI']))); exit; @@ -85,6 +104,18 @@ require_once('admin-header.php');

+ +

+ +

+ +
@@ -175,7 +206,7 @@ if ( $page_links ) - +
@@ -197,12 +228,13 @@ if ($posts) { -
+ +
- - - +
diff --git a/wp-admin/edit.php b/wp-admin/edit.php index fe8614b0ab..8a3f3261e2 100644 --- a/wp-admin/edit.php +++ b/wp-admin/edit.php @@ -10,10 +10,10 @@ require_once('admin.php'); // Handle bulk actions -if ( isset($_GET['action']) && $_GET['action'] != -1 && isset($_GET['doaction']) ) { +if ( isset($_GET['action']) && $_GET['action'] != -1 ) { switch ( $_GET['action'] ) { case 'delete': - if ( isset($_GET['post']) ) { + if ( isset($_GET['post']) && isset($_GET['doaction']) ) { check_admin_referer('bulk-posts'); foreach( (array) $_GET['post'] as $post_id_del ) { $post_del = & get_post($post_id_del); @@ -32,14 +32,28 @@ if ( isset($_GET['action']) && $_GET['action'] != -1 && isset($_GET['doaction']) } break; case 'edit': - // TODO: Decide what to do here - add bulk edit feature, or just disallow if >1 post selected + if ( isset($_GET['post']) ) { + check_admin_referer('bulk-posts'); + $_GET['post_status'] = $_GET['_status']; + + if ( -1 == $_GET['post_author'] ) + unset($_GET['post_author']); + + $done = bulk_edit_posts($_GET); + } break; } + $sendback = wp_get_referer(); if (strpos($sendback, 'post.php') !== false) $sendback = admin_url('post-new.php'); elseif (strpos($sendback, 'attachments.php') !== false) $sendback = admin_url('attachments.php'); $sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback); - + if ( isset($done) ) { + $done['upd'] = count( $done['upd'] ); + $done['skip'] = count( $done['skip'] ); + $sendback = add_query_arg( $done, $sendback ); + unset($done); + } wp_redirect($sendback); exit(); } elseif ( !empty($_GET['_wp_http_referer']) ) { @@ -79,6 +93,23 @@ else

+ +

|

+ + + +

+ +

+ +
@@ -154,14 +185,7 @@ unset( $status_links ); - -

|

- - +
    @@ -189,7 +213,7 @@ if ( $page_links ) - + + +
    diff --git a/wp-admin/inbox.php b/wp-admin/inbox.php index 9f068d21a7..343625eaa8 100644 --- a/wp-admin/inbox.php +++ b/wp-admin/inbox.php @@ -31,7 +31,7 @@ endif; - +

diff --git a/wp-admin/includes/post.php b/wp-admin/includes/post.php index e4b62d7af7..fa1cd2b6d9 100644 --- a/wp-admin/includes/post.php +++ b/wp-admin/includes/post.php @@ -177,6 +177,68 @@ function edit_post( $post_data = null ) { return $post_ID; } +function bulk_edit_posts( $post_data = null ) { + + if ( empty($post_data) ) + $post_data = &$_POST; + + if ( 'page' == $post_data['post_type'] ) { + if ( ! current_user_can( 'edit_pages' ) ) + wp_die( __('You are not allowed to edit pages.') ); + } else { + if ( ! current_user_can( 'edit_posts' ) ) + wp_die( __('You are not allowed to edit posts.') ); + } + + $post_IDs = array_map( intval, (array) $post_data['post'] ); + + if ( isset($post_data['post_category']) ) { + if ( is_array($post_data['post_category']) && ! empty($post_data['post_category']) ) + $new_cats = array_map( absint, $post_data['post_category'] ); + else + unset($post_data['post_category']); + } + + if ( isset($post_data['tags_input']) ) { + if ( ! empty($post_data['tags_input']) ) { + $new_tags = preg_replace( '/\s*,\s*/', ',', rtrim($post_data['tags_input'], ' ,') ); + $new_tags = explode(',', $new_tags); + } else { + unset($post_data['tags_input']); + } + } + + $reset = array( 'post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private' ); + foreach ( $reset as $field ) { + if ( isset($post_data[$field]) && '' == $post_data[$field] ) + unset($post_data[$field]); + } + + $updated = $skipped = array(); + foreach ( $post_IDs as $post_ID ) { + + if ( wp_check_post_lock( $post_ID ) ) { + $skipped[] = $post_ID; + continue; + } + + if ( isset($new_cats) ) { + $cats = (array) wp_get_post_categories($post_ID); + $post_data['post_category'] = array_unique( array_merge($cats, $new_cats) ); + } + + if ( isset($new_tags) ) { + $tags = wp_get_post_tags($post_ID, array('fields' => 'names')); + $post_data['tags_input'] = array_unique( array_merge($tags, $new_tags) ); + } + + $post_data['ID'] = $post_ID; + $updated[] = wp_update_post( $post_data ); + } + + return array( 'upd' => $updated, 'skip' => $skipped ); +} + // Default post information to use when populating the "Write Post" form. function get_default_post_to_edit() { if ( !empty( $_REQUEST['post_title'] ) ) diff --git a/wp-admin/includes/template.php b/wp-admin/includes/template.php index 10d2fa6511..0de33fd695 100644 --- a/wp-admin/includes/template.php +++ b/wp-admin/includes/template.php @@ -622,8 +622,14 @@ function inline_edit_row( $type ) { $hidden_count = empty($hidden[0]) ? 0 : count($hidden); $col_count = count($columns) - $hidden_count; $m = ( isset($mode) && 'excerpt' == $mode ) ? 'excerpt' : 'list'; - ?> - + $can_publish = current_user_can('publish_posts'); ?> + + + + + + +
ID . '"> - - - - - - - - - - - - '; +'; } @@ -1035,7 +1079,6 @@ function _post_row($a_post, $pending_comments, $mode) { break; case 'comments': - $attributes = 'class="comments column-comments num"' . $style; ?> >
$column_display_name) { break; case 'comments': - $attributes = 'class="comments column-comments num"' . $style; ?> >
0 ) { + t.revert(); + } + }); + + $('#post-query-submit').click(function(e){ + if ( $('form#posts-filter tr.inline-editor').length > 0 ) + t.revert(); + }); + }, toggle : function(el) { var t = this; - $('#'+t.type+'-'+t.getId(el)).css('display') == 'none' ? t.revert(el) : t.edit(el); + $(t.what+t.getId(el)).css('display') == 'none' ? t.revert() : t.edit(el); }, addEvents : function(r) { @@ -38,48 +78,66 @@ inlineEdit = { }); }, - edit : function(id) { - var t = this, type = t.type, old = $('tr.inline-editor').attr('id'); + setBulk : function() { + var te = '', c = ''; + this.revert(); - if( typeof(id) == 'object' ) + $('table.widefat tbody').prepend( $('#bulk-edit') ); + $('#bulk-edit').addClass('inline-editor').show(); + + $('tbody th.check-column input[type="checkbox"]').each(function(i){ + if ( $(this).attr('checked') ) { + var id = $(this).val(); + c = c == '' ? ' class="alternate"' : ''; + te += ''+$('#inline_'+id+' .post_title').text()+'
'; + } + }); + + $('#bulk-titles').html(te); + + // enable autocomplete for tags + if ( this.type == 'post' ) + $('tr.inline-editor textarea[name="tags_input"]').suggest( 'admin-ajax.php?action=ajax-tag-search', { delay: 500, minchars: 2, multiple: true, multipleSep: ", " } ); + }, + + edit : function(id) { + var t = this; + t.revert(); + + if ( typeof(id) == 'object' ) id = t.getId(id); - if ( old ) { - old = old.split('-')[1]; - t.revert(old); - } - var fields = ['post_title', 'post_name', 'post_author', '_status', 'jj', 'mm', 'aa', 'hh', 'mn', 'post_password']; - if ( type == 'page' ) fields.push('post_parent', 'menu_order', 'page_template'); - if ( type == 'post' ) fields.push('tags_input'); + if ( t.type == 'page' ) fields.push('post_parent', 'menu_order', 'page_template'); + if ( t.type == 'post' ) fields.push('tags_input'); // add the new blank row var editRow = $('#inline-edit').clone(true); - if ( $('#'+type+'-'+id).hasClass('alternate') ) + if ( $(t.what+id).hasClass('alternate') ) $(editRow).addClass('alternate'); - $('#'+type+'-'+id).hide().after(editRow); + $(t.what+id).hide().after(editRow); // populate the data var rowData = $('#inline_'+id); for ( var f = 0; f < fields.length; f++ ) { - $(':input[name="'+fields[f]+'"]', editRow).val( $('.'+fields[f], rowData).val() ); + $(':input[name="'+fields[f]+'"]', editRow).val( $('.'+fields[f], rowData).text() ); } - if ( $('.comment_status', rowData).val() == 'open' ) + if ( $('.comment_status', rowData).text() == 'open' ) $('input[name="comment_status"]', editRow).attr("checked", "checked"); - if ( $('.ping_status', rowData).val() == 'open' ) + if ( $('.ping_status', rowData).text() == 'open' ) $('input[name="ping_status"]', editRow).attr("checked", "checked"); - if ( $('.sticky', rowData).val() == 'sticky' ) + if ( $('.sticky', rowData).text() == 'sticky' ) $('input[name="sticky"]', editRow).attr("checked", "checked"); // categories var cats; - if ( cats = $('.post_category', rowData).val() ) - $('ul.cat-checklist :checkbox').val(cats.split(',')); + if ( cats = $('.post_category', rowData).text() ) + $('ul.cat-checklist :checkbox', editRow).val(cats.split(',')); // handle the post status - var status = $('._status', rowData).val(); + var status = $('._status', rowData).text(); if ( status != 'future' ) $('select[name="_status"] option[value="future"]', editRow).remove(); if ( status == 'private' ) $('input[name="keep_private"]', editRow).attr("checked", "checked"); @@ -99,24 +157,11 @@ inlineEdit = { pageOpt.remove(); } - // categories expandable? - $('span.catshow', editRow).click(function() { - $('ul.cat-checklist', editRow).addClass("cat-hover"); - $('span.cathide', editRow).show(); - $(this).hide(); - }); - - $('span.cathide', editRow).click(function() { - $('ul.cat-checklist', editRow).removeClass("cat-hover"); - $('span.catshow', editRow).show(); - $(this).hide(); - }); - $(editRow).attr('id', 'edit-'+id).addClass('inline-editor').show(); $('.ptitle', editRow).focus(); // enable autocomplete for tags - if ( type == 'post' ) + if ( t.type == 'post' ) $('tr.inline-editor textarea[name="tags_input"]').suggest( 'admin-ajax.php?action=ajax-tag-search', { delay: 500, minchars: 2, multiple: true, multipleSep: ", " } ); return false; @@ -140,25 +185,36 @@ inlineEdit = { // make ajax request $.post('admin-ajax.php', params, - function(html) { - var row = $('#'+inlineEdit.type+'-'+id); - $('#edit-'+id).hide(); - html = $(html).html(); - row.html(html).show(); - row.animate( { backgroundColor: '#FFFBCC' }, 200) - .animate( { backgroundColor: row.css('background-color') }, 500); + function(r) { + var row = $(inlineEdit.what+id); + $('#edit-'+id).remove(); + row.html($(r).html()).show() + .animate( { backgroundColor: '#CCEEBB' }, 500) + .animate( { backgroundColor: '#eefee7' }, 500); inlineEdit.addEvents(row); } ); return false; }, - revert : function(id) { - if ( typeof(id) == 'object' ) - id = this.getId(id); + saveBulk : function() { + $('form#posts-filter').submit(); + }, - $('#edit-'+id).remove(); - $('#'+this.type+'-'+id).show(); + revert : function() { + var id; + + if ( id = $('table.widefat tr.inline-editor').attr('id') ) { + if ( 'bulk-edit' == id ) { + $('table.widefat #bulk-edit').removeClass('inline-editor').hide(); + $('#bulk-titles').html(''); + $('#inlineedit').append( $('#bulk-edit') ); + } else { + $('#'+id).remove(); + id = id.substr( id.lastIndexOf('-') + 1 ); + $(this.what+id).show(); + } + } return false; }, diff --git a/wp-admin/link-manager.php b/wp-admin/link-manager.php index a2eaf4eebc..7c5fe9c80b 100644 --- a/wp-admin/link-manager.php +++ b/wp-admin/link-manager.php @@ -120,7 +120,7 @@ if ( isset($_GET['deleted']) ) { - + \n"; diff --git a/wp-admin/plugins.php b/wp-admin/plugins.php index 5ac1f7fc69..210b3b26d9 100644 --- a/wp-admin/plugins.php +++ b/wp-admin/plugins.php @@ -331,7 +331,7 @@ function print_plugins_table($plugins, $context = '') { - +

@@ -356,7 +356,7 @@ function print_plugins_table($plugins, $context = '') { - + diff --git a/wp-admin/upload.php b/wp-admin/upload.php index 1d05cdb491..6f10c6704a 100644 --- a/wp-admin/upload.php +++ b/wp-admin/upload.php @@ -271,7 +271,7 @@ if ( $page_links ) - + - + diff --git a/wp-admin/wp-admin.css b/wp-admin/wp-admin.css index 5222d3e03f..b56f7927ac 100644 --- a/wp-admin/wp-admin.css +++ b/wp-admin/wp-admin.css @@ -2203,7 +2203,9 @@ a.togbox { } .inline-editor div.title { - padding: 2px 5px; + height: 18px; + line-height: 16px; + padding: 1px 5px; cursor: default; } @@ -2212,6 +2214,12 @@ a.togbox { width: 260px; } +#bulk-edit .post-title, +#bulk-edit .page-title { + width: 200px; + height: 179px; +} + .inline-editor .post-title .ptitle, .inline-editor .page-title .ptitle { width: 245px; @@ -2258,7 +2266,7 @@ a.togbox { } .inline-editor .categories { - width: 180px; + width: 200px; } .inline-editor .categories ul.cat-checklist { @@ -2275,7 +2283,7 @@ a.togbox { .inline-editor .categories ul.cat-hover { height: 200px; - overflow: auto; + overflow-x: auto; } .inline-editor .categories ul.children { @@ -2301,14 +2309,14 @@ a.togbox { } .inline-editor .tags { - width: 220px; + width: 200px; } .inline-editor textarea { border-width: 1px; border-style: solid; height: 45px; - width: 200px; + width: 180px; font-size: 11px; } @@ -2317,10 +2325,33 @@ a.togbox { width: 160px; } +#wpbody-content .inline-editor .comments select { + margin-bottom: 3px; + width: 150px; +} + +.inline-editor .parent { + width: 180px; +} + +#wpbody-content .inline-editor .parent select { + width: 170px; +} + .inline-editor .quick-edit-save { padding: 8px 10px; } +#bulk-titles { + height: 150px; + overflow: auto; + cursor: default; +} + +#bulk-titles div { + padding: 1px 2px; +} + /* Media library */ #wpbody-content .media-item-info tr { background-color: transparent;