MediaWiki REL1_39
WikitextContent.php
Go to the documentation of this file.
1<?php
30
38 private $redirectTargetAndText = null;
39
43 private $preSaveTransformFlags = [];
44
50 public function __construct( $text ) {
51 parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
52 }
53
61 public function getSection( $sectionId ) {
62 $text = $this->getText();
63 $sect = MediaWikiServices::getInstance()->getParserFactory()->getInstance()
64 ->getSection( $text, $sectionId, false );
65
66 if ( $sect === false ) {
67 return false;
68 } else {
69 return new static( $sect );
70 }
71 }
72
83 public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) {
84 // @phan-suppress-previous-line PhanParamSignatureMismatch False positive
85 $myModelId = $this->getModel();
86 $sectionModelId = $with->getModel();
87
88 if ( $sectionModelId != $myModelId ) {
89 throw new MWException( "Incompatible content model for section: " .
90 "document uses $myModelId but " .
91 "section uses $sectionModelId." );
92 }
94 '@phan-var self $with';
95
96 $oldtext = $this->getText();
97 $text = $with->getText();
98
99 if ( strval( $sectionId ) === '' ) {
100 return $with; # XXX: copy first?
101 }
102
103 if ( $sectionId === 'new' ) {
104 # Inserting a new section
105 $subject = strval( $sectionTitle ) !== '' ? wfMessage( 'newsectionheaderdefaultlevel' )
106 ->plaintextParams( $sectionTitle )->inContentLanguage()->text() . "\n\n" : '';
107 if ( Hooks::runner()->onPlaceNewSection( $this, $oldtext, $subject, $text ) ) {
108 $text = strlen( trim( $oldtext ) ) > 0
109 ? "{$oldtext}\n\n{$subject}{$text}"
110 : "{$subject}{$text}";
111 }
112 } else {
113 # Replacing an existing section; roll out the big guns
114 $text = MediaWikiServices::getInstance()->getParserFactory()->getInstance()
115 ->replaceSection( $oldtext, $sectionId, $text );
116 }
117
118 $newContent = new static( $text );
119
120 return $newContent;
121 }
122
131 public function addSectionHeader( $header ) {
132 $text = strval( $header ) !== '' ? wfMessage( 'newsectionheaderdefaultlevel' )
133 ->plaintextParams( $header )->inContentLanguage()->text() . "\n\n" : '';
134 $text .= $this->getText();
135
136 return new static( $text );
137 }
138
148 public function getRedirectTargetAndText() {
149 if ( $this->redirectTargetAndText !== null ) {
150 return $this->redirectTargetAndText;
151 }
152
153 $redir = MediaWikiServices::getInstance()->getMagicWordFactory()->get( 'redirect' );
154 $text = ltrim( $this->getText() );
155 if ( $redir->matchStartAndRemove( $text ) ) {
156 // Extract the first link and see if it's usable
157 // Ensure that it really does come directly after #REDIRECT
158 // Some older redirects included a colon, so don't freak about that!
159 $m = [];
160 if ( preg_match( '!^\s*:?\s*\[{2}(.*?)(?:\|.*?)?\]{2}\s*!', $text, $m ) ) {
161 // Strip preceding colon used to "escape" categories, etc.
162 // and URL-decode links
163 if ( strpos( $m[1], '%' ) !== false ) {
164 // Match behavior of inline link parsing here;
165 $m[1] = rawurldecode( ltrim( $m[1], ':' ) );
166 }
167 $title = Title::newFromText( $m[1] );
168 // If the title is a redirect to bad special pages or is invalid, return null
169 if ( !$title instanceof Title || !$title->isValidRedirectTarget() ) {
170 $this->redirectTargetAndText = [ null, $this->getText() ];
171 return $this->redirectTargetAndText;
172 }
173
174 $this->redirectTargetAndText = [ $title, substr( $text, strlen( $m[0] ) ) ];
175 return $this->redirectTargetAndText;
176 }
177 }
178
179 $this->redirectTargetAndText = [ null, $this->getText() ];
180 return $this->redirectTargetAndText;
181 }
182
190 public function getRedirectTarget() {
191 list( $title, ) = $this->getRedirectTargetAndText();
192
193 return $title;
194 }
195
208 public function updateRedirect( Title $target ) {
209 if ( !$this->isRedirect() ) {
210 return $this;
211 }
212
213 # Fix the text
214 # Remember that redirect pages can have categories, templates, etc.,
215 # so the regex has to be fairly general
216 $newText = preg_replace( '/ \[ \[ [^\]]* \] \] /x',
217 '[[' . $target->getFullText() . ']]',
218 $this->getText(), 1 );
219
220 return new static( $newText );
221 }
222
234 public function isCountable( $hasLinks = null, Title $title = null ) {
235 $articleCountMethod = MediaWikiServices::getInstance()->getMainConfig()
236 ->get( MainConfigNames::ArticleCountMethod );
237
238 if ( $this->isRedirect() ) {
239 return false;
240 }
241
242 if ( $articleCountMethod === 'link' ) {
243 if ( $hasLinks === null ) { # not known, find out
244 // @TODO: require an injected title
245 if ( !$title ) {
246 $context = RequestContext::getMain();
247 $title = $context->getTitle();
248 }
249 $contentRenderer = MediaWikiServices::getInstance()->getContentRenderer();
250 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable getTitle does not return null here
251 $po = $contentRenderer->getParserOutput( $this, $title, null, null, false );
252 $links = $po->getLinks();
253 $hasLinks = !empty( $links );
254 }
255
256 return $hasLinks;
257 }
258
259 return true;
260 }
261
266 public function getTextForSummary( $maxlength = 250 ) {
267 $truncatedtext = parent::getTextForSummary( $maxlength );
268
269 # clean up unfinished links
270 # XXX: make this optional? wasn't there in autosummary, but required for
271 # deletion summary.
272 $truncatedtext = preg_replace( '/\[\[([^\]]*)\]?$/', '$1', $truncatedtext );
273
274 return $truncatedtext;
275 }
276
286 public function matchMagicWord( MagicWord $word ) {
287 return $word->match( $this->getText() );
288 }
289
295 public function setPreSaveTransformFlags( array $flags ) {
296 $this->preSaveTransformFlags = $flags;
297 }
298
304 public function getPreSaveTransformFlags() {
305 return $this->preSaveTransformFlags;
306 }
307}
const CONTENT_MODEL_WIKITEXT
Definition Defines.php:211
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
MediaWiki exception.
This class encapsulates "magic words" such as "#redirect", NOTOC, etc.
Definition MagicWord.php:60
match( $text)
Returns true if the text contains the word.
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
Content object implementation for representing flat text.
getText()
Returns the text represented by this Content object, as a string.
Represents a title within MediaWiki.
Definition Title.php:49
getFullText()
Get the prefixed title with spaces, plus any fragment (part beginning with '#')
Definition Title.php:1914
isValidRedirectTarget()
Check if this Title is a valid redirect target.
Definition Title.php:3811
Content object for wiki text pages.
updateRedirect(Title $target)
This implementation replaces the first link on the page with the given new target if this Content obj...
setPreSaveTransformFlags(array $flags)
Records flags set by preSaveTransform.
getRedirectTarget()
Implement redirect extraction for wikitext.
getTextForSummary( $maxlength=250)
getPreSaveTransformFlags()
Records flags set by preSaveTransform.
getRedirectTargetAndText()
Extract the redirect target and the remaining text on the page.
addSectionHeader( $header)
Returns a new WikitextContent object with the given section heading prepended.
isCountable( $hasLinks=null, Title $title=null)
Returns true if this content is not a redirect, and this content's text is countable according to the...
getSection( $sectionId)
matchMagicWord(MagicWord $word)
This implementation calls $word->match() on the this TextContent object's text.
replaceSection( $sectionId, Content $with, $sectionTitle='')
Base interface for content objects.
Definition Content.php:35
getModel()
Returns the ID of the content model used by this Content object.
$header