summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/ChangePropListener.php
blob: b41a0ddc2ce16599131c348a70d7924e177bd81e (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
<?php

namespace SMW;

use Closure;
use SMW\Exception\PropertyLabelNotResolvedException;

/**
 * @license GNU GPL v2+
 * @since 3.0
 *
 * @author mwjames
 */
class ChangePropListener {

	/**
	 * @var []
	 */
	private static $listenerCallbacks = [];

	/**
	 * @var []
	 */
	private static $deferrableCallbacks = [];

	/**
	 * @since 3.0
	 */
	public static function clearListeners() {
		self::$listenerCallbacks = [];
		self::$deferrableCallbacks = [];
	}

	/**
	 * @since 3.0
	 *
	 * @param string $key
	 * @param Closure $callback
	 */
	public function addListenerCallback( $key, Closure $callback ) {

		if ( $key === '' ) {
			return;
		}

		if ( !isset( self::$listenerCallbacks[$key] ) ) {
			self::$listenerCallbacks[$key] = [];
		}

		self::$listenerCallbacks[$key][] = $callback;
	}

	/**
	 * Finalize event inception points by matching the key to a property
	 * equivalent representation.
	 *
	 * @since 3.0
	 *
	 * @param Store $store
	 */
	public function loadListeners( Store $store ) {

		foreach ( self::$listenerCallbacks as $key => $value ) {

			try {
				$property = DIProperty::newFromUserLabel( $key );
			} catch ( PropertyLabelNotResolvedException $e ) {
				continue;
			}

			$pid = $store->getObjectIds()->getSMWPropertyID(
				$property
			);

			self::$listenerCallbacks[$pid] = $value;
			unset( self::$listenerCallbacks[$key] );
		}
	}

	/**
	 * @since 3.0
	 *
	 * @param integer $pid
	 * @param array $record
	 */
	public static function record( $pid, array $record ) {

		if ( !isset( self::$listenerCallbacks[$pid] ) ) {
			return;
		}

		if ( !isset( self::$deferrableCallbacks[$pid] ) ) {
			self::$deferrableCallbacks[$pid] = [];
		}

		// Copy callbacks to the deferred list to isolate the execution
		// from the event point
		foreach ( self::$listenerCallbacks[$pid] as $callback ) {
			self::$deferrableCallbacks[$pid][] = [ $callback, $record ];
		}
	}

	/**
	 * @since 3.0
	 */
	public function callListeners() {

		if ( self::$deferrableCallbacks === [] ) {
			return;
		}

		$deferrableCallbacks = self::$deferrableCallbacks;

		$callback = function() use( $deferrableCallbacks ) {
			foreach ( $deferrableCallbacks as $pid => $records ) {
				foreach ( $records as $rec ) {
					call_user_func_array( $rec[0], [ $rec[1] ] );
				}
			}
		};

		$deferredTransactionalUpdate = ApplicationFactory::getInstance()->newDeferredTransactionalCallableUpdate(
			$callback
		);

		$deferredTransactionalUpdate->setOrigin(
			[
				'ChangePropListener::callListeners'
			]
		);

		$deferredTransactionalUpdate->commitWithTransactionTicket();
		$deferredTransactionalUpdate->pushUpdate();

		self::$deferrableCallbacks = [];
	}

}