Index: trunk/extensions/CodeReview/CodeRevision.php |
— | — | @@ -116,27 +116,39 @@ |
117 | 117 | return true; |
118 | 118 | } |
119 | 119 | |
| 120 | + function previewComment( $text, $review, $parent=null ) { |
| 121 | + $data = $this->commentData( $text, $review, $parent ); |
| 122 | + $data['cc_id'] = null; |
| 123 | + return CodeComment::newFromData( $this, $data ); |
| 124 | + } |
| 125 | + |
120 | 126 | function saveComment( $text, $review, $parent=null ) { |
121 | | - global $wgUser; |
122 | | - $ts = wfTimestamp( TS_MW ); |
123 | | - $sortkey = $this->threadedSortkey( $parent, $ts ); |
124 | | - |
125 | 127 | $dbw = wfGetDB( DB_SLAVE ); |
| 128 | + $data = $this->commentData( $text, $review, $parent ); |
| 129 | + $data['cc_id'] = $dbw->nextSequenceValue( 'code_comment_cc_id' ); |
126 | 130 | $dbw->insert( 'code_comment', |
127 | | - array( |
128 | | - 'cc_repo_id' => $this->mRepo, |
129 | | - 'cc_rev_id' => $this->mId, |
130 | | - 'cc_text' => $text, |
131 | | - 'cc_parent' => $parent, |
132 | | - 'cc_user' => $wgUser->getId(), |
133 | | - 'cc_user_text' => $wgUser->getName(), |
134 | | - 'cc_timestamp' => $dbw->timestamp( $ts ), |
135 | | - 'cc_review' => $review, |
136 | | - 'cc_sortkey' => $sortkey ), |
| 131 | + $data, |
137 | 132 | __METHOD__ ); |
138 | 133 | |
139 | 134 | return $dbw->insertId(); |
140 | 135 | } |
| 136 | + |
| 137 | + protected function commentData( $text, $review, $parent=null ) { |
| 138 | + global $wgUser; |
| 139 | + $dbw = wfGetDB( DB_SLAVE ); |
| 140 | + $ts = wfTimestamp( TS_MW ); |
| 141 | + $sortkey = $this->threadedSortkey( $parent, $ts ); |
| 142 | + return array( |
| 143 | + 'cc_repo_id' => $this->mRepo, |
| 144 | + 'cc_rev_id' => $this->mId, |
| 145 | + 'cc_text' => $text, |
| 146 | + 'cc_parent' => $parent, |
| 147 | + 'cc_user' => $wgUser->getId(), |
| 148 | + 'cc_user_text' => $wgUser->getName(), |
| 149 | + 'cc_timestamp' => $dbw->timestamp( $ts ), |
| 150 | + 'cc_review' => $review, |
| 151 | + 'cc_sortkey' => $sortkey ); |
| 152 | + } |
141 | 153 | |
142 | 154 | protected function threadedSortKey( $parent, $ts ) { |
143 | 155 | if( $parent ) { |
— | — | @@ -179,7 +191,7 @@ |
180 | 192 | |
181 | 193 | $comments = array(); |
182 | 194 | foreach( $result as $row ) { |
183 | | - $comments[] = new CodeComment( $this, $row ); |
| 195 | + $comments[] = CodeComment::newFromRow( $this, $row ); |
184 | 196 | } |
185 | 197 | $result->free(); |
186 | 198 | return $comments; |
Index: trunk/extensions/CodeReview/CodeComment.php |
— | — | @@ -2,17 +2,26 @@ |
3 | 3 | if (!defined('MEDIAWIKI')) die(); |
4 | 4 | |
5 | 5 | class CodeComment { |
6 | | - function __construct( $repo, $row ) { |
7 | | - $this->repo = $repo; |
8 | | - $this->id = $row->cc_id; |
9 | | - $this->text = $row->cc_text; // fixme |
10 | | - $this->user = $row->cc_user; |
11 | | - $this->userText = $row->cc_user_text; |
12 | | - $this->timestamp = wfTimestamp( TS_MW, $row->cc_timestamp ); |
13 | | - $this->review = $row->cc_review; |
14 | | - $this->sortkey = $row->cc_sortkey; |
| 6 | + function __construct( $rev ) { |
| 7 | + $this->rev = $rev; |
15 | 8 | } |
16 | 9 | |
| 10 | + function newFromRow( $rev, $row ) { |
| 11 | + return self::newFromData( $rev, get_object_vars( $row ) ); |
| 12 | + } |
| 13 | + |
| 14 | + function newFromData( $rev, $data ) { |
| 15 | + $comment = new CodeComment( $rev ); |
| 16 | + $comment->id = $data['cc_id']; |
| 17 | + $comment->text = $data['cc_text']; // fixme |
| 18 | + $comment->user = $data['cc_user']; |
| 19 | + $comment->userText = $data['cc_user_text']; |
| 20 | + $comment->timestamp = wfTimestamp( TS_MW, $data['cc_timestamp'] ); |
| 21 | + $comment->review = $data['cc_review']; |
| 22 | + $comment->sortkey = $data['cc_sortkey']; |
| 23 | + return $comment; |
| 24 | + } |
| 25 | + |
17 | 26 | function threadDepth() { |
18 | 27 | $timestamps = explode( ",", $this->sortkey ); |
19 | 28 | return count( $timestamps ); |
Index: trunk/extensions/CodeReview/CodeRevisionView.php |
— | — | @@ -8,6 +8,7 @@ |
9 | 9 | $this->mRepo = CodeRepository::newFromName( $repoName ); |
10 | 10 | $this->mRev = $this->mRepo ? $this->mRepo->getRevision( intval( $rev ) ) : null; |
11 | 11 | $this->mReplyTarget = $replyTarget; |
| 12 | + $this->mPreviewText = false; |
12 | 13 | } |
13 | 14 | |
14 | 15 | function execute(){ |
— | — | @@ -113,7 +114,8 @@ |
114 | 115 | $review = $wgRequest->getInt( 'wpReview' ); |
115 | 116 | $isPreview = $wgRequest->getCheck( 'wpPreview' ); |
116 | 117 | if( $isPreview ) { |
117 | | - // NYI |
| 118 | + // Save the text for reference on later comment display... |
| 119 | + $this->mPreviewText = $text; |
118 | 120 | } else { |
119 | 121 | $id = $this->mRev->saveComment( $text, $review, $parent ); |
120 | 122 | |
— | — | @@ -262,17 +264,30 @@ |
263 | 265 | return $title; |
264 | 266 | } |
265 | 267 | |
| 268 | + function previewComment( $text, $review=0 ) { |
| 269 | + $comment = $this->mRev->previewComment( $text, $review ); |
| 270 | + return $this->formatComment( $comment ); |
| 271 | + } |
| 272 | + |
266 | 273 | function formatComment( $comment, $replyForm='' ) { |
267 | 274 | global $wgOut, $wgLang; |
268 | 275 | $linker = new CodeCommentLinkerWiki( $this->mRepo ); |
269 | 276 | |
| 277 | + if( $comment->id === null ) { |
| 278 | + $linkId = 'cpreview'; |
| 279 | + $permaLink = "<b>Preview:</b> "; |
| 280 | + } else { |
| 281 | + $linkId = 'c' . intval( $comment->id ); |
| 282 | + $permaLink = $this->mSkin->link( $this->commentLink( $comment->id ), "#" ); |
| 283 | + } |
| 284 | + |
270 | 285 | return Xml::openElement( 'div', |
271 | 286 | array( |
272 | 287 | 'class' => 'mw-codereview-comment', |
273 | | - 'id' => 'c' . intval( $comment->id ), |
| 288 | + 'id' => $linkId, |
274 | 289 | 'style' => $this->commentStyle( $comment ) ) ) . |
275 | 290 | '<div class="mw-codereview-comment-meta">' . |
276 | | - $this->mSkin->link( $this->commentLink( $comment->id ), "#" ) . |
| 291 | + $permaLink . |
277 | 292 | wfMsgHtml( 'code-rev-comment-by', |
278 | 293 | $this->mSkin->userLink( $comment->user, $comment->userText ) . |
279 | 294 | $this->mSkin->userToolLinks( $comment->user, $comment->userText ) ) . |
— | — | @@ -306,10 +321,25 @@ |
307 | 322 | |
308 | 323 | function postCommentForm( $parent=null ) { |
309 | 324 | global $wgUser; |
| 325 | + if( $this->mPreviewText != false && $parent === $this->mReplyTarget ) { |
| 326 | + $preview = $this->previewComment( $this->mPreviewText ); |
| 327 | + $text = htmlspecialchars( $this->mPreviewText ); |
| 328 | + } else { |
| 329 | + $preview = ''; |
| 330 | + $text = ''; |
| 331 | + } |
| 332 | + $repo = $this->mRepo->getName(); |
| 333 | + $rev = $this->mRev->getId(); |
| 334 | + if( $parent ) { |
| 335 | + $special = SpecialPage::getTitleFor( 'Code', "$repo/$rev/reply/$parent" ); |
| 336 | + } else { |
| 337 | + $special = SpecialPage::getTitleFor( 'Code', "$repo/$rev" ); |
| 338 | + } |
310 | 339 | return '<div class="mw-codereview-post-comment">' . |
| 340 | + $preview . |
311 | 341 | Xml::openElement( 'form', |
312 | 342 | array( |
313 | | - 'action' => '', // fixme |
| 343 | + 'action' => $special->getLocalUrl(), |
314 | 344 | 'method' => 'post' ) ) . |
315 | 345 | Xml::hidden( 'wpEditToken', $wgUser->editToken() ) . |
316 | 346 | ($parent ? Xml::hidden( 'wpParent', $parent ) : '') . |
— | — | @@ -319,6 +349,7 @@ |
320 | 350 | 'id' => "wpReplyTo{$parent}", |
321 | 351 | 'cols' => 40, |
322 | 352 | 'rows' => 5 ) ) . |
| 353 | + $text . |
323 | 354 | '</textarea>' . |
324 | 355 | '</div>' . |
325 | 356 | '<div>' . |