Merge "Add semantic tags to license info text"
[lhc/web/wiklou.git] / includes / editpage / TextConflictHelper.php
1 <?php
2 /**
3 * Helper for displaying edit conflicts to users
4 *
5 * Copyright (C) 2017 Kunal Mehta <legoktm@member.fsf.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * http://www.gnu.org/copyleft/gpl.html
21 *
22 * @file
23 */
24
25 namespace MediaWiki\EditPage;
26
27 use Content;
28 use ContentHandler;
29 use Html;
30 use IBufferingStatsdDataFactory;
31 use OutputPage;
32 use Title;
33
34 /**
35 * Helper for displaying edit conflicts in text content
36 * models to users
37 *
38 * @since 1.31
39 */
40 class TextConflictHelper {
41
42 /**
43 * @var Title
44 */
45 protected $title;
46
47 /**
48 * @var null|string
49 */
50 public $contentModel = null;
51
52 /**
53 * @var null|string
54 */
55 public $contentFormat = null;
56
57 /**
58 * @var OutputPage
59 */
60 protected $out;
61
62 /**
63 * @var IBufferingStatsdDataFactory
64 */
65 protected $stats;
66
67 /**
68 * @var string Message key for submit button's label
69 */
70 protected $submitLabel;
71
72 /**
73 * @var string
74 */
75 protected $yourtext = '';
76
77 /**
78 * @var string
79 */
80 protected $storedversion = '';
81
82 /**
83 * @param Title $title
84 * @param OutputPage $out
85 * @param IBufferingStatsdDataFactory $stats
86 * @param string $submitLabel
87 */
88 public function __construct( Title $title, OutputPage $out, IBufferingStatsdDataFactory $stats,
89 $submitLabel
90 ) {
91 $this->title = $title;
92 $this->out = $out;
93 $this->stats = $stats;
94 $this->submitLabel = $submitLabel;
95 $this->contentModel = $title->getContentModel();
96 $this->contentFormat = ContentHandler::getForModelID( $this->contentModel )->getDefaultFormat();
97 }
98
99 /**
100 * @param string $yourtext
101 * @param string $storedversion
102 */
103 public function setTextboxes( $yourtext, $storedversion ) {
104 $this->yourtext = $yourtext;
105 $this->storedversion = $storedversion;
106 }
107
108 /**
109 * @param string $contentModel
110 */
111 public function setContentModel( $contentModel ) {
112 $this->contentModel = $contentModel;
113 }
114
115 /**
116 * @param string $contentFormat
117 */
118 public function setContentFormat( $contentFormat ) {
119 $this->contentFormat = $contentFormat;
120 }
121
122 /**
123 * Record a user encountering an edit conflict
124 */
125 public function incrementConflictStats() {
126 $this->stats->increment( 'edit.failures.conflict' );
127 // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics
128 if (
129 $this->title->getNamespace() >= NS_MAIN &&
130 $this->title->getNamespace() <= NS_CATEGORY_TALK
131 ) {
132 $this->stats->increment(
133 'edit.failures.conflict.byNamespaceId.' . $this->title->getNamespace()
134 );
135 }
136 }
137
138 /**
139 * Record when a user has resolved an edit conflict
140 */
141 public function incrementResolvedStats() {
142 $this->stats->increment( 'edit.failures.conflict.resolved' );
143 // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics
144 if (
145 $this->title->getNamespace() >= NS_MAIN &&
146 $this->title->getNamespace() <= NS_CATEGORY_TALK
147 ) {
148 $this->stats->increment(
149 'edit.failures.conflict.resolved.byNamespaceId.' . $this->title->getNamespace()
150 );
151 }
152 }
153
154 /**
155 * @return string HTML
156 */
157 public function getExplainHeader() {
158 return Html::rawElement(
159 'div',
160 [ 'class' => 'mw-explainconflict' ],
161 $this->out->msg( 'explainconflict', $this->out->msg( $this->submitLabel )->text() )->parse()
162 );
163 }
164
165 /**
166 * HTML to build the textbox1 on edit conflicts
167 *
168 * @param mixed[]|null $customAttribs
169 * @return string HTML
170 */
171 public function getEditConflictMainTextBox( $customAttribs = [] ) {
172 $builder = new TextboxBuilder();
173 $classes = $builder->getTextboxProtectionCSSClasses( $this->title );
174
175 $attribs = [ 'tabindex' => 1 ];
176 $attribs += $customAttribs;
177
178 $attribs = $builder->mergeClassesIntoAttributes( $classes, $attribs );
179
180 $attribs = $builder->buildTextboxAttribs(
181 'wpTextbox1',
182 $attribs,
183 $this->out->getUser(),
184 $this->title
185 );
186
187 $this->out->addHTML(
188 Html::textarea( 'wpTextbox1', $builder->addNewLineAtEnd( $this->storedversion ), $attribs )
189 );
190 }
191
192 /**
193 * Content to go in the edit form before textbox1
194 *
195 * @see EditPage::$editFormTextBeforeContent
196 * @return string HTML
197 */
198 public function getEditFormHtmlBeforeContent() {
199 return '';
200 }
201
202 /**
203 * Content to go in the edit form after textbox1
204 *
205 * @see EditPage::$editFormTextAfterContent
206 * @return string HTML
207 */
208 public function getEditFormHtmlAfterContent() {
209 return '';
210 }
211
212 /**
213 * Content to go in the edit form after the footers
214 * (templates on this page, hidden categories, limit report)
215 */
216 public function showEditFormTextAfterFooters() {
217 $this->out->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
218
219 $yourContent = $this->toEditContent( $this->yourtext );
220 $storedContent = $this->toEditContent( $this->storedversion );
221 $handler = ContentHandler::getForModelID( $this->contentModel );
222 $diffEngine = $handler->createDifferenceEngine( $this->out );
223
224 $diffEngine->setContent( $yourContent, $storedContent );
225 $diffEngine->showDiff(
226 $this->out->msg( 'yourtext' )->parse(),
227 $this->out->msg( 'storedversion' )->text()
228 );
229
230 $this->out->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
231
232 $builder = new TextboxBuilder();
233 $attribs = $builder->buildTextboxAttribs(
234 'wpTextbox2',
235 [ 'tabindex' => 6, 'readonly' ],
236 $this->out->getUser(),
237 $this->title
238 );
239
240 $this->out->addHTML(
241 Html::textarea( 'wpTextbox2', $builder->addNewLineAtEnd( $this->yourtext ), $attribs )
242 );
243 }
244
245 /**
246 * @param string $text
247 * @return Content
248 */
249 public function toEditContent( $text ) {
250 return ContentHandler::makeContent(
251 $text,
252 $this->title,
253 $this->contentModel,
254 $this->contentFormat
255 );
256 }
257 }