summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Hooks/ArticleProtectComplete.php
blob: bbd9de1841d460fee0df79f3587099d19839f506 (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
<?php

namespace SMW\MediaWiki\Hooks;

use SMW\ApplicationFactory;
use SMW\MediaWiki\EditInfoProvider;
use SMW\Message;
use SMW\PropertyAnnotators\EditProtectedPropertyAnnotator;
use Title;

/**
 * Occurs after the protect article request has been processed
 *
 * @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleProtectComplete
 *
 * @license GNU GPL v2+
 * @since 2.5
 *
 * @author mwjames
 */
class ArticleProtectComplete extends HookHandler {

	/**
	 * Whether the update should be restricted or not. Which means that when
	 * no other change is required then categorize the update as restricted
	 * to avoid unnecessary cascading updates.
	 */
	const RESTRICTED_UPDATE = 'articleprotectcomplete.restricted.update';

	/**
	 * @var Title
	 */
	private $title;

	/**
	 * @var EditInfoProvider
	 */
	private $editInfoProvider;

	/**
	 * @since  2.5
	 *
	 * @param Title $title
	 * @param EditInfoProvider $editInfoProvider
	 */
	public function __construct( Title $title, EditInfoProvider $editInfoProvider ) {
		parent::__construct();
		$this->title = $title;
		$this->editInfoProvider = $editInfoProvider;
	}

	/**
	 * @since 2.5
	 *
	 * @param array $protections
	 * @param string $reason
	 */
	public function process( $protections, $reason ) {

		if ( Message::get( 'smw-edit-protection-auto-update' ) === $reason ) {
			return $this->log( __METHOD__ . ' No changes required, invoked by own process!' );
		}

		$this->editInfoProvider->fetchEditInfo();

		$output = $this->editInfoProvider->getOutput();

		if ( $output === null ) {
			return $this->log( __METHOD__ . ' Missing ParserOutput!' );
		}

		$parserData = ApplicationFactory::getInstance()->newParserData(
			$this->title,
			$output
		);

		$this->doPrepareData( $protections, $parserData );
		$parserData->setOrigin( 'ArticleProtectComplete' );

		$parserData->updateStore(
			true
		);
	}

	private function doPrepareData( $protections, $parserData ) {

		$isRestrictedUpdate = true;
		$isAnnotationBySystem = false;

		$dataItemFactory = ApplicationFactory::getInstance()->getDataItemFactory();
		$property = $dataItemFactory->newDIProperty( '_EDIP' );

		$dataItems = $parserData->getSemanticData()->getPropertyValues( $property );
		$dataItem = end( $dataItems );

		if ( $dataItem ) {
			$isAnnotationBySystem = $dataItem->getOption( EditProtectedPropertyAnnotator::SYSTEM_ANNOTATION );
		}

		$editProtectionRight = $this->getOption( 'smwgEditProtectionRight', false );

		// No _EDIP annotation but a selected protection matches the
		// `EditProtectionRight` setting
		if ( !$dataItem && isset( $protections['edit'] ) && $protections['edit'] === $editProtectionRight ) {
			$this->log( 'ArticleProtectComplete addProperty `Is edit protected`' );

			$isRestrictedUpdate = false;
			$parserData->getSemanticData()->addPropertyObjectValue(
				$property,
				$dataItemFactory->newDIBoolean( true )
			);
		}

		// _EDIP exists and was set by the EditProtectedPropertyAnnotator (which
		// means that is has been set by the system and is not a "human" added
		// annotation) but since the selected protection doesn't match the
		// `EditProtectionRight` setting, remove the annotation
		if ( $dataItem && $isAnnotationBySystem && isset( $protections['edit'] ) && $protections['edit'] !== $editProtectionRight ) {
			$this->log( 'ArticleProtectComplete removeProperty `Is edit protected`' );

			$isRestrictedUpdate = false;
			$parserData->getSemanticData()->removePropertyObjectValue(
				$property,
				$dataItemFactory->newDIBoolean( true )
			);
		}

		$parserData->getSemanticData()->setOption(
			self::RESTRICTED_UPDATE,
			$isRestrictedUpdate
		);
	}

}