Merge "Improve docs for Title::getInternalURL/getCanonicalURL"
[lhc/web/wiklou.git] / includes / Revision / MainSlotRoleHandler.php
1 <?php
2 /**
3 * This file is part of MediaWiki.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 */
22
23 namespace MediaWiki\Revision;
24
25 use ContentHandler;
26 use Hooks;
27 use MediaWiki\Linker\LinkTarget;
28 use Title;
29
30 /**
31 * A SlotRoleHandler for the main slot. While most slot roles serve a specific purpose and
32 * thus typically exhibit the same behaviour on all pages, the main slot is used for different
33 * things in different pages, typically depending on the namespace, a "file extension" in
34 * the page name, or the content model of the slot's content.
35 *
36 * MainSlotRoleHandler implements some of the per-namespace and per-model behavior that was
37 * supported prior to MediaWiki Version 1.33.
38 *
39 * @since 1.33
40 */
41 class MainSlotRoleHandler extends SlotRoleHandler {
42
43 /**
44 * @var string[] A mapping of namespaces to content models.
45 * @see $wgNamespaceContentModels
46 */
47 private $namespaceContentModels;
48
49 /**
50 * @param string[] $namespaceContentModels A mapping of namespaces to content models,
51 * typically from $wgNamespaceContentModels.
52 */
53 public function __construct( array $namespaceContentModels ) {
54 parent::__construct( 'main', CONTENT_MODEL_WIKITEXT );
55 $this->namespaceContentModels = $namespaceContentModels;
56 }
57
58 public function supportsArticleCount() {
59 return true;
60 }
61
62 /**
63 * @param string $model
64 * @param LinkTarget $page
65 *
66 * @return bool
67 */
68 public function isAllowedModel( $model, LinkTarget $page ) {
69 $title = Title::newFromLinkTarget( $page );
70 $handler = ContentHandler::getForModelID( $model );
71 return $handler->canBeUsedOn( $title );
72 }
73
74 /**
75 * @param LinkTarget $page
76 *
77 * @return string
78 */
79 public function getDefaultModel( LinkTarget $page ) {
80 // NOTE: this method must not rely on $title->getContentModel() directly or indirectly,
81 // because it is used to initialize the mContentModel member.
82
83 $ext = '';
84 $ns = $page->getNamespace();
85 $model = $this->namespaceContentModels[$ns] ?? null;
86
87 // Hook can determine default model
88 $title = Title::newFromLinkTarget( $page );
89 if ( !Hooks::run( 'ContentHandlerDefaultModelFor', [ $title, &$model ] ) && !is_null( $model ) ) {
90 return $model;
91 }
92
93 // Could this page contain code based on the title?
94 $isCodePage = $ns === NS_MEDIAWIKI && preg_match( '!\.(css|js|json)$!u', $title->getText(), $m );
95 if ( $isCodePage ) {
96 $ext = $m[1];
97 }
98
99 // Is this a user subpage containing code?
100 $isCodeSubpage = $ns === NS_USER
101 && !$isCodePage
102 && preg_match( "/\\/.*\\.(js|css|json)$/", $title->getText(), $m );
103
104 if ( $isCodeSubpage ) {
105 $ext = $m[1];
106 }
107
108 // Is this wikitext, according to $wgNamespaceContentModels or the DefaultModelFor hook?
109 $isWikitext = is_null( $model ) || $model == CONTENT_MODEL_WIKITEXT;
110 $isWikitext = $isWikitext && !$isCodePage && !$isCodeSubpage;
111
112 if ( !$isWikitext ) {
113 switch ( $ext ) {
114 case 'js':
115 return CONTENT_MODEL_JAVASCRIPT;
116 case 'css':
117 return CONTENT_MODEL_CSS;
118 case 'json':
119 return CONTENT_MODEL_JSON;
120 default:
121 return $model ?? CONTENT_MODEL_TEXT;
122 }
123 }
124
125 // We established that it must be wikitext
126
127 return CONTENT_MODEL_WIKITEXT;
128 }
129
130 }