Completed
Push — master ( 3294f9...cc37b1 )
by mw
19s
created

ParserData::updateStore()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 13
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 26
ccs 13
cts 13
cp 1
crap 1
rs 8.8571
1
<?php
2
3
namespace SMW;
4
5
use ParserOutput;
6
use SMWDataValue as DataValue;
7
use Title;
8
9
/**
10
 * Handling semantic data exchange with a ParserOutput object
11
 *
12
 * Provides access to a semantic data container that is generated
13
 * either from the ParserOutput or is a newly created container
14
 *
15
 * @license GNU GPL v2+
16
 * @since 1.9
17
 *
18
 * @author mwjames
19
 * @author Markus Krötzsch
20
 */
21
class ParserData {
22
23
	/**
24
	 * @var Title
25
	 */
26
	private $title;
27
28
	/**
29
	 * @var ParserOutput
30
	 */
31
	private $parserOutput;
32
33
	/**
34
	 * @var SemanticData
35
	 */
36
	private $semanticData;
37
38
	/**
39
	 * @var array
40
	 */
41
	private $errors = array();
42
43
	/**
44
	 * @var $updateJobs
45
	 */
46
	private $updateJobs = true;
47
48
	/**
49
	 * @since 1.9
50
	 *
51
	 * @param Title $title
52
	 * @param ParserOutput $parserOutput
53
	 */
54 212
	public function __construct( Title $title, ParserOutput $parserOutput ) {
55 212
		$this->title = $title;
56 212
		$this->parserOutput = $parserOutput;
57
58 212
		$this->initSemanticData();
59 212
	}
60
61
	/**
62
	 * @since 1.9
63
	 *
64
	 * @return Title
65
	 */
66 184
	public function getTitle() {
67 184
		return $this->title;
68
	}
69
70
	/**
71
	 * @since 1.9
72
	 *
73
	 * @return DIWikiPage
74
	 */
75 193
	public function getSubject() {
76 193
		return $this->getSemanticData()->getSubject();
77
	}
78
79
	/**
80
	 * @since 1.9
81
	 *
82
	 * @return ParserOutput
83
	 */
84 186
	public function getOutput() {
85 186
		return $this->parserOutput;
86
	}
87
88
	/**
89
	 * Explicitly disable update jobs (e.g when running store update
90
	 * in the job queue)
91
	 *
92
	 * @since 1.9
93
	 */
94 21
	public function disableBackgroundUpdateJobs() {
95 21
		$this->updateJobs = false;
96 21
		return $this;
97
	}
98
99
	/**
100
	 * @since 2.4
101
	 *
102
	 * @return boolean
103
	 */
104 164
	public function canModifySemanticData() {
105
106
		// getExtensionData returns null if no value was set for this key
107
		if (
108 164
			$this->hasExtensionData() &&
109 164
			$this->parserOutput->getExtensionData( 'smw-blockannotation' ) !== null &&
110 164
			$this->parserOutput->getExtensionData( 'smw-blockannotation' ) ) {
111 3
			return false;
112
		}
113
114 164
		return true;
115
	}
116
117
	/**
118
	 * @since 2.1
119
	 *
120
	 * @return boolean
121
	 */
122 1
	public function getUpdateJobState() {
123 1
		return $this->updateJobs;
124
	}
125
126
	/**
127
	 * @deprecated since 2.1, use getUpdateJobState
128
	 */
129
	public function getUpdateStatus() {
130
		return $this->updateJobs;
131
	}
132
133
	/**
134
	 * Returns collected errors occurred during processing
135
	 *
136
	 * @since 1.9
137
	 *
138
	 * @return array
139
	 */
140 53
	public function getErrors() {
141 53
		return $this->errors;
142
	}
143
144
	/**
145
	 * @since  1.9
146
	 */
147 1
	public function addError( $error ) {
148 1
		$this->errors = array_merge( $this->errors, (array)$error );
149 1
	}
150
151
	/**
152
	 * @since 1.9
153
	 *
154
	 * @param SemanticData $semanticData
155
	 */
156 212
	public function setSemanticData( SemanticData $semanticData ) {
157 212
		$this->semanticData = $semanticData;
158 212
	}
159
160
	/**
161
	 * @deprecated since 2.0, use setSemanticData
162
	 */
163
	public function setData( SemanticData $semanticData ) {
164
		$this->setSemanticData( $semanticData );
165
	}
166
167
	/**
168
	 * @since 1.9
169
	 *
170
	 * @return SemanticData
171
	 */
172 199
	public function getSemanticData() {
173 199
		return $this->semanticData;
174
	}
175
176
	/**
177
	 * @deprecated since 2.0, use getSemanticData
178
	 */
179
	public function getData() {
180
		return $this->getSemanticData();
181
	}
182
183
	/**
184
	 * @since 2.1
185
	 */
186 212
	public function setEmptySemanticData() {
187 212
		$this->setSemanticData( new SemanticData( DIWikiPage::newFromTitle( $this->title ) ) );
188 212
	}
189
190
	/**
191
	 * @deprecated since 2.1, use setEmptySemanticData
192
	 */
193
	public function clearData() {
194
		$this->setEmptySemanticData();
195
	}
196
197
	/**
198
	 * @deprecated since 2.1, use pushSemanticDataToParserOutput
199
	 */
200
	public function updateOutput() {
201
		$this->pushSemanticDataToParserOutput();
202
	}
203
204
	/**
205
	 * @since 2.1
206
	 *
207
	 * @param ParserOutput|null
208
	 */
209 5
	public function importFromParserOutput( ParserOutput $parserOutput = null ) {
210
211 5
		if ( $parserOutput === null ) {
212 1
			return;
213
		}
214
215 5
		$semanticData = $this->fetchDataFromParserOutput( $parserOutput );
216
217
		// Only import data that is known to be different
218 5
		if ( $semanticData !== null &&
219 5
			$this->getSubject()->equals( $semanticData->getSubject() ) &&
220 5
			$semanticData->getHash() !== $this->getSemanticData()->getHash() ) {
221
222 4
			$this->getSemanticData()->importDataFrom( $semanticData );
223
		}
224 5
	}
225
226
	/**
227
	 * @since 2.1
228
	 */
229 191
	public function pushSemanticDataToParserOutput() {
230
231 191
		$this->setSemanticDataStateToParserOutputProperty();
232
233 191
		if ( $this->hasExtensionData() ) {
234 190
			return $this->parserOutput->setExtensionData( 'smwdata', $this->semanticData );
235
		}
236
237 1
		$this->parserOutput->mSMWData = $this->semanticData;
238 1
	}
239
240
	/**
241
	 * @since 2.1
242
	 */
243 192
	public function setSemanticDataStateToParserOutputProperty() {
244
245 192
		$this->parserOutput->setTimestamp( wfTimestampNow() );
246
247 192
		$this->parserOutput->setProperty(
248 192
			'smw-semanticdata-status',
249 192
			$this->semanticData->getProperties() !== array()
250
		);
251
252
		// Ensure any errors are reported and recorded
253 192
		$processingErrorMsgHandler = new ProcessingErrorMsgHandler(
254 192
			$this->getSubject()
255
		);
256
257 192
		foreach ( $this->errors as $error ) {
258 1
			$processingErrorMsgHandler->pushTo(
259 1
				$this->semanticData,
260 1
				$processingErrorMsgHandler->getErrorContainerFromMsg( $error )
261
			);
262
		}
263 192
	}
264
265
	/**
266
	 * @see SemanticData::addDataValue
267
	 *
268
	 * @since 1.9
269
	 *
270
	 * @param SMWDataValue $dataValue
271
	 */
272 166
	public function addDataValue( DataValue $dataValue ) {
273 166
		$this->semanticData->addDataValue( $dataValue );
274 166
	}
275
276
	/**
277
	 * @private This method is not for public use
278
	 *
279
	 * @since 1.9
280
	 *
281
	 * @return boolean
282
	 */
283 182
	public function updateStore( $enabledDeferredUpdate = false ) {
284
285 182
		$applicationFactory = ApplicationFactory::getInstance();
286
287 182
		$storeUpdater = $applicationFactory->newStoreUpdater( $this->semanticData );
288
289 182
		$storeUpdater->setUpdateJobsEnabledState(
290 182
			$this->updateJobs
291
		);
292
293 182
		DeferredCallableUpdate::releasePendingUpdates();
294
295 182
		$deferredCallableUpdate = $applicationFactory->newDeferredCallableUpdate( function() use( $storeUpdater ) {
296 182
			$storeUpdater->doUpdate();
297 182
		} );
298
299 182
		$deferredCallableUpdate->setOrigin( __METHOD__ );
300
301 182
		$deferredCallableUpdate->enabledDeferredUpdate(
302
			$enabledDeferredUpdate
303
		);
304
305 182
		$deferredCallableUpdate->pushUpdate();
306
307 182
		return true;
308
	}
309
310
	/**
311
	 * @note ParserOutput::setLimitReportData
312
	 *
313
	 * @since 2.4
314
	 *
315
	 * @param string $key
316
	 * @param string $value
317
	 */
318 180
	public function addLimitReport( $key, $value ) {
319
320
		// FIXME 1.22+
321 180
		if ( !method_exists( $this->parserOutput, 'setLimitReportData' ) ) {
322
			return null;
323
		}
324
325 180
		$this->parserOutput->setLimitReportData( 'smw-limitreport-' . $key, $value );
326 180
	}
327
328
	/**
329
	 * FIXME Remove when MW 1.21 becomes mandatory
330
	 */
331 211
	protected function hasExtensionData() {
332 211
		return method_exists( $this->parserOutput, 'getExtensionData' );
333
	}
334
335
	/**
336
	 * Setup the semantic data container either from the ParserOutput or
337
	 * if not available create an empty container
338
	 */
339 212
	private function initSemanticData() {
340
341 212
		$this->semanticData = $this->fetchDataFromParserOutput( $this->parserOutput );
342
343 212
		if ( !( $this->semanticData instanceof SemanticData ) ) {
344 212
			$this->setEmptySemanticData();
345
		}
346 212
	}
347
348 212
	private function fetchDataFromParserOutput( ParserOutput $parserOutput ) {
349
350 212
		if ( $this->hasExtensionData() ) {
351 211
			$semanticData = $parserOutput->getExtensionData( 'smwdata' );
352
		} else {
353 1
			$semanticData = isset( $parserOutput->mSMWData ) ? $parserOutput->mSMWData : null;
354
		}
355
356 212
		return $semanticData;
357
	}
358
359
}
360