]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/TemplatesOnThisPageFormatter.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / TemplatesOnThisPageFormatter.php
1 <?php
2 /**
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  * http://www.gnu.org/copyleft/gpl.html
17  *
18  * @file
19  */
20
21 use MediaWiki\Linker\LinkRenderer;
22 use MediaWiki\Linker\LinkTarget;
23
24 /**
25  * Handles formatting for the "templates used on this page"
26  * lists. Formerly known as Linker::formatTemplates()
27  *
28  * @since 1.28
29  */
30 class TemplatesOnThisPageFormatter {
31
32         /**
33          * @var IContextSource
34          */
35         private $context;
36
37         /**
38          * @var LinkRenderer
39          */
40         private $linkRenderer;
41
42         /**
43          * @param IContextSource $context
44          * @param LinkRenderer $linkRenderer
45          */
46         public function __construct( IContextSource $context, LinkRenderer $linkRenderer ) {
47                 $this->context = $context;
48                 $this->linkRenderer = $linkRenderer;
49         }
50
51         /**
52          * Make an HTML list of templates, and then add a "More..." link at
53          * the bottom. If $more is null, do not add a "More..." link. If $more
54          * is a LinkTarget, make a link to that title and use it. If $more is a string,
55          * directly paste it in as the link (escaping needs to be done manually).
56          *
57          * @param LinkTarget[] $templates
58          * @param string|bool $type 'preview' if a preview, 'section' if a section edit, false if neither
59          * @param LinkTarget|string|null $more An escaped link for "More..." of the templates
60          * @return string HTML output
61          */
62         public function format( array $templates, $type = false, $more = null ) {
63                 if ( !$templates ) {
64                         // No templates
65                         return '';
66                 }
67
68                 # Do a batch existence check
69                 $batch = new LinkBatch;
70                 foreach ( $templates as $title ) {
71                         $batch->addObj( $title );
72                 }
73                 $batch->execute();
74
75                 # Construct the HTML
76                 $outText = '<div class="mw-templatesUsedExplanation">';
77                 $count = count( $templates );
78                 if ( $type === 'preview' ) {
79                         $outText .= $this->context->msg( 'templatesusedpreview' )->numParams( $count )
80                                 ->parseAsBlock();
81                 } elseif ( $type === 'section' ) {
82                         $outText .= $this->context->msg( 'templatesusedsection' )->numParams( $count )
83                                 ->parseAsBlock();
84                 } else {
85                         $outText .= $this->context->msg( 'templatesused' )->numParams( $count )
86                                 ->parseAsBlock();
87                 }
88                 $outText .= "</div><ul>\n";
89
90                 usort( $templates, 'Title::compare' );
91                 foreach ( $templates as $template ) {
92                         $outText .= $this->formatTemplate( $template );
93                 }
94
95                 if ( $more instanceof LinkTarget ) {
96                         $outText .= Html::rawElement( 'li', [], $this->linkRenderer->makeLink(
97                                 $more, $this->context->msg( 'moredotdotdot' )->text() ) );
98                 } elseif ( $more ) {
99                         // Documented as should already be escaped
100                         $outText .= Html::rawElement( 'li', [], $more );
101                 }
102
103                 $outText .= '</ul>';
104                 return $outText;
105         }
106
107         /**
108          * Builds an <li> item for an individual template
109          *
110          * @param LinkTarget $target
111          * @return string
112          */
113         private function formatTemplate( LinkTarget $target ) {
114                 // TODO Would be nice if we didn't have to use Title here
115                 $titleObj = Title::newFromLinkTarget( $target );
116                 $protected = $this->getRestrictionsText( $titleObj->getRestrictions( 'edit' ) );
117                 $editLink = $this->buildEditLink( $titleObj );
118                 return '<li>' . $this->linkRenderer->makeLink( $target )
119                         . $this->context->msg( 'word-separator' )->escaped()
120                         . $this->context->msg( 'parentheses' )->rawParams( $editLink )->escaped()
121                         . $this->context->msg( 'word-separator' )->escaped()
122                         . $protected . '</li>';
123         }
124
125         /**
126          * If the page is protected, get the relevant text
127          * for those restrictions
128          *
129          * @param array $restrictions
130          * @return string
131          */
132         private function getRestrictionsText( array $restrictions ) {
133                 $protected = '';
134                 if ( !$restrictions ) {
135                         return $protected;
136                 }
137
138                 // Check backwards-compatible messages
139                 $msg = null;
140                 if ( $restrictions === [ 'sysop' ] ) {
141                         $msg = $this->context->msg( 'template-protected' );
142                 } elseif ( $restrictions === [ 'autoconfirmed' ] ) {
143                         $msg = $this->context->msg( 'template-semiprotected' );
144                 }
145                 if ( $msg && !$msg->isDisabled() ) {
146                         $protected = $msg->parse();
147                 } else {
148                         // Construct the message from restriction-level-*
149                         // e.g. restriction-level-sysop, restriction-level-autoconfirmed
150                         $msgs = [];
151                         foreach ( $restrictions as $r ) {
152                                 $msgs[] = $this->context->msg( "restriction-level-$r" )->parse();
153                         }
154                         $protected = $this->context->msg( 'parentheses' )
155                                 ->rawParams( $this->context->getLanguage()->commaList( $msgs ) )->escaped();
156                 }
157
158                 return $protected;
159         }
160
161         /**
162          * Return a link to the edit page, with the text
163          * saying "view source" if the user can't edit the page
164          *
165          * @param Title $titleObj
166          * @return string
167          */
168         private function buildEditLink( Title $titleObj ) {
169                 if ( $titleObj->quickUserCan( 'edit', $this->context->getUser() ) ) {
170                         $linkMsg = 'editlink';
171                 } else {
172                         $linkMsg = 'viewsourcelink';
173                 }
174
175                 return $this->linkRenderer->makeLink(
176                         $titleObj,
177                         $this->context->msg( $linkMsg )->text(),
178                         [],
179                         [ 'action' => 'edit' ]
180                 );
181         }
182
183 }