MediaWiki 1.44.0
TextConflictHelper.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\EditPage;
22
33
41
45 protected $title;
46
51
56
60 protected $out;
61
65 protected $stats;
66
70 protected $submitLabel;
71
75 protected $yourtext = '';
76
80 protected $storedversion = '';
81
85 private $contentHandlerFactory;
86
96 public function __construct(
98 IContentHandlerFactory $contentHandlerFactory
99 ) {
100 $this->title = $title;
101 $this->out = $out;
102 $this->stats = $stats;
103 $this->submitLabel = $submitLabel;
104 $this->contentModel = $title->getContentModel();
105 $this->contentHandlerFactory = $contentHandlerFactory;
106
107 $this->contentFormat = $this->contentHandlerFactory
108 ->getContentHandler( $this->contentModel )
109 ->getDefaultFormat();
110 }
111
117 $this->yourtext = $yourtext;
118 $this->storedversion = $storedversion;
119 }
120
124 public function setContentModel( $contentModel ) {
125 $this->contentModel = $contentModel;
126 }
127
131 public function setContentFormat( $contentFormat ) {
132 $this->contentFormat = $contentFormat;
133 }
134
139 public function incrementConflictStats( ?User $user = null ) {
140 $namespace = 'n/a';
141 $userBucket = 'n/a';
142 $statsdMetrics = [ 'edit.failures.conflict' ];
143
144 // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics
145 if (
146 $this->title->getNamespace() >= NS_MAIN &&
147 $this->title->getNamespace() <= NS_CATEGORY_TALK
148 ) {
149 // getNsText() returns empty string if getNamespace() === NS_MAIN
150 $namespace = $this->title->getNsText() ?: 'Main';
151 $statsdMetrics[] = 'edit.failures.conflict.byNamespaceId.' . $this->title->getNamespace();
152 }
153 if ( $user ) {
154 $userBucket = $this->getUserBucket( $user->getEditCount() );
155 $statsdMetrics[] = 'edit.failures.conflict.byUserEdits.' . $userBucket;
156 }
157 if ( $this->stats instanceof StatsFactory ) {
158 $this->stats->getCounter( 'edit_failure_total' )
159 ->setLabel( 'cause', 'conflict' )
160 ->setLabel( 'namespace', $namespace )
161 ->setLabel( 'user_bucket', $userBucket )
162 ->copyToStatsdAt( $statsdMetrics )
163 ->increment();
164 }
165
166 if ( $this->stats instanceof IBufferingStatsdDataFactory ) {
167 foreach ( $statsdMetrics as $metric ) {
168 $this->stats->increment( $metric );
169 }
170 }
171 }
172
177 public function incrementResolvedStats( ?User $user = null ) {
178 $namespace = 'n/a';
179 $userBucket = 'n/a';
180 $statsdMetrics = [ 'edit.failures.conflict.resolved' ];
181
182 // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics
183 if (
184 $this->title->getNamespace() >= NS_MAIN &&
185 $this->title->getNamespace() <= NS_CATEGORY_TALK
186 ) {
187 // getNsText() returns empty string if getNamespace() === NS_MAIN
188 $namespace = $this->title->getNsText() ?: 'Main';
189 $statsdMetrics[] = 'edit.failures.conflict.resolved.byNamespaceId.' . $this->title->getNamespace();
190 }
191
192 if ( $user ) {
193 $userBucket = $this->getUserBucket( $user->getEditCount() );
194 $statsdMetrics[] = 'edit.failures.conflict.resolved.byUserEdits.' . $userBucket;
195 }
196
197 if ( $this->stats instanceof StatsFactory ) {
198 $this->stats->getCounter( 'edit_failure_resolved_total' )
199 ->setLabel( 'cause', 'conflict' )
200 ->setLabel( 'namespace', $namespace )
201 ->setLabel( 'user_bucket', $userBucket )
202 ->copyToStatsdAt( $statsdMetrics )
203 ->increment();
204 }
205
206 if ( $this->stats instanceof IBufferingStatsdDataFactory ) {
207 foreach ( $statsdMetrics as $metric ) {
208 $this->stats->increment( $metric );
209 }
210 }
211 }
212
222 protected function incrementStatsByUserEdits( $userEdits, $keyPrefixBase ) {
223 if ( $this->stats instanceof IBufferingStatsdDataFactory ) {
224 $this->stats->increment( $keyPrefixBase . '.byUserEdits.' . $this->getUserBucket( $userEdits ) );
225 }
226 }
227
232 protected function getUserBucket( ?int $userEdits ): string {
233 if ( $userEdits === null ) {
234 return 'anon';
235 } elseif ( $userEdits > 200 ) {
236 return 'over200';
237 } elseif ( $userEdits > 100 ) {
238 return 'over100';
239 } elseif ( $userEdits > 10 ) {
240 return 'over10';
241 } else {
242 return 'under11';
243 }
244 }
245
249 public function getExplainHeader() {
250 return Html::rawElement(
251 'div',
252 [ 'class' => 'mw-explainconflict' ],
253 $this->out->msg( 'explainconflict', $this->out->msg( $this->submitLabel )->text() )->parse()
254 );
255 }
256
263 public function getEditConflictMainTextBox( array $customAttribs = [] ) {
264 $builder = new TextboxBuilder();
265 $classes = $builder->getTextboxProtectionCSSClasses( $this->title );
266
267 $attribs = [
268 'aria-label' => $this->out->msg( 'edit-textarea-aria-label' )->text(),
269 'tabindex' => 1,
270 ];
271 $attribs += $customAttribs;
272 foreach ( $classes as $class ) {
273 Html::addClass( $attribs['class'], $class );
274 }
275
276 $attribs = $builder->buildTextboxAttribs(
277 'wpTextbox1',
278 $attribs,
279 $this->out->getUser(),
280 $this->title
281 );
282
283 return Html::textarea(
284 'wpTextbox1',
285 $builder->addNewLineAtEnd( $this->storedversion ),
286 $attribs
287 );
288 }
289
297 return '';
298 }
299
306 public function getEditFormHtmlAfterContent() {
307 return '';
308 }
309
315 $this->out->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
316
317 $yourContent = $this->toEditContent( $this->yourtext );
318 $storedContent = $this->toEditContent( $this->storedversion );
319 $handler = $this->contentHandlerFactory->getContentHandler( $this->contentModel );
320 $diffEngine = $handler->createDifferenceEngine( $this->out );
321
322 $diffEngine->setContent( $yourContent, $storedContent );
323 $diffEngine->showDiff(
324 $this->out->msg( 'yourtext' )->parse(),
325 $this->out->msg( 'storedversion' )->text()
326 );
327
328 $this->out->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
329
330 $builder = new TextboxBuilder();
331 $attribs = $builder->buildTextboxAttribs(
332 'wpTextbox2',
333 [ 'tabindex' => 6, 'readonly' ],
334 $this->out->getUser(),
335 $this->title
336 );
337
338 $this->out->addHTML(
339 Html::textarea( 'wpTextbox2', $builder->addNewLineAtEnd( $this->yourtext ), $attribs )
340 );
341 }
342
347 private function toEditContent( $text ) {
348 return ContentHandler::makeContent(
349 $text,
350 $this->title,
351 $this->contentModel,
352 $this->contentFormat
353 );
354 }
355}
const NS_MAIN
Definition Defines.php:65
const NS_CATEGORY_TALK
Definition Defines.php:80
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:82
Base class for content handling.
Helper for displaying edit conflicts in text content models to users.
incrementConflictStats(?User $user=null)
Record a user encountering an edit conflict.
getEditFormHtmlAfterContent()
Content to go in the edit form after textbox1.
getEditConflictMainTextBox(array $customAttribs=[])
HTML to build the textbox1 on edit conflicts.
showEditFormTextAfterFooters()
Content to go in the edit form after the footers (templates on this page, hidden categories,...
__construct(Title $title, OutputPage $out, $stats, $submitLabel, IContentHandlerFactory $contentHandlerFactory)
incrementResolvedStats(?User $user=null)
Record when a user has resolved an edit conflict.
IBufferingStatsdDataFactory StatsFactory $stats
setTextboxes( $yourtext, $storedversion)
incrementStatsByUserEdits( $userEdits, $keyPrefixBase)
Retained temporarily for backwards-compatibility.
string $submitLabel
Message key for submit button's label.
getEditFormHtmlBeforeContent()
Content to go in the edit form before textbox1.
Helps EditPage build textboxes.
Exception thrown when an unregistered content model is requested.
This class is a collection of static functions that serve two purposes:
Definition Html.php:57
This is one of the Core classes and should be read at least once by any new developers.
Represents a title within MediaWiki.
Definition Title.php:78
getContentModel( $flags=0)
Get the page's content model id, see the CONTENT_MODEL_XXX constants.
Definition Title.php:1068
User class for the MediaWiki software.
Definition User.php:121
This is the primary interface for validating metrics definitions, caching defined metrics,...
Content objects represent page content, e.g.
Definition Content.php:42
getContentHandler(string $modelID)
Returns a ContentHandler instance for the given $modelID.
MediaWiki adaptation of StatsdDataFactory that provides buffering functionality.