Index: trunk/extensions/CodeReview/CodeReview.i18n.php |
— | — | @@ -43,6 +43,7 @@ |
44 | 44 | 'code-field-comments' => 'Notes', |
45 | 45 | 'code-field-path' => 'Path', |
46 | 46 | 'code-field-text' => 'Note', |
| 47 | + 'code-field-select' => 'Select', |
47 | 48 | 'code-rev-author' => 'Author:', |
48 | 49 | 'code-rev-date' => 'Date:', |
49 | 50 | 'code-rev-message' => 'Comment:', |
— | — | @@ -76,6 +77,11 @@ |
77 | 78 | 'code-rev-submit' => 'Save changes', |
78 | 79 | 'code-rev-submit-next' => 'Save & next unresolved', |
79 | 80 | |
| 81 | + 'code-batch-status' => 'Change status:', |
| 82 | + 'code-batch-tags' => 'Change tags:', |
| 83 | + 'codereview-batch-title' => 'Change all selected revisions', |
| 84 | + 'codereview-batch-submit' => 'Submit', |
| 85 | + |
80 | 86 | 'code-releasenotes' => 'release notes', |
81 | 87 | 'code-release-legend' => 'Generate release notes', |
82 | 88 | 'code-release-startrev' => 'Start rev:', |
Index: trunk/extensions/CodeReview/CodeRevisionListView.php |
— | — | @@ -15,22 +15,117 @@ |
16 | 16 | } |
17 | 17 | |
18 | 18 | function execute() { |
19 | | - global $wgOut; |
| 19 | + global $wgOut, $wgUser, $wgRequest; |
20 | 20 | if( !$this->mRepo ) { |
21 | 21 | $view = new CodeRepoListView(); |
22 | 22 | $view->execute(); |
23 | 23 | return; |
24 | 24 | } |
| 25 | + |
| 26 | + // Check for batch change requests. |
| 27 | + $editToken = $wgRequest->getVal( 'wpBatchChangeEditToken' ); |
| 28 | + if ( $wgUser->matchEditToken( $editToken ) ) { |
| 29 | + $this->doBatchChange(); |
| 30 | + return; |
| 31 | + } |
| 32 | + |
25 | 33 | $this->showForm(); |
26 | 34 | $pager = $this->getPager(); |
| 35 | + |
| 36 | + // Batch change interface. |
| 37 | + $changeInterface = $this->buildBatchInterface( $pager ); |
| 38 | + |
27 | 39 | $wgOut->addHTML( |
28 | 40 | $pager->getNavigationBar() . |
29 | 41 | $pager->getLimitForm() . |
| 42 | + Xml::openElement( 'form', |
| 43 | + array( |
| 44 | + 'action' => $pager->getTitle()->getLocalURL(), |
| 45 | + 'method' => 'POST' |
| 46 | + ) ) . |
30 | 47 | $pager->getBody() . |
31 | | - $pager->getNavigationBar() |
| 48 | + $pager->getNavigationBar() . |
| 49 | + $changeInterface . |
| 50 | + Xml::closeElement( 'form' ) |
32 | 51 | ); |
33 | 52 | } |
34 | 53 | |
| 54 | + function doBatchChange() { |
| 55 | + global $wgRequest; |
| 56 | + |
| 57 | + $revisions = $wgRequest->getArray( 'wpRevisionSelected' ); |
| 58 | + $removeTags = $wgRequest->getVal( 'wpRemoveTag' ); |
| 59 | + $addTags = $wgRequest->getVal( 'wpTag' ); |
| 60 | + $status = $wgRequest->getVal( 'wpStatus' ); |
| 61 | + |
| 62 | + // Grab data from the DB |
| 63 | + $dbr = wfGetDB( DB_SLAVE ); |
| 64 | + $revObjects = array(); |
| 65 | + $res = $dbr->select( 'code_rev', '*', array( 'cr_id' => $revisions ), __METHOD__ ); |
| 66 | + while( $row = $dbr->fetchObject( $res ) ) { |
| 67 | + $revObjects[] = CodeRevision::newFromRow( $this->mRepo, $row ); |
| 68 | + } |
| 69 | + |
| 70 | + global $wgUser; |
| 71 | + if ( $wgUser->isAllowed( 'codereview-add-tag' ) && |
| 72 | + $addTags || $removeTags ) { |
| 73 | + $addTags = array_map( 'trim', explode( ",", $addTags ) ); |
| 74 | + $removeTags = array_map( 'trim', explode( ",", $removeTags ) ); |
| 75 | + |
| 76 | + foreach( $revObjects as $id => $rev ) { |
| 77 | + $rev->changeTags( $addTags, $removeTags, $wgUser ); |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + if( $wgUser->isAllowed( 'codereview-set-status' ) && |
| 82 | + $revObjects[0]->isValidStatus( $status ) ) { |
| 83 | + foreach( $revObjects as $id => $rev ) { |
| 84 | + $rev->setStatus( $status, $wgUser ); |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | + // Automatically refresh |
| 89 | + // This way of getting GET parameters is horrible, but effective. |
| 90 | + $fields = array_merge( $_GET, $_POST ); |
| 91 | + foreach( array_keys( $fields ) as $key ) { |
| 92 | + if ( substr( $key, 0, 2 ) == 'wp' || $key == 'title' ) |
| 93 | + unset( $fields[$key] ); |
| 94 | + } |
| 95 | + |
| 96 | + global $wgOut; |
| 97 | + $wgOut->redirect( $this->getPager()->getTitle()->getFullURL( $fields ) ); |
| 98 | + } |
| 99 | + |
| 100 | + function buildBatchInterface( $pager ) { |
| 101 | + global $wgUser; |
| 102 | + |
| 103 | + $changeInterface = ''; |
| 104 | + $changeFields = array(); |
| 105 | + |
| 106 | + if( $wgUser->isAllowed( 'codereview-set-status' ) ) { |
| 107 | + $changeFields['code-batch-status'] = |
| 108 | + Xml::tags( 'select', array( 'name' => 'wpStatus' ), |
| 109 | + Xml::tags( 'option', |
| 110 | + array( 'value' => '', 'selected' => 'selected' ), ' ' |
| 111 | + ) . |
| 112 | + CodeRevisionView::buildStatusList( null, $this ) |
| 113 | + ); |
| 114 | + } |
| 115 | + |
| 116 | + if ($wgUser->isAllowed( 'codereview-add-tag' ) ) { |
| 117 | + $changeFields['code-batch-tags'] = |
| 118 | + CodeRevisionView::addTagForm( '', '' ); |
| 119 | + } |
| 120 | + |
| 121 | + $changeInterface = Xml::fieldset( wfMsg('codereview-batch-title'), |
| 122 | + Xml::buildForm( $changeFields, 'codereview-batch-submit' ) ); |
| 123 | + |
| 124 | + $changeInterface .= $pager->getHiddenFields(); |
| 125 | + $changeInterface .= Xml::hidden( 'wpBatchChangeEditToken', $wgUser->editToken() ); |
| 126 | + |
| 127 | + return $changeInterface; |
| 128 | + } |
| 129 | + |
35 | 130 | function showForm( $path = '' ) { |
36 | 131 | global $wgOut, $wgScript; |
37 | 132 | if( $this->mAuthor ) { |
— | — | @@ -117,6 +212,7 @@ |
118 | 213 | |
119 | 214 | function getFieldNames() { |
120 | 215 | return array( |
| 216 | + 'selectforchange' => wfMsg( 'code-field-select' ), |
121 | 217 | $this->getDefaultSort() => wfMsg( 'code-field-id' ), |
122 | 218 | 'cr_status' => wfMsg( 'code-field-status' ), |
123 | 219 | 'comments' => wfMsg( 'code-field-comments' ), |
— | — | @@ -132,6 +228,10 @@ |
133 | 229 | function formatRevValue( $name, $value, $row ) { |
134 | 230 | global $wgUser, $wgLang; |
135 | 231 | switch( $name ) { |
| 232 | + case 'selectforchange': |
| 233 | + $sort = $this->getDefaultSort(); |
| 234 | + return Xml::check( "wpRevisionSelected[]", false, |
| 235 | + array( 'value' => $row->$sort ) ); |
136 | 236 | case 'cp_rev_id': |
137 | 237 | case 'cr_id': |
138 | 238 | return $this->mView->mSkin->link( |
Index: trunk/extensions/CodeReview/CodeRevisionView.php |
— | — | @@ -205,7 +205,7 @@ |
206 | 206 | ) . ' '; |
207 | 207 | } |
208 | 208 | if( $wgUser->isAllowed( 'codereview-add-tag' ) ) { |
209 | | - $list .= $this->addTagForm(); |
| 209 | + $list .= $this->addTagForm( $this->mAddTags, $this->mRemoveTags ); |
210 | 210 | } |
211 | 211 | return $list; |
212 | 212 | } |
— | — | @@ -223,7 +223,7 @@ |
224 | 224 | return $tags; |
225 | 225 | } |
226 | 226 | |
227 | | - protected function listTags( $tags ) { |
| 227 | + static function listTags( $tags ) { |
228 | 228 | if( empty($tags) ) |
229 | 229 | return ""; |
230 | 230 | return implode(",",$tags); |
— | — | @@ -235,30 +235,31 @@ |
236 | 236 | $repo = $this->mRepo->getName(); |
237 | 237 | $rev = $this->mRev->getId(); |
238 | 238 | return Xml::openElement( 'select', array( 'name' => 'wpStatus' ) ) . |
239 | | - $this->buildStatusList() . xml::closeElement('select'); |
| 239 | + self::buildStatusList( $this->mRev->getStatus(), $this ) . |
| 240 | + xml::closeElement('select'); |
240 | 241 | } else { |
241 | 242 | return htmlspecialchars( $this->statusDesc( $this->mRev->getStatus() ) ); |
242 | 243 | } |
243 | 244 | } |
244 | 245 | |
245 | | - protected function buildStatusList() { |
| 246 | + static function buildStatusList( $status, $view ) { |
246 | 247 | $states = CodeRevision::getPossibleStates(); |
247 | 248 | $out = ''; |
248 | 249 | foreach( $states as $state ) { |
249 | | - $out .= Xml::option( $this->statusDesc( $state ), $state, $this->mStatus === $state ); |
| 250 | + $out .= Xml::option( $view->statusDesc( $state ), $state, |
| 251 | + $status === $state ); |
250 | 252 | } |
251 | 253 | return $out; |
252 | 254 | } |
253 | 255 | |
254 | | - protected function addTagForm() { |
| 256 | + /** Parameters are the tags to be added/removed sent with the request */ |
| 257 | + static function addTagForm( $addTags, $removeTags ) { |
255 | 258 | global $wgUser; |
256 | | - $repo = $this->mRepo->getName(); |
257 | | - $rev = $this->mRev->getId(); |
258 | 259 | return '<div><table><tr><td>' . |
259 | 260 | Xml::inputLabel( wfMsg('code-rev-tag-add'), 'wpTag', 'wpTag', 20, |
260 | | - $this->listTags($this->mAddTags) ) . '</td><td> </td><td>' . |
| 261 | + self::listTags( $addTags ) ) . '</td><td> </td><td>' . |
261 | 262 | Xml::inputLabel( wfMsg('code-rev-tag-remove'), 'wpRemoveTag', 'wpRemoveTag', 20, |
262 | | - $this->listTags($this->mRemoveTags) ) . '</td></tr></table></div>'; |
| 263 | + self::listTags( $removeTags ) ) . '</td></tr></table></div>'; |
263 | 264 | } |
264 | 265 | |
265 | 266 | protected function formatTag( $tag ) { |