summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Hooks/InternalParseBeforeLinks.php
blob: 9994016aafc87f496f7b376643d3a2369753a112 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<?php

namespace SMW\MediaWiki\Hooks;

use Parser;
use SMW\ApplicationFactory;
use SMW\Parser\InTextAnnotationParser;
use StripState;

/**
 * Hook: InternalParseBeforeLinks is used to process the expanded wiki
 * code after <nowiki>, HTML-comments, and templates have been treated.
 *
 * This method will be called before an article is displayed or previewed.
 * For display and preview we strip out the semantic properties and append them
 * at the end of the article.
 *
 * @note MW 1.20+ see InternalParseBeforeSanitize
 *
 * @see http://www.mediawiki.org/wiki/Manual:Hooks/InternalParseBeforeLinks
 *
 * @ingroup FunctionHook
 *
 * @license GNU GPL v2+
 * @since 1.9
 *
 * @author mwjames
 */
class InternalParseBeforeLinks extends HookHandler {

	/**
	 * @var Parser
	 */
	private $parser;

	/**
	 * @var StripState
	 */
	private $stripState;

	/**
	 * @since 1.9
	 *
	 * @param Parser $parser
	 * @param StripState $stripState
	 */
	public function __construct( Parser &$parser, $stripState ) {
		$this->parser = $parser;
		$this->stripState = $stripState;
	}

	/**
	 * @since 1.9
	 *
	 * @param string $text
	 *
	 * @return true
	 */
	public function process( &$text ) {

		if ( !$this->canPerformUpdate( $text, $this->parser->getTitle() ) ) {
			return true;
		}

		return $this->performUpdate( $text );
	}

	private function canPerformUpdate( $text, $title ) {

		if ( $this->getRedirectTarget() !== null ) {
			return true;
		}

		// #2209, #2370 Allow content to be parsed that contain [[SMW::off]]/[[SMW::on]]
		// even in case of MediaWiki messages
		if ( InTextAnnotationParser::hasMarker( $text ) ) {
			return true;
		}

		// ParserOptions::getInterfaceMessage is being used to identify whether a
		// parse was initiated by `Message::parse`
		if ( $text === '' || $this->parser->getOptions()->getInterfaceMessage() ) {
			return false;
		}

		if ( !$title->isSpecialPage() ) {
			return true;
		}

		// #2529
		foreach ( $this->getOption( 'smwgEnabledSpecialPage', [] ) as $specialPage ) {
			if ( is_string( $specialPage ) && $title->isSpecial( $specialPage ) ) {
				return true;
			}
		}

		return false;
	}

	private function performUpdate( &$text ) {

		$applicationFactory = ApplicationFactory::getInstance();

		/**
		 * @var ParserData $parserData
		 */
		$parserData = $applicationFactory->newParserData(
			$this->parser->getTitle(),
			$this->parser->getOutput()
		);

		/**
		 * Performs [[link::syntax]] parsing and adding of property annotations
		 * to the ParserOutput
		 *
		 * @var InTextAnnotationParser
		 */
		$inTextAnnotationParser = $applicationFactory->newInTextAnnotationParser(
			$parserData
		);

		$stripMarkerDecoder = $applicationFactory->newMwCollaboratorFactory()->newStripMarkerDecoder(
			$this->stripState
		);

		$inTextAnnotationParser->setStripMarkerDecoder(
			$stripMarkerDecoder
		);

		$inTextAnnotationParser->setRedirectTarget(
			$this->getRedirectTarget()
		);

		$inTextAnnotationParser->parse( $text );

		$parserData->markParserOutput();

		return true;
	}

	/**
	 * #656 / MW 1.24+
	 */
	private function getRedirectTarget() {

		if ( method_exists( $this->parser->getOptions(), 'getRedirectTarget' ) ) {
			return $this->parser->getOptions()->getRedirectTarget();
		}

		return null;
	}

}