Index: trunk/extensions/CodeReview/CodeRevision.php |
— | — | @@ -145,4 +145,52 @@ |
146 | 146 | $result->free(); |
147 | 147 | return $comments; |
148 | 148 | } |
| 149 | + |
| 150 | + function getTags() { |
| 151 | + $dbr = wfGetDB( DB_SLAVE ); |
| 152 | + $result = $dbr->select( 'code_tags', |
| 153 | + array( 'ct_tag' ), |
| 154 | + array( |
| 155 | + 'ct_repo_id' => $this->mRepo, |
| 156 | + 'ct_rev_id' => $this->mId ), |
| 157 | + __METHOD__ ); |
| 158 | + |
| 159 | + $tags = array(); |
| 160 | + foreach( $result as $row ) { |
| 161 | + $tags[] = $row->ct_tag; |
| 162 | + } |
| 163 | + return $tags; |
| 164 | + } |
| 165 | + |
| 166 | + function addTags( $tags ) { |
| 167 | + $dbw = wfGetDB( DB_MASTER ); |
| 168 | + $result = $dbw->insert( 'code_tags', |
| 169 | + $this->tagData( $tags ), |
| 170 | + __METHOD__, |
| 171 | + array( 'IGNORE' ) ); |
| 172 | + } |
| 173 | + |
| 174 | + function removeTags( $tags ) { |
| 175 | + $dbw = wfGetDB( DB_MASTER ); |
| 176 | + $result = $dbw->delete( 'code_tags', |
| 177 | + $this->tagData( $tags ), |
| 178 | + __METHOD__ ); |
| 179 | + } |
| 180 | + |
| 181 | + protected function tagData( $tags ) { |
| 182 | + $data = array(); |
| 183 | + foreach( $tags as $tag ) { |
| 184 | + $data[] = array( |
| 185 | + 'ct_repo_id' => $this->mRepo, |
| 186 | + 'ct_rev_id' => $this->mId, |
| 187 | + 'ct_tag' => $tag ); |
| 188 | + } |
| 189 | + return $data; |
| 190 | + } |
| 191 | + |
| 192 | + function isValidTag( $tag ) { |
| 193 | + // fixme? |
| 194 | + $title = Title::newFromText( $tag ); |
| 195 | + return $title && $title->getPrefixedText() === $tag; |
| 196 | + } |
149 | 197 | } |
Index: trunk/extensions/CodeReview/CodeReview.php |
— | — | @@ -42,6 +42,7 @@ |
43 | 43 | $wgAutoloadClasses['CodeRepoListView'] = $dir . 'CodeRepoListView.php'; |
44 | 44 | $wgAutoloadClasses['CodeRevision'] = $dir . 'CodeRevision.php'; |
45 | 45 | $wgAutoloadClasses['CodeRevisionListView'] = $dir . 'CodeRevisionListView.php'; |
| 46 | +$wgAutoloadClasses['CodeRevisionTagger'] = $dir . 'CodeRevisionTagger.php'; |
46 | 47 | $wgAutoloadClasses['CodeRevisionView'] = $dir . 'CodeRevisionView.php'; |
47 | 48 | $wgAutoloadClasses['CodeComment'] = $dir . 'CodeComment.php'; |
48 | 49 | $wgAutoloadClasses['SpecialCode'] = $dir . 'SpecialCode.php'; |
— | — | @@ -52,6 +53,11 @@ |
53 | 54 | $wgExtensionAliasesFiles['CodeReview'] = $dir . 'CodeReview.alias.php'; |
54 | 55 | |
55 | 56 | $wgAvailableRights[] = 'repoadmin'; |
| 57 | +$wgGroupPermissions['*']['codereview-add-tag'] = true; |
| 58 | +$wgGroupPermissions['*']['codereview-remove-tag'] = true; |
| 59 | +$wgGroupPermissions['*']['codereview-post-comment'] = true; |
56 | 60 | |
| 61 | +$wgGroupPermissions['steward']['repoadmin'] = true; // temp |
| 62 | + |
57 | 63 | $wgSpecialPages['Code'] = 'SpecialCode'; |
58 | 64 | $wgSpecialPages['RepoAdmin'] = 'SpecialRepoAdmin'; |
Index: trunk/extensions/CodeReview/codereview.css |
— | — | @@ -1,3 +1,7 @@ |
| 2 | +table.mw-codereview-meta td { |
| 3 | + vertical-align: top; |
| 4 | +} |
| 5 | + |
2 | 6 | .mw-codereview-comment { |
3 | 7 | border: solid 1px #aaaab3; |
4 | 8 | padding: 0px; |
Index: trunk/extensions/CodeReview/CodeReview.i18n.php |
— | — | @@ -26,6 +26,7 @@ |
27 | 27 | 'code-rev-modified-c' => 'copied', |
28 | 28 | 'code-rev-modified-d' => 'deleted', |
29 | 29 | 'code-rev-modified-m' => 'modified', |
| 30 | + 'code-rev-tags' => 'Tags:', |
30 | 31 | 'code-rev-comment-by' => 'Comment by $1', |
31 | 32 | 'code-rev-comment-submit' => 'Submit comment', |
32 | 33 | 'code-rev-comment-preview' => 'Preview', |
Index: trunk/extensions/CodeReview/SpecialCode.php |
— | — | @@ -29,6 +29,9 @@ |
30 | 30 | if( $params[2] == 'reply' ) { |
31 | 31 | $view = new CodeRevisionView( $params[0], $params[1], $params[3] ); |
32 | 32 | break; |
| 33 | + } elseif( $params[2] == 'add' && $params[3] == 'tag' ) { |
| 34 | + $view = new CodeRevisionTagger( $params[0], $params[1] ); |
| 35 | + break; |
33 | 36 | } |
34 | 37 | default: |
35 | 38 | throw new MWException( "Unexpected number of parameters" ); |
— | — | @@ -48,6 +51,13 @@ |
49 | 52 | global $wgUser; |
50 | 53 | $this->mSkin = $wgUser->getSkin(); |
51 | 54 | } |
| 55 | + |
| 56 | + function validPost( $permission ) { |
| 57 | + global $wgRequest, $wgUser; |
| 58 | + return $wgRequest->wasPosted() |
| 59 | + && $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) |
| 60 | + && $wgUser->isAllowed( $permission ); |
| 61 | + } |
52 | 62 | |
53 | 63 | abstract function execute(); |
54 | 64 | |
Index: trunk/extensions/CodeReview/CodeRevisionTagger.php |
— | — | @@ -0,0 +1,32 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class CodeRevisionTagger extends CodeRevisionView { |
| 5 | + |
| 6 | + function __construct( $repoName, $rev ){ |
| 7 | + parent::__construct( $repoName, $rev ); |
| 8 | + |
| 9 | + global $wgRequest; |
| 10 | + $this->mTag = $wgRequest->getText( 'wpTag' ); |
| 11 | + } |
| 12 | + |
| 13 | + function execute() { |
| 14 | + global $wgOut; |
| 15 | + |
| 16 | + if( $this->validPost( 'codereview-add-tag' ) ) { |
| 17 | + $this->mRev->addTags( array( $this->mTag ) ); |
| 18 | + |
| 19 | + $repo = $this->mRepo->getName(); |
| 20 | + $rev = $this->mRev->getId(); |
| 21 | + $special = SpecialPage::getTitleFor( 'Code', "$repo/$rev" ); |
| 22 | + |
| 23 | + $wgOut->redirect( $special->getFullUrl() ); |
| 24 | + } else { |
| 25 | + throw new MWException( 'barf' ); |
| 26 | + } |
| 27 | + } |
| 28 | + |
| 29 | + function validPost( $permission ) { |
| 30 | + return parent::validPost( $permission ) && |
| 31 | + $this->mRev->isValidTag( $this->mTag ); |
| 32 | + } |
| 33 | +} |
Property changes on: trunk/extensions/CodeReview/CodeRevisionTagger.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 34 | + native |
Index: trunk/extensions/CodeReview/CodeRevisionView.php |
— | — | @@ -42,13 +42,20 @@ |
43 | 43 | if( $paths ){ |
44 | 44 | $paths = "<ul>\n$paths</ul>"; |
45 | 45 | } |
46 | | - $html = '<table> |
47 | | -<tr><td valign="top">' . wfMsgHtml( 'code-rev-repo' ) . '</td><td valign="top">' . $repoLink . '</td></tr> |
48 | | -<tr><td valign="top">' . wfMsgHtml( 'code-rev-rev' ) . '</td><td valign="top">' . $revText . '</td></tr> |
49 | | -<tr><td valign="top">' . wfMsgHtml( 'code-rev-author' ) . '</td><td valign="top">' . $this->authorLink( $this->mRev->getAuthor() ) . '</td></tr> |
50 | | -<tr><td valign="top">' . wfMsgHtml( 'code-rev-message' ) . '</td><td valign="top">' . $this->formatMessage( $this->mRev->getMessage() ) . '</td></tr> |
51 | | -<tr><td valign="top">' . wfMsgHtml( 'code-rev-paths' ) . '</td><td valign="top">' . $paths . '</td></tr> |
52 | | -</table>'; |
| 46 | + $fields = array( |
| 47 | + 'code-rev-repo' => $repoLink, |
| 48 | + 'code-rev-rev' => $revText, |
| 49 | + 'code-rev-author' => $this->authorLink( $this->mRev->getAuthor() ), |
| 50 | + 'code-rev-message' => $this->formatMessage( $this->mRev->getMessage() ), |
| 51 | + 'code-rev-paths' => $paths, |
| 52 | + 'code-rev-tags' => $this->formatTags(), |
| 53 | + ); |
| 54 | + $html = '<table class="mw-codereview-meta">'; |
| 55 | + foreach( $fields as $label => $data ) { |
| 56 | + $html .= "<tr><td>" . wfMsgHtml( $label ) . "</td><td>$data</td></tr>\n"; |
| 57 | + } |
| 58 | + $html .= '</table>'; |
| 59 | + |
53 | 60 | $html .= |
54 | 61 | "<h2>" . wfMsgHtml( 'code-rev-diff' ) . "</h2>" . |
55 | 62 | "<div class='mw-codereview-diff'>" . |
— | — | @@ -107,6 +114,48 @@ |
108 | 115 | } |
109 | 116 | return "<li>$link ($desc)</li>\n"; |
110 | 117 | } |
| 118 | + |
| 119 | + function formatTags() { |
| 120 | + global $wgUser; |
| 121 | + |
| 122 | + $tags = $this->mRev->getTags(); |
| 123 | + $list = implode( ", ", |
| 124 | + array_map( |
| 125 | + array( $this, 'formatTag' ), |
| 126 | + $tags ) ); |
| 127 | + |
| 128 | + if( $wgUser->isAllowed( 'codereview-add-tag' ) ) { |
| 129 | + $list .= $this->addTagForm(); |
| 130 | + } |
| 131 | + |
| 132 | + return $list; |
| 133 | + } |
| 134 | + |
| 135 | + function addTagForm() { |
| 136 | + global $wgUser; |
| 137 | + $repo = $this->mRepo->getName(); |
| 138 | + $rev = $this->mRev->getId(); |
| 139 | + $special = SpecialPage::getTitleFor( 'Code', "$repo/$rev/add/tag" ); |
| 140 | + return |
| 141 | + Xml::openElement( 'form', |
| 142 | + array( |
| 143 | + 'action' => $special->getLocalUrl(), |
| 144 | + 'method' => 'post' ) ) . |
| 145 | + Xml::input( 'wpTag', '' ) . |
| 146 | + Xml::hidden( 'wpEditToken', $wgUser->editToken() ) . |
| 147 | + ' ' . |
| 148 | + Xml::submitButton( 'Add tag' ) . |
| 149 | + '</form>'; |
| 150 | + } |
| 151 | + |
| 152 | + function formatTag( $tag ) { |
| 153 | + global $wgUser; |
| 154 | + |
| 155 | + $repo = $this->mRepo->getName(); |
| 156 | + $special = SpecialPage::getTitleFor( 'Code', "$repo/tag/$tag" ); |
| 157 | + |
| 158 | + return $this->mSkin->link( $special, htmlspecialchars( $tag ) ); |
| 159 | + } |
111 | 160 | |
112 | 161 | function formatDiff() { |
113 | 162 | $diff = $this->mRepo->getDiff( $this->mRev->getId() ); |