Index: trunk/extensions/Translate/tag/TranslatablePage.php |
— | — | @@ -316,6 +316,19 @@ |
317 | 317 | return $this->getTag( 'tp:tag' ); |
318 | 318 | } |
319 | 319 | |
| 320 | + public function removeTags() { |
| 321 | + $dbw = wfGetDB( DB_MASTER ); |
| 322 | + $conds = array( |
| 323 | + 'rt_page' => $this->getTitle()->getArticleId(), |
| 324 | + 'rt_type' => array( |
| 325 | + $this->getTagId( 'tp:mark' ), |
| 326 | + $this->getTagId( 'tp:tag' ), |
| 327 | + ), |
| 328 | + ); |
| 329 | + |
| 330 | + $dbw->delete( 'revtag', $conds, __METHOD__ ); |
| 331 | + } |
| 332 | + |
320 | 333 | // Returns false if not found |
321 | 334 | protected function getTag( $tag, $dbt = DB_SLAVE ) { |
322 | 335 | $db = wfGetDB( $dbt ); |
Index: trunk/extensions/Translate/tag/SpecialPageTranslation.php |
— | — | @@ -40,12 +40,25 @@ |
41 | 41 | return; |
42 | 42 | } |
43 | 43 | |
| 44 | + // Check permissions |
| 45 | + if (!$this->user->matchEditToken( $wgRequest->getText( 'token' ) ) ) { |
| 46 | + $wgOut->permissionRequired( 'pagetranslation' ); |
| 47 | + return; |
| 48 | + } |
| 49 | + |
44 | 50 | // We are processing some specific page |
45 | 51 | if ( !$title->exists() ) { |
46 | 52 | $wgOut->addWikiMsg( 'tpt-nosuchpage', $title->getPrefixedText() ); |
47 | 53 | return; |
48 | 54 | } |
49 | 55 | |
| 56 | + if ( $revision === -1 ) { |
| 57 | + $page = TranslatablePage::newFromTitle( $title ); |
| 58 | + $page->removeTags(); |
| 59 | + $wgOut->addWikiMsg( 'tpt-unmarked', $title->getPrefixedText() ); |
| 60 | + return; |
| 61 | + } |
| 62 | + |
50 | 63 | if ( $revision === 0 ) { |
51 | 64 | // Get the latest revision |
52 | 65 | $revision = $title->getLatestRevID(); |
— | — | @@ -122,59 +135,81 @@ |
123 | 136 | return; |
124 | 137 | } |
125 | 138 | |
126 | | - $old = $new = array(); |
| 139 | + $pages = array(); |
127 | 140 | foreach ( $res as $r ) { |
128 | | - if ( $r->rtt_name === 'tp:mark' ) { |
129 | | - $old[$r->page_id] = array( |
130 | | - $r->rt_revision, |
131 | | - Title::newFromRow( $r ) |
132 | | - ); |
133 | | - } elseif ( $r->rtt_name === 'tp:tag' ) { |
134 | | - $new[$r->page_id] = array( |
135 | | - $r->rt_revision, |
136 | | - Title::newFromRow( $r ) |
137 | | - ); |
| 141 | + if ( !isset( $pages[$r->page_id] ) ) { |
| 142 | + $pages[$r->page_id] = array(); |
| 143 | + $pages[$r->page_id]['title'] = Title::newFromRow( $r ); |
138 | 144 | } |
| 145 | + $pages[$r->page_id][$r->rtt_name] = $r->rt_revision; |
139 | 146 | } |
140 | 147 | |
141 | | - // Pages may have both tags, ignore the transtag if both |
142 | | - foreach ( array_keys( $old ) as $k ) unset( $new[$k] ); |
| 148 | + // Pages where mark <= tag |
| 149 | + $items = array(); |
| 150 | + foreach ( $pages as $index => $page ) { |
| 151 | + if ( !isset( $page['tp:mark'] ) ) continue; |
| 152 | + if ( !isset( $page['tp:tag'] ) ) continue; |
| 153 | + if ( $page['tp:mark'] > $page['tp:tag'] ) continue; |
| 154 | + $link = $this->user->getSkin()->link( $page['title'] ); |
| 155 | + $acts = $this->actionLinks( $page['title'], $page['tp:mark'], 'old' ); |
| 156 | + $items[] = "<li>$link ($acts) </li>"; |
| 157 | + unset( $pages[$index] ); |
| 158 | + } |
143 | 159 | |
144 | | - if ( count( $old ) ) { |
145 | | - $wgOut->addWikiMsg( 'tpt-old-pages', count( $old ) ); |
146 | | - $wgOut->addHTML( '<ol>' ); |
147 | | - foreach ( $old as $o ) { |
148 | | - list( $rev, $title ) = $o; |
149 | | - $link = $this->user->getSkin()->link( $title ); |
150 | | - $acts = $this->actionLinks( $title, $rev, 'old' ); |
151 | | - $wgOut->addHTML( "<li>$link ($acts) </li>" ); |
152 | | - } |
153 | | - $wgOut->addHTML( '</ol>' ); |
| 160 | + if ( count($items) ) { |
| 161 | + $wgOut->addWikiMsg( 'tpt-old-pages', count( $items ) ); |
| 162 | + $wgOut->addHtml( Html::rawElement( 'ol', null, implode( "\n", $items ) ) ); |
| 163 | + $wgOut->addHtml( '<hr />' ); |
154 | 164 | } |
155 | 165 | |
156 | | - if ( count( $new ) ) { |
157 | | - $wgOut->addWikiMsg( 'tpt-new-pages', count( $new ) ); |
158 | | - $wgOut->addHTML( '<ol>' ); |
159 | | - foreach ( $new as $n ) { |
160 | | - list( $rev, $title ) = $n; |
161 | | - $link = $this->user->getSkin()->link( $title ); |
162 | | - $acts = $this->actionLinks( $title, $rev, 'new' ); |
163 | | - $wgOut->addHTML( "<li>$link ($acts) </li>" ); |
164 | | - } |
165 | | - $wgOut->addHTML( '</ol>' ); |
| 166 | + // Pages which are never marked |
| 167 | + $items = array(); |
| 168 | + foreach ( $pages as $index => $page ) { |
| 169 | + if ( isset( $page['tp:mark'] ) ) continue; |
| 170 | + if ( !isset( $page['tp:tag'] ) ) continue; |
| 171 | + $link = $this->user->getSkin()->link( $page['title'] ); |
| 172 | + $acts = $this->actionLinks( $page['title'], $page['tp:tag'], 'old' ); |
| 173 | + $items[] = "<li>$link ($acts) </li>"; |
| 174 | + unset( $pages[$index] ); |
166 | 175 | } |
167 | 176 | |
| 177 | + if ( count($items) ) { |
| 178 | + $wgOut->addWikiMsg( 'tpt-new-pages', count( $items ) ); |
| 179 | + $wgOut->addHtml( Html::rawElement( 'ol', null, implode( "\n", $items ) ) ); |
| 180 | + $wgOut->addHtml( '<hr />' ); |
| 181 | + } |
| 182 | + |
| 183 | + /* Pages which have been marked in the past, but newest version does |
| 184 | + * not have a tag */ |
| 185 | + $items = array(); |
| 186 | + foreach ( $pages as $index => $page ) { |
| 187 | + $link = $this->user->getSkin()->link( $page['title'] ); |
| 188 | + $acts = $this->actionLinks( $page['title'], $page['tp:tag'], 'stuck' ); |
| 189 | + $items[] = "<li>$link ($acts) </li>"; |
| 190 | + unset( $pages[$index] ); |
| 191 | + } |
| 192 | + |
| 193 | + if ( count($items) ) { |
| 194 | + $wgOut->addWikiMsg( 'tpt-other-pages', count( $items ) ); |
| 195 | + $wgOut->addHtml( Html::rawElement( 'ol', null, implode( "\n", $items ) ) ); |
| 196 | + $wgOut->addHtml( '<hr />' ); |
| 197 | + } |
| 198 | + |
168 | 199 | } |
169 | 200 | |
170 | 201 | protected function actionLinks( $title, $rev, $old = 'old' ) { |
171 | 202 | $actions = array(); |
| 203 | + |
172 | 204 | $latest = $title->getLatestRevId(); |
173 | | - |
174 | | - if ( $latest !== $rev ) { |
175 | | - $text = wfMsg( 'tpt-rev-old', $rev ); |
| 205 | + /* For pages that have been marked for translation at some point, |
| 206 | + * but there has been new changes since then, provide a link to |
| 207 | + * to view the differences between last marked version and latest |
| 208 | + * version of the page. |
| 209 | + */ |
| 210 | + if ( $latest !== $rev && $old !== 'new' ) { |
176 | 211 | $actions[] = $this->user->getSkin()->link( |
177 | 212 | $title, |
178 | | - htmlspecialchars( $text ), |
| 213 | + htmlspecialchars( wfMsg( 'tpt-rev-old', $rev ) ), |
179 | 214 | array(), |
180 | 215 | array( 'oldid' => $rev, 'diff' => $title->getLatestRevId() ) |
181 | 216 | ); |
— | — | @@ -182,18 +217,33 @@ |
183 | 218 | $actions[] = wfMsgHtml( 'tpt-rev-latest' ); |
184 | 219 | } |
185 | 220 | |
186 | | - if ( $this->user->isAllowed( 'pagetranslation' ) && |
187 | | - ( ( $old === 'new' && $latest === $rev ) || |
188 | | - ( $old === 'old' && $latest !== $rev ) ) ) { |
189 | | - $actions[] = $this->user->getSkin()->link( |
190 | | - $this->getTitle(), |
191 | | - wfMsgHtml( 'tpt-rev-mark-new' ), |
192 | | - array(), |
193 | | - array( |
194 | | - 'target' => $title->getPrefixedText(), |
195 | | - 'revision' => $title->getLatestRevId() |
196 | | - ) |
197 | | - ); |
| 221 | + if ( $this->user->isAllowed( 'pagetranslation' ) ) { |
| 222 | + $token = $this->user->editToken(); |
| 223 | + |
| 224 | + if ( ( $old === 'new' && $latest === $rev ) || |
| 225 | + ( $old === 'old' && $latest !== $rev ) ) { |
| 226 | + $actions[] = $this->user->getSkin()->link( |
| 227 | + $this->getTitle(), |
| 228 | + wfMsgHtml( 'tpt-rev-mark-new' ), |
| 229 | + array(), |
| 230 | + array( |
| 231 | + 'target' => $title->getPrefixedText(), |
| 232 | + 'revision' => $title->getLatestRevId(), |
| 233 | + 'token' => $token, |
| 234 | + ) |
| 235 | + ); |
| 236 | + } elseif ( $old === 'stuck' ) { |
| 237 | + $actions[] = $this->user->getSkin()->link( |
| 238 | + $this->getTitle(), |
| 239 | + wfMsgHtml( 'tpt-rev-unmark' ), |
| 240 | + array(), |
| 241 | + array( |
| 242 | + 'target' => $title->getPrefixedText(), |
| 243 | + 'revision' => -1, |
| 244 | + 'token' => $token, |
| 245 | + ) |
| 246 | + ); |
| 247 | + } |
198 | 248 | } |
199 | 249 | |
200 | 250 | if ( $old === 'old' && $this->user->isAllowed( 'translate' ) ) { |
— | — | @@ -206,13 +256,7 @@ |
207 | 257 | } |
208 | 258 | |
209 | 259 | global $wgLang; |
210 | | - if ( method_exists( $wgLang, 'semicolonList' ) ) { |
211 | | - // BC for <1.15 |
212 | | - $actionText = $wgLang->semicolonList( $actions ); |
213 | | - } else { |
214 | | - $actionText = implode( '; ', $actions ); |
215 | | - } |
216 | | - return $actionText; |
| 260 | + return $wgLang->semicolonList( $actions ); |
217 | 261 | } |
218 | 262 | |
219 | 263 | public function checkInput( TranslatablePage $page, &$error = false ) { |
— | — | @@ -230,9 +274,10 @@ |
231 | 275 | |
232 | 276 | $name = $wgRequest->getText( 'tpt-sect-' . $s->id, $s->id ); |
233 | 277 | |
| 278 | + // Make sure valid title can be constructed |
234 | 279 | $sectionTitle = Title::makeTitleSafe( |
235 | 280 | NS_TRANSLATIONS, |
236 | | - $page->getTitle()->getPrefixedText() . '/' . $name . '/qqq' |
| 281 | + $page->getTitle()->getPrefixedText() . '/' . $name . '/foo' |
237 | 282 | ); |
238 | 283 | if ( trim( $name ) === '' || !$sectionTitle ) { |
239 | 284 | $wgOut->addWikiMsg( 'tpt-badsect', $name, $s->id ); |
Index: trunk/extensions/Translate/PageTranslation.i18n.php |
— | — | @@ -44,14 +44,19 @@ |
45 | 45 | 'tpt-mark-summary' => 'Marked this version for translation', |
46 | 46 | 'tpt-edit-failed' => 'Could not update the page: $1', |
47 | 47 | 'tpt-already-marked' => 'The latest version of this page has already been marked for translation.', |
| 48 | + 'tpt-unmarked' => 'Page $1 is no longer marked for translation.', |
48 | 49 | |
49 | 50 | # Page list on the special page |
50 | 51 | 'tpt-list-nopages' => 'No pages are marked for translation nor ready to be marked for translation.', |
51 | 52 | 'tpt-old-pages' => 'Some version of {{PLURAL:$1|this page has|these pages have}} been marked for translation.', |
52 | | - 'tpt-new-pages' => '{{PLURAL:$1|This page contains|These pages contain}} text with translation tags, but no version of {{PLURAL:$1|this page is|these pages are}} currently marked for translation.', |
| 53 | + 'tpt-new-pages' => '{{PLURAL:$1|This page contains|These pages contain}} text with translation tags, |
| 54 | +but no version of {{PLURAL:$1|this page is|these pages are}} currently marked for translation.', |
| 55 | + 'tpt-other-pages' => 'Old version of {{PLURAL:$1|this page is|these pages are}} marked for translation, |
| 56 | +but the current version cannot be marked for translation.', |
53 | 57 | 'tpt-rev-latest' => 'latest version', |
54 | 58 | 'tpt-rev-old' => 'difference to previous marked version', |
55 | 59 | 'tpt-rev-mark-new' => 'mark this version for translation', |
| 60 | + 'tpt-rev-unmark' => 'remove this page from translation', |
56 | 61 | 'tpt-translate-this' => 'translate this page', |
57 | 62 | |
58 | 63 | # Source and translation page headers |