Index: trunk/extensions/CodeReview/CodeRevision.php |
— | — | @@ -5,6 +5,7 @@ |
6 | 6 | static function newFromSvn( CodeRepository $repo, $data ) { |
7 | 7 | $rev = new CodeRevision(); |
8 | 8 | $rev->mRepoId = $repo->getId(); |
| 9 | + $rev->mRepo = $repo; |
9 | 10 | $rev->mId = intval($data['rev']); |
10 | 11 | $rev->mAuthor = $data['author']; |
11 | 12 | $rev->mTimestamp = wfTimestamp( TS_MW, strtotime( $data['date'] ) ); |
— | — | @@ -46,6 +47,7 @@ |
47 | 48 | static function newFromRow( $row ) { |
48 | 49 | $rev = new CodeRevision(); |
49 | 50 | $rev->mRepoId = intval($row->cr_repo_id); |
| 51 | + $rev->mRepo = NULL; |
50 | 52 | $rev->mId = intval($row->cr_id); |
51 | 53 | $rev->mAuthor = $row->cr_author; |
52 | 54 | $rev->mTimestamp = wfTimestamp( TS_MW, $row->cr_timestamp ); |
— | — | @@ -58,10 +60,25 @@ |
59 | 61 | function getId() { |
60 | 62 | return intval( $this->mId ); |
61 | 63 | } |
| 64 | + |
| 65 | + function getRepoId() { |
| 66 | + return intval( $this->mRepoId ); |
| 67 | + } |
62 | 68 | |
63 | 69 | function getAuthor() { |
64 | 70 | return $this->mAuthor; |
65 | 71 | } |
| 72 | + |
| 73 | + function getRepo() { |
| 74 | + if( !isset($this->mRepo) ) { |
| 75 | + $this->mRepo = CodeRepository::newFromId( $this->mRepoId ); |
| 76 | + } |
| 77 | + return $this->mRepo; |
| 78 | + } |
| 79 | + |
| 80 | + function getWikiUser() { |
| 81 | + return $this->getRepo()->authorWikiUser( $this->getAuthor() ); |
| 82 | + } |
66 | 83 | |
67 | 84 | function getTimestamp() { |
68 | 85 | return $this->mTimestamp; |
— | — | @@ -131,7 +148,7 @@ |
132 | 149 | 'cr_id' => $this->mId ), |
133 | 150 | __METHOD__ ); |
134 | 151 | } |
135 | | - |
| 152 | + // Update path tracking used for output and searching |
136 | 153 | if( $this->mPaths ) { |
137 | 154 | $data = array(); |
138 | 155 | foreach( $this->mPaths as $path ) { |
— | — | @@ -175,17 +192,46 @@ |
176 | 193 | } |
177 | 194 | |
178 | 195 | function saveComment( $text, $review, $parent=null ) { |
| 196 | + global $wgUser; |
179 | 197 | if( !strlen($text) ) { |
180 | 198 | return 0; |
181 | 199 | } |
182 | 200 | $dbw = wfGetDB( DB_MASTER ); |
183 | 201 | $data = $this->commentData( $text, $review, $parent ); |
| 202 | + |
| 203 | + $dbw->begin(); |
184 | 204 | $data['cc_id'] = $dbw->nextSequenceValue( 'code_comment_cc_id' ); |
185 | | - $dbw->insert( 'code_comment', |
186 | | - $data, |
187 | | - __METHOD__ ); |
| 205 | + $dbw->insert( 'code_comment', $data, __METHOD__ ); |
| 206 | + $commentId = $dbw->insertId(); |
| 207 | + $dbw->commit(); |
| 208 | + |
| 209 | + // Give email notices to committer and commentors |
| 210 | + global $wgCodeReviewENotif, $wgEnableEmail; |
| 211 | + if( $wgCodeReviewENotif && $wgEnableEmail ) { |
| 212 | + // Make list of users to send emails to |
| 213 | + $users = $this->getCommentingUsers(); |
| 214 | + if( $user = $this->getWikiUser() ) { |
| 215 | + $users[$user->getId()] = $user; |
| 216 | + } |
| 217 | + // Get repo and build comment title (for url) |
| 218 | + $title = SpecialPage::getTitleFor( 'Code', $this->getRepo()->getName().'/'.$this->mId ); |
| 219 | + $title->setFragment( "#c{$commentId}" ); |
| 220 | + $url = $title->getFullUrl(); |
| 221 | + foreach( $users as $userId => $user ) { |
| 222 | + // No sense in notifying this commentor |
| 223 | + if( $wgUser->getId() == $user->getId() ) { |
| 224 | + continue; |
| 225 | + } |
| 226 | + if( $user->canReceiveEmail() ) { |
| 227 | + $user->sendMail( |
| 228 | + wfMsg( 'codereview-email-subj', $this->getRepo()->getName(), $this->mId ), |
| 229 | + wfMsg( 'codereview-email-body', $wgUser->getName(), $url, $this->mId, $text ) |
| 230 | + ); |
| 231 | + } |
| 232 | + } |
| 233 | + } |
188 | 234 | |
189 | | - return $dbw->insertId(); |
| 235 | + return $commentId; |
190 | 236 | } |
191 | 237 | |
192 | 238 | protected function commentData( $text, $review, $parent=null ) { |
— | — | @@ -252,6 +298,24 @@ |
253 | 299 | return $comments; |
254 | 300 | } |
255 | 301 | |
| 302 | + function getCommentingUsers() { |
| 303 | + $dbr = wfGetDB( DB_SLAVE ); |
| 304 | + $res = $dbr->select( 'code_comment', |
| 305 | + 'DISTINCT(cc_user)', |
| 306 | + array( |
| 307 | + 'cc_repo_id' => $this->mRepoId, |
| 308 | + 'cc_rev_id' => $this->mId, |
| 309 | + 'cc_user != 0' // users only |
| 310 | + ), |
| 311 | + __METHOD__ |
| 312 | + ); |
| 313 | + $users = array(); |
| 314 | + while( $row = $res->fetchObject() ) { |
| 315 | + $users[$row->cc_user] = User::newFromId( $row->cc_user ); |
| 316 | + } |
| 317 | + return $users; |
| 318 | + } |
| 319 | + |
256 | 320 | function getTags() { |
257 | 321 | $dbr = wfGetDB( DB_SLAVE ); |
258 | 322 | $result = $dbr->select( 'code_tags', |
Index: trunk/extensions/CodeReview/CodeReview.php |
— | — | @@ -99,3 +99,4 @@ |
100 | 100 | // The name of a repo which represents the code running on this wiki, used to highlight active revisions |
101 | 101 | $wgWikiSVN = 'MediaWiki'; |
102 | 102 | |
| 103 | +$wgCodeReviewENotif = true; |
Index: trunk/extensions/CodeReview/CodeReview.i18n.php |
— | — | @@ -69,6 +69,11 @@ |
70 | 70 | 'code-rev-submit-next' => 'Commit & next unresolved', |
71 | 71 | |
72 | 72 | 'codereview-reply-link' => 'reply', |
| 73 | + |
| 74 | + 'codereview-email-subj' => '[$1] [r$2]: New comment added', |
| 75 | + 'codereview-email-body' => 'User <b>$1</b> posted the <a href="$2">following comment</a> on r$3: |
| 76 | + |
| 77 | +$4', |
73 | 78 | |
74 | 79 | 'repoadmin' => 'Repository Administration', |
75 | 80 | 'repoadmin-new-legend' => 'Create a new repository', |