Index: trunk/phpwiki/newcodebase/User.php |
— | — | @@ -46,8 +46,7 @@ |
47 | 47 | global $wgDefaultOptions; |
48 | 48 | |
49 | 49 | $this->mId = 0; |
50 | | - $remaddr = getenv( "REMOTE_ADDR" ); |
51 | | - $this->mName = preg_replace( "/\d+$/", "xxx", $remaddr ); |
| 50 | + $this->mName = getenv( "REMOTE_ADDR" ); |
52 | 51 | $this->mEmail = ""; |
53 | 52 | $this->mPassword = ""; |
54 | 53 | $this->mRights = array(); |
— | — | @@ -62,7 +61,7 @@ |
63 | 62 | |
64 | 63 | /* private */ function getBlockedStatus() |
65 | 64 | { |
66 | | - if ( -1 != $this->mBlockedby ) { return ; } |
| 65 | + if ( -1 != $this->mBlockedby ) { return; } |
67 | 66 | |
68 | 67 | $remaddr = getenv( "REMOTE_ADDR" ); |
69 | 68 | $conn = wfGetDB(); |
— | — | @@ -71,15 +70,18 @@ |
72 | 71 | wfDebug( "User: 5: $sql\n" ); |
73 | 72 | |
74 | 73 | $res = mysql_query( $sql, $conn ); |
75 | | - if ( ! $res ) { |
| 74 | + if ( ( ! $res ) || ( 0 == mysql_num_rows( $res ) ) ) { |
76 | 75 | if ( 0 == $this->mId ) { |
77 | 76 | $this->mBlockedby = 0; |
78 | 77 | return; |
79 | 78 | } |
| 79 | + $conn = wfGetDB(); |
80 | 80 | $sql = "SELECT ipb_by,ipb_reason FROM ipblocks WHERE " . |
81 | 81 | "ipb_user={$this->mId}"; |
82 | 82 | wfDebug( "User: 6: $sql\n" ); |
83 | | - if ( ! $res ) { |
| 83 | + |
| 84 | + $res = mysql_query( $sql, $conn ); |
| 85 | + if ( ( ! $res ) || ( 0 == mysql_num_rows( $res ) ) ) { |
84 | 86 | $this->mBlockedby = 0; |
85 | 87 | return; |
86 | 88 | } |
— | — | @@ -368,7 +370,6 @@ |
369 | 371 | wfSetSQL( "user", "user_watch", implode( "\n", $this->mWatchlist ), |
370 | 372 | "user_id={$this->mId}" ); |
371 | 373 | } |
372 | | - $this->setCookies(); |
373 | 374 | } |
374 | 375 | |
375 | 376 | # Checks if a user with the given name exists |
Index: trunk/phpwiki/newcodebase/Title.php |
— | — | @@ -145,7 +145,9 @@ |
146 | 146 | wfDebug( "Title: 2: $sql\n" ); |
147 | 147 | |
148 | 148 | $res = mysql_query( $sql, $conn ); |
149 | | - if ( ! $res ) { return $this->mOtherNamespaces; } |
| 149 | + if ( ! $res || 0 == mysql_num_rows( $res ) ) { |
| 150 | + return $this->mOtherNamespaces; |
| 151 | + } |
150 | 152 | |
151 | 153 | while ( $row = mysql_fetch_object( $res ) ) { |
152 | 154 | $ns = $row->cur_namespace; |
— | — | @@ -186,7 +188,7 @@ |
187 | 189 | # wfDebug( "Title: 1: $sql\n" ); |
188 | 190 | $res = mysql_query( $sql, $conn ); |
189 | 191 | |
190 | | - if ( ! $res ) { |
| 192 | + if ( ! $res || 0 == mysql_num_rows( $res ) ) { |
191 | 193 | $this->mArticleID = 0; |
192 | 194 | } else { |
193 | 195 | $s = mysql_fetch_object( $res ); |
Index: trunk/phpwiki/newcodebase/Language.php |
— | — | @@ -118,11 +118,26 @@ |
119 | 119 | "preview" => "Preview", |
120 | 120 | "showpreview" => "Show preview", |
121 | 121 | "blockedtitle" => "User is blocked", |
122 | | -"blockedtext" => "Your user name or IP addressed has been blocked by $1. |
123 | | -The reason given is this:<br>$2<p>You may contact that administrator to |
| 122 | +"blockedtext" => "Your user name or IP address has been blocked by $1. |
| 123 | +The reason given is this:<br>$2<p>You may contact the administrator to |
124 | 124 | discuss the block.", |
125 | | -"newarticle" => "New article", |
| 125 | +"newarticle" => "New article: $1", |
126 | 126 | "newarticletext" => "Describe the new page here.", |
| 127 | +"updated" => "Updated: $1", |
| 128 | +"note" => "<strong>Note:</strong> ", |
| 129 | +"previewnote" => "Remember that this is only a preview, and has not yet been saved!", |
| 130 | +"previewconflict" => "This preview reflects the text in the upper |
| 131 | +text editing area as it will appear if you choose to save.", |
| 132 | +"editing" => "Editing $1", |
| 133 | +"editconflict" => "Edit conflict: $1", |
| 134 | +"explainconflict" => "Someone else has changed this article since you |
| 135 | +started editing it. |
| 136 | +The upper text area contains the article text as it currently exists. |
| 137 | +Your changes are shown in the lower text area. |
| 138 | +You will have to merge your changes into the existing text. |
| 139 | +<b>Only</b> the text in the upper text area will be saved when you |
| 140 | +press \"Save\".\n<p>", |
| 141 | +"yourtext" => "Your text", |
127 | 142 | |
128 | 143 | # Preferences page |
129 | 144 | # |
Index: trunk/phpwiki/newcodebase/Article.php |
— | — | @@ -4,14 +4,14 @@ |
5 | 5 | class Article { |
6 | 6 | /* private */ var $mTitle; # WikiTitle object |
7 | 7 | /* private */ var $mContent, $mContentLoaded; |
8 | | - /* private */ var $mTimestamp, $mParams; |
| 8 | + /* private */ var $mUser, $mTimestamp, $mParams; |
9 | 9 | /* private */ var $mCounter; |
10 | 10 | |
11 | 11 | function Article( $t ) |
12 | 12 | { |
13 | 13 | $this->mTitle = $t; |
14 | 14 | $this->mContentLoaded = false; |
15 | | - $this->mCounter = -1; # Not loaded |
| 15 | + $this->mUser = $this->mCounter = -1; # Not loaded |
16 | 16 | $this->mTimestamp = ""; |
17 | 17 | } |
18 | 18 | |
— | — | @@ -33,16 +33,17 @@ |
34 | 34 | if ( 0 == $id ) return; |
35 | 35 | |
36 | 36 | $conn = wfGetDB(); |
37 | | - $sql = "SELECT cur_text, cur_timestamp, cur_counter, " . |
| 37 | + $sql = "SELECT cur_text,cur_timestamp,cur_user,cur_counter, " . |
38 | 38 | "cur_params FROM cur WHERE cur_id=$id"; |
39 | 39 | wfDebug( "Art: 1: $sql\n" ); |
40 | 40 | $result = mysql_query( $sql, $conn ); |
41 | 41 | |
42 | | - if ( ! $result ) { |
| 42 | + if ( ! $result || 0 == mysql_num_rows( $result ) ) { |
43 | 43 | $this->mContent = "Fatal database error.\n"; |
44 | 44 | } else { |
45 | 45 | $s = mysql_fetch_object( $result ); |
46 | 46 | $this->mContent = $s->cur_text; |
| 47 | + $this->mUser = $s->cur_user; |
47 | 48 | $this->mCounter = $s->cur_counter; |
48 | 49 | $this->mParams = $s->cur_params; |
49 | 50 | $this->mTimestamp = $s->cur_timestamp; |
— | — | @@ -62,15 +63,35 @@ |
63 | 64 | return $this->mCounter; |
64 | 65 | } |
65 | 66 | |
| 67 | + /* private */ function loadLastEdit() |
| 68 | + { |
| 69 | + if ( -1 != $this->mUser ) return; |
| 70 | + |
| 71 | + $conn = wfGetDB(); |
| 72 | + $sql = "SELECT cur_user,cur_timestamp FROM cur WHERE " . |
| 73 | + "cur_id=" . $this->getID(); |
| 74 | + wfDebug( "Art: 3: $sql\n" ); |
| 75 | + |
| 76 | + $res = mysql_query( $sql, $conn ); |
| 77 | + if ( "" != $res ) { |
| 78 | + $s = mysql_fetch_object( $res ); |
| 79 | + $this->mUser = $s->cur_user; |
| 80 | + $this->mTimestamp = $s->mTimestamp; |
| 81 | + } |
| 82 | + } |
| 83 | + |
66 | 84 | function getTimestamp() |
67 | 85 | { |
68 | | - if ( "" == $this->mTimestamp ) { |
69 | | - $id = $this->getID(); |
70 | | - $this->mTimestamp = wfGetSQL( "cur", "cur_timestamp", "cur_id=$id" ); |
71 | | - } |
| 86 | + $this->loadLastEdit(); |
72 | 87 | return $this->mTimestamp; |
73 | 88 | } |
74 | 89 | |
| 90 | + function getUser() |
| 91 | + { |
| 92 | + $this->loadLastEdit(); |
| 93 | + return $this->mTimestamp; |
| 94 | + } |
| 95 | + |
75 | 96 | function view() |
76 | 97 | { |
77 | 98 | global $wgOut; |
— | — | @@ -112,6 +133,7 @@ |
113 | 134 | global $wpTextbox1, $wpSummary, $wpSave, $wpPreview; |
114 | 135 | global $wpMinoredit, $wpEdittime, $wpTextbox2; |
115 | 136 | |
| 137 | + $isConflict = false; |
116 | 138 | if ( "save" == $formtype ) { |
117 | 139 | if ( $wgUser->isBlocked() ) { |
118 | 140 | $this->blockedIPpage(); |
— | — | @@ -119,42 +141,42 @@ |
120 | 142 | } |
121 | 143 | $aid = $wgTitle->getArticleID(); |
122 | 144 | if ( 0 == $aid ) { # New aritlce |
123 | | - $conn = wfGetDB(); |
124 | | - $sql = "INSERT INTO cur (cur_namespace,cur_title,cur_text," . |
125 | | - "cur_comment,cur_user,cur_timestamp) VALUES ('" . |
126 | | - $wgTitle->getNamespace() . "', '" . |
127 | | - $wgTitle->getDBKey() . "', '" . |
128 | | - wfStrencode( $wpTextbox1 ) . "', '" . |
129 | | - wfStrencode( $wpSummary ) . "', '" . $wgUser->getID() . |
130 | | - "', '" . date( "YmdHis" ) . "')"; |
131 | | - |
132 | | - wfDebug( "Art: 2: $sql\n" ); |
133 | | - $res = mysql_query( $sql, $conn ); |
134 | | - $this->editUpdates(); |
135 | | - |
136 | | - $wgOut->setPageTitle( wfMsg( "newarticle" ) . ": " . |
137 | | - $wgTitle->getPrefixedText() ); |
138 | | - $wgOut->addWikiText( $wpTextbox1 ); |
| 145 | + $this->insertArticle( $wpTextbox1, $wpSummary ); |
139 | 146 | return; |
140 | 147 | } |
141 | 148 | # Check for edit conflict |
142 | 149 | # |
143 | | - |
144 | | - # All's well: save the article here |
145 | | - # |
146 | | - $conn = wfGetDB(); |
147 | | - $sql = ""; |
148 | | - $this->editUpdates(); |
| 150 | + if ( $this->getUser() != $wgUser->getID() && |
| 151 | + $this->mTimestamp > $wpEdittime ) { |
| 152 | + $isConflict = true; |
| 153 | + } else { |
| 154 | + # All's well: save the article here |
| 155 | + $this->updateArticle( $wpTextbox1, $wpSummary, $wpMinoredit ); |
| 156 | + return; |
| 157 | + } |
149 | 158 | } |
150 | 159 | if ( "initial" == $formtype ) { |
151 | | - $wpEdittime = time( "YmdHis" ); |
| 160 | + $wpEdittime = $this->getTimestamp(); |
152 | 161 | $wpTextbox1 = $this->getContent(); |
153 | 162 | $wpSummary = "*"; |
154 | 163 | } |
155 | | - $wgOut->setPageTitle( "Editing " . $wgTitle->getPrefixedText() ); |
156 | 164 | $wgOut->setRobotpolicy( "noindex,nofollow" ); |
157 | 165 | $wgOut->setArticleFlag( false ); |
158 | 166 | |
| 167 | + if ( $isConflict ) { |
| 168 | + $s = str_replace( "$1", $wgTitle->getPrefixedText(), |
| 169 | + wfMsg( "editconflict" ) ); |
| 170 | + $wgOut->setPageTitle( $s ); |
| 171 | + $wgOut->addHTML( wfMsg( "explainconflict" ) ); |
| 172 | + |
| 173 | + $wpTextbox2 = $wpTextbox1; |
| 174 | + $wpTextbox1 = $this->getContent(); |
| 175 | + $wpEdittime = $this->getTimestamp(); |
| 176 | + } else { |
| 177 | + $s = str_replace( "$1", $wgTitle->getPrefixedText(), |
| 178 | + wfMsg( "editing" ) ); |
| 179 | + $wgOut->setPageTitle( $s ); |
| 180 | + } |
159 | 181 | $rows = $wgUser->getOption( "rows" ); |
160 | 182 | $cols = $wgUser->getOption( "cols" ); |
161 | 183 | $action = "$wgServer$wgScript?title=" . |
— | — | @@ -174,18 +196,78 @@ |
175 | 197 | <input tabindex=3 type=checkbox value=1 name='wpMinoredit'>$minor<br> |
176 | 198 | <input tabindex=4 type=submit value='$save' name='wpSave'> |
177 | 199 | <input tabindex=5 type=submit value='$prev' name='wpPreview'> |
178 | | -<input type=hidden value='$wpEdittime' name='wpEdittime'> |
179 | | -</form>\n" ); |
| 200 | +<input type=hidden value='$wpEdittime' name='wpEdittime'>\n" ); |
180 | 201 | |
| 202 | + if ( $isConflict ) { |
| 203 | + $wgOut->AddHTML( "<h2>" . wfMsg( "yourtext" ) . "</h2> |
| 204 | +<textarea tabindex=6 name='wpTextbox2' rows=$rows cols=$cols style='width:100%' wrap=virtual>\n" ); |
| 205 | + } |
| 206 | + $wgOut->addHTML( "</form>\n" ); |
| 207 | + |
181 | 208 | if ( "preview" == $formtype ) { |
182 | 209 | $wgOut->addHTML( "<h2>" . wfMsg( "preview" ) . "</h2>\n" ); |
| 210 | + if ( $isConflict ) { |
| 211 | + $wgOut->addHTML( "<h2>" . wfMsg( "previewconflict" ) . |
| 212 | + "</h2>\n" ); |
| 213 | + } |
183 | 214 | $wgOut->addWikiText( $wpTextbox1 ); |
| 215 | + $wgOut->addHTML( "<p><large>" . wfMsg( "note" ) . |
| 216 | + wfMsg( "previewnote" ) . "</large>\n" ); |
184 | 217 | } |
185 | 218 | } |
186 | 219 | |
| 220 | + # Theoretically we could defer these whole insert and update |
| 221 | + # functions for after display, but that's taking a big leap |
| 222 | + # leap of faith, and I want to be able to report database |
| 223 | + # errors at some point. |
| 224 | + # |
| 225 | + /* private */ function insertArticle( $text, $summary ) |
| 226 | + { |
| 227 | + global $wgOut, $wgUser, $wgTitle; |
| 228 | + |
| 229 | + $conn = wfGetDB(); |
| 230 | + $sql = "INSERT INTO cur (cur_namespace,cur_title,cur_text," . |
| 231 | + "cur_comment,cur_user,cur_timestamp,cur_minor_edit) VALUES ('" . |
| 232 | + $wgTitle->getNamespace() . "', '" . $wgTitle->getDBKey() . "', '" . |
| 233 | + wfStrencode( $text ) . "', '" . wfStrencode( $summary ) . "', '" . |
| 234 | + $wgUser->getID() . "', '" . date( "YmdHis" ) . "', 0)"; |
| 235 | + |
| 236 | + wfDebug( "Art: 2: $sql\n" ); |
| 237 | + $res = mysql_query( $sql, $conn ); |
| 238 | + $this->editUpdates(); |
| 239 | + |
| 240 | + $s = str_replace( "$1", $wgTitle->getPrefixedText, |
| 241 | + wfMsg( "newarticle" ) ); |
| 242 | + $wgOut->setPageTitle( $s ); |
| 243 | + $wgOut->addWikiText( $text ); |
| 244 | + } |
| 245 | + |
| 246 | + function updateArticle( $text, $summary, $minor ) |
| 247 | + { |
| 248 | + global $wgOut, $wgUser, $wgTitle; |
| 249 | + |
| 250 | + if ( $minor) { $me = 1; } else { $me = 0; } |
| 251 | + |
| 252 | + $conn = wfGetDB(); |
| 253 | + $sql = "UPDATE cur SET cur_text='" . wfStrencode( $text ) . |
| 254 | + "',cur_comment='" . wfStrencode( $summary ) . |
| 255 | + "',cur_minor_edit=$me, cur_user=" . $wgUser->getID() . |
| 256 | + ", cur_timestamp='" . date( "YmdHis" ) . "' " . |
| 257 | + "WHERE cur_id=" . $this->getID(); |
| 258 | + |
| 259 | + wfDebug( "Art: 4: $sql\n" ); |
| 260 | + $res = mysql_query( $sql, $conn ); |
| 261 | + $this->editUpdates(); |
| 262 | + |
| 263 | + $s = str_replace( "$1", $wgTitle->getPrefixedText(), |
| 264 | + wfMsg( "updated" ) ); |
| 265 | + $wgOut->setPageTitle( $s ); |
| 266 | + $wgOut->addWikiText( $text ); |
| 267 | + } |
| 268 | + |
187 | 269 | function viewprintable() |
188 | 270 | { |
189 | | - global $wgOut, $wgUser; |
| 271 | + global $wgOut, $wgUser, $wgTitle; |
190 | 272 | |
191 | 273 | $n = $this->mTitle->getPrefixedText(); |
192 | 274 | $wgOut->setPageTitle( $n ); |
Index: trunk/phpwiki/newcodebase/GlobalFunctions.php |
— | — | @@ -126,7 +126,7 @@ |
127 | 127 | wfDebug( "Glob: 1: $sql\n" ); |
128 | 128 | |
129 | 129 | $res = mysql_query( $sql, $conn ); |
130 | | - if ( ! $res ) { return; } |
| 130 | + if ( ! $res || 0 == mysql_num_rows( $res) ) { return; } |
131 | 131 | else { |
132 | 132 | $s = mysql_fetch_object( $res ); |
133 | 133 | $wgTotalViews = $s->ss_total_views; |
Index: trunk/phpwiki/newcodebase/SpecialPreferences.php |
— | — | @@ -50,7 +50,6 @@ |
51 | 51 | $wgUser->setOption( $tname, $HTTP_POST_VARS["wpOp$tname"] ); |
52 | 52 | } |
53 | 53 | $wgUser->setCookies(); |
54 | | - |
55 | 54 | $up = new UserUpdate(); |
56 | 55 | array_push( $wgDeferredUpdateList, $up ); |
57 | 56 | mainPrefsForm( wfMsg( "savedprefs" ) ); |
Index: trunk/phpwiki/newcodebase/SpecialUserlogin.php |
— | — | @@ -118,7 +118,7 @@ |
119 | 119 | { |
120 | 120 | global $wgOut; |
121 | 121 | |
122 | | - $wgOut->setPageTitle( "loginsuccesstitle" ); |
| 122 | + $wgOut->setPageTitle( wfMsg( "loginsuccesstitle" ) ); |
123 | 123 | $wgOut->setRobotpolicy( "noindex,nofollow" ); |
124 | 124 | $wgOut->addHTML( $msg . "\n<p>" ); |
125 | 125 | $wgOut->addWikiText( wfMsg( "returntomain" ) ); |
Index: trunk/phpwiki/newcodebase/sql/buildtables.sql |
— | — | @@ -97,7 +97,8 @@ |
98 | 98 | CREATE TABLE ipblocks ( |
99 | 99 | ipb_address varchar(40) binary default '', |
100 | 100 | ipb_user mediumint(8) unsigned default '0', |
101 | | - ipb_reason mediumtext, |
| 101 | + ipb_by mediumint(8) unsigned default '0', |
| 102 | + ipb_reason mediumtext default '', |
102 | 103 | INDEX ipb_address (ipb_address), |
103 | 104 | INDEX ipb_user (ipb_user) |
104 | 105 | ) TYPE=MyISAM; |