14
14
15
15
class Hooks {
16
16
17
- public static function setup () {
18
- if ( !defined ( 'MEDIAWIKI ' ) ) {
19
- die ();
20
- }
21
-
22
- if ( !defined ( 'SMW_VERSION ' ) ) {
23
- die ( "ERROR: Semantic MediaWiki must be installed for Semantic Dependency Updater to run! " );
24
- }
25
- }
26
-
27
- public static function onAfterDataUpdateComplete (
28
- SMWStore $ store , SMWSemanticData $ newData ,
29
- $ compositePropertyTableDiffIterator
30
- ) {
31
- global $ wgSDUProperty ;
32
- global $ wgSDUTraversed ;
33
-
34
- if ( !isset ( $ wgSDUTraversed ) ) {
35
- $ wgSDUTraversed = [];
36
- }
37
-
38
- $ wgSDUProperty = str_replace ( ' ' , '_ ' , $ wgSDUProperty );
39
- $ subject = $ newData ->getSubject ();
40
- $ title = $ subject ->getTitle ();
41
- if ( $ title == null ) {
42
- return true ;
43
- }
44
-
45
- $ id = $ title ->getPrefixedDBKey ();
46
-
47
- wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] --> " . $ title );
48
-
49
- // FIRST CHECK: Does the page data contain a $wgSDUProperty semantic property ?
50
- $ properties = $ newData ->getProperties ();
51
- if ( !isset ( $ properties [$ wgSDUProperty ] ) ) {
52
- wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] <-- No SDU property found " );
53
- return true ;
54
- }
55
-
56
- $ diffTable = $ compositePropertyTableDiffIterator ->getOrderedDiffByTable ();
57
-
58
- // SECOND CHECK: Have there been actual changes in the data? (Ignore internal SMW data!)
59
- // TODO: Introduce an explicit list of Semantic Properties to watch ?
60
- unset( $ diffTable ['smw_fpt_mdat ' ] ); // Ignore SMW's internal properties "smw_fpt_mdat"
61
-
62
- if ( count ( $ diffTable ) > 0 ) {
63
- // wfDebugLog('SemanticDependencyUpdater', "[SDU] diffTable: " . print_r($diffTable, true));
64
- wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] -----> Data changes detected " );
65
- } else {
66
- wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] <-- No semantic data changes detected " );
67
- return true ;
68
- }
69
-
70
- // THIRD CHECK: Has this page been already traversed more than twice?
71
- // This should only be the case when SMW errors occur.
72
- // In that case, the diffTable contains everything and SDU can't know if changes happened
73
- if ( array_key_exists ( $ id , $ wgSDUTraversed ) ) {
74
- $ wgSDUTraversed [$ id ] = $ wgSDUTraversed [$ id ] + 1 ;
75
- } else {
76
- $ wgSDUTraversed [$ id ] = 1 ;
77
- }
78
- if ( $ wgSDUTraversed [$ id ] > 2 ) {
79
- wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] <-- Already traversed " );
80
- return true ;
81
- }
82
-
83
- // QUERY AND UPDATE DEPENDENCIES
84
-
85
- // SMW\SemanticData $newData
86
- // SMWDataItem[] $dataItem
87
- $ dataItem = $ newData ->getPropertyValues ( $ properties [$ wgSDUProperty ] );
88
-
89
- $ wikiPageValues = [];
90
- if ( $ dataItem != null ) {
91
- foreach ( $ dataItem as $ valueItem ) {
92
- if ( $ valueItem instanceof SMWDIBlob ) {
93
- $ wikiPageValues = array_merge ( $ wikiPageValues , self ::updatePagesMatchingQuery ( $ valueItem ->getSerialization () ) );
94
- }
95
- }
96
- }
97
-
98
- self ::rebuildData ( $ wikiPageValues , $ store );
99
- return true ;
100
- }
101
-
102
- /**
103
- * @param string $queryString Query string, excluding [[ and ]] brackets
104
- */
105
- private static function updatePagesMatchingQuery ( $ queryString ) {
106
- global $ sfgListSeparator ;
107
-
108
- $ queryString = str_replace ( 'AND ' , ']] [[ ' , $ queryString );
109
- $ queryString = str_replace ( 'OR ' , ']] OR [[ ' , $ queryString );
110
-
111
- // If SF is installed, get the separator character and change it into ||
112
- // Otherwise SDU won't work with multi-value properties
113
- if ( isset ( $ sfgListSeparator ) ) {
114
- $ queryString = rtrim ( $ queryString , $ sfgListSeparator );
115
- $ queryString = str_replace ( $ sfgListSeparator , ' || ' , $ queryString );
116
- }
117
-
118
- wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] --------> [[ $ queryString]] " );
119
-
120
- $ store = smwfGetStore ();
121
-
122
- $ params = [
123
- 'limit ' => 10000 ,
124
- ];
125
- $ processedParams = SMWQueryProcessor::getProcessedParams ( $ params );
126
- $ query =
127
- SMWQueryProcessor::createQuery ( "[[ $ queryString]] " , $ processedParams , SMWQueryProcessor::SPECIAL_PAGE );
128
- $ result = $ store ->getQueryResult ( $ query ); // SMWQueryResult
129
- $ wikiPageValues = $ result ->getResults (); // array of SMWWikiPageValues
130
-
131
- return $ wikiPageValues ;
132
- }
133
-
134
- /**
135
- * Rebuilds data of the given wikipages to regenerate semantic attrubutes and re-run queries
136
- *
137
- * @param SMWWikiPageValues[] $wikiPageValues
138
- * @param SMWStore $store
139
- */
140
- public static function rebuildData ( $ wikiPageValues , $ store ) {
141
- global $ wgSDUUseJobQueue ;
142
-
143
- $ pageArray = [];
144
- foreach ( $ wikiPageValues as $ wikiPageValue ) {
145
- $ page = WikiPage::newFromID ( $ wikiPageValue ->getTitle ()->getArticleId () );
146
- if ( $ page ) {
147
- $ pageArray [] = $ page ->getTitle ()->prefixedText ;
148
- }
149
- }
150
- $ pageString = implode ( $ pageArray , "| " );
151
-
152
- // TODO: A threshold when to switch to Queue Jobs might be smarter
153
-
154
- if ( $ pageString !== "" ) {
155
- if ( $ wgSDUUseJobQueue ) {
156
- $ jobs = [];
157
- $ jobs [] = new RebuildDataJob ( [
158
- 'pageString ' => $ pageString ,
159
- ] );
160
- foreach ( $ wikiPageValues as $ page ) {
161
- $ jobs [] = new PageUpdaterJob ( [
162
- 'page ' => $ page
163
- ] );
164
- }
165
- if ( $ jobs ) {
166
- JobQueueGroup::singleton ()->lazyPush ( $ jobs );
167
- }
168
- } else {
169
- DeferredUpdates::addCallableUpdate ( static function () use ( $ store , $ pageString ) {
170
- wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] --------> [rebuildData] $ pageString " );
171
- $ maintenanceFactory = ApplicationFactory::getInstance ()->newMaintenanceFactory ();
172
-
173
- $ dataRebuilder = $ maintenanceFactory ->newDataRebuilder ( $ store );
174
- $ dataRebuilder ->setOptions (
175
- new Options ( [ 'page ' => $ pageString ] )
176
- );
177
- $ dataRebuilder ->rebuild ();
178
- } );
179
- }
180
- }
181
- }
182
-
183
- }
17
+ public static function setup () {
18
+ if ( !defined ( 'MEDIAWIKI ' ) ) {
19
+ die ();
20
+ }
21
+
22
+ if ( !defined ( 'SMW_VERSION ' ) ) {
23
+ die ( "ERROR: Semantic MediaWiki must be installed for Semantic Dependency Updater to run! " );
24
+ }
25
+ }
26
+
27
+ public static function onAfterDataUpdateComplete (
28
+ SMWStore $ store , SMWSemanticData $ newData ,
29
+ $ compositePropertyTableDiffIterator
30
+ ) {
31
+ global $ wgSDUProperty ;
32
+ global $ wgSDUTraversed ;
33
+
34
+ if ( !isset ( $ wgSDUTraversed ) ) {
35
+ $ wgSDUTraversed = [];
36
+ }
37
+
38
+ $ wgSDUProperty = str_replace ( ' ' , '_ ' , $ wgSDUProperty );
39
+ $ subject = $ newData ->getSubject ();
40
+ $ title = $ subject ->getTitle ();
41
+ if ( $ title == null ) {
42
+ return true ;
43
+ }
44
+
45
+ $ id = $ title ->getPrefixedDBKey ();
46
+
47
+ wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] --> " . $ title );
48
+
49
+ // FIRST CHECK: Does the page data contain a $wgSDUProperty semantic property ?
50
+ $ properties = $ newData ->getProperties ();
51
+ if ( !isset ( $ properties [$ wgSDUProperty ] ) ) {
52
+ wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] <-- No SDU property found " );
53
+ return true ;
54
+ }
55
+
56
+ $ diffTable = $ compositePropertyTableDiffIterator ->getOrderedDiffByTable ();
57
+
58
+ // SECOND CHECK: Have there been actual changes in the data? (Ignore internal SMW data!)
59
+ // TODO: Introduce an explicit list of Semantic Properties to watch ?
60
+ unset( $ diffTable ['smw_fpt_mdat ' ] ); // Ignore SMW's internal properties "smw_fpt_mdat"
61
+
62
+ if ( count ( $ diffTable ) > 0 ) {
63
+ // wfDebugLog('SemanticDependencyUpdater', "[SDU] diffTable: " . print_r($diffTable, true));
64
+ wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] -----> Data changes detected " );
65
+ } else {
66
+ wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] <-- No semantic data changes detected " );
67
+ return true ;
68
+ }
69
+
70
+ // THIRD CHECK: Has this page been already traversed more than twice?
71
+ // This should only be the case when SMW errors occur.
72
+ // In that case, the diffTable contains everything and SDU can't know if changes happened
73
+ if ( array_key_exists ( $ id , $ wgSDUTraversed ) ) {
74
+ $ wgSDUTraversed [$ id ] = $ wgSDUTraversed [$ id ] + 1 ;
75
+ } else {
76
+ $ wgSDUTraversed [$ id ] = 1 ;
77
+ }
78
+ if ( $ wgSDUTraversed [$ id ] > 2 ) {
79
+ wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] <-- Already traversed " );
80
+ return true ;
81
+ }
82
+
83
+ // QUERY AND UPDATE DEPENDENCIES
84
+
85
+ // SMW\SemanticData $newData
86
+ // SMWDataItem[] $dataItem
87
+ $ dataItem = $ newData ->getPropertyValues ( $ properties [$ wgSDUProperty ] );
88
+
89
+ $ wikiPageValues = [];
90
+ if ( $ dataItem != null ) {
91
+ foreach ( $ dataItem as $ valueItem ) {
92
+ if ( $ valueItem instanceof SMWDIBlob ) {
93
+ $ wikiPageValues = array_merge ( $ wikiPageValues , self ::updatePagesMatchingQuery ( $ valueItem ->getSerialization () ) );
94
+ }
95
+ }
96
+ }
97
+
98
+ self ::rebuildData ( $ wikiPageValues , $ store );
99
+ return true ;
100
+ }
101
+
102
+ /**
103
+ * @param string $queryString Query string, excluding [[ and ]] brackets
104
+ */
105
+ private static function updatePagesMatchingQuery ( $ queryString ) {
106
+ global $ sfgListSeparator ;
107
+
108
+ $ queryString = str_replace ( 'AND ' , ']] [[ ' , $ queryString );
109
+ $ queryString = str_replace ( 'OR ' , ']] OR [[ ' , $ queryString );
110
+
111
+ // If SF is installed, get the separator character and change it into ||
112
+ // Otherwise SDU won't work with multi-value properties
113
+ if ( isset ( $ sfgListSeparator ) ) {
114
+ $ queryString = rtrim ( $ queryString , $ sfgListSeparator );
115
+ $ queryString = str_replace ( $ sfgListSeparator , ' || ' , $ queryString );
116
+ }
117
+
118
+ wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] --------> [[ $ queryString]] " );
119
+
120
+ $ store = smwfGetStore ();
121
+
122
+ $ params = [
123
+ 'limit ' => 10000 ,
124
+ ];
125
+ $ processedParams = SMWQueryProcessor::getProcessedParams ( $ params );
126
+ $ query =
127
+ SMWQueryProcessor::createQuery ( "[[ $ queryString]] " , $ processedParams , SMWQueryProcessor::SPECIAL_PAGE );
128
+ $ result = $ store ->getQueryResult ( $ query ); // SMWQueryResult
129
+ $ wikiPageValues = $ result ->getResults (); // array of SMWWikiPageValues
130
+
131
+ return $ wikiPageValues ;
132
+ }
133
+
134
+ /**
135
+ * Rebuilds data of the given wikipages to regenerate semantic attrubutes and re-run queries
136
+ *
137
+ * @param SMWWikiPageValues[] $wikiPageValues
138
+ * @param SMWStore $store
139
+ */
140
+ public static function rebuildData ( $ wikiPageValues , $ store ) {
141
+ global $ wgSDUUseJobQueue ;
142
+
143
+ $ pageArray = [];
144
+ foreach ( $ wikiPageValues as $ wikiPageValue ) {
145
+ $ page = WikiPage::newFromID ( $ wikiPageValue ->getTitle ()->getArticleId () );
146
+ if ( $ page ) {
147
+ $ pageArray [] = $ page ->getTitle ()->prefixedText ;
148
+ }
149
+ }
150
+ $ pageString = implode ( $ pageArray , "| " );
151
+
152
+ // TODO: A threshold when to switch to Queue Jobs might be smarter
153
+
154
+ if ( $ pageString !== "" ) {
155
+ if ( $ wgSDUUseJobQueue ) {
156
+ $ jobs = [];
157
+ $ jobs [] = new RebuildDataJob ( [
158
+ 'pageString ' => $ pageString ,
159
+ ] );
160
+ foreach ( $ wikiPageValues as $ page ) {
161
+ $ jobs [] = new PageUpdaterJob ( [
162
+ 'page ' => $ page
163
+ ] );
164
+ }
165
+ if ( $ jobs ) {
166
+ JobQueueGroup::singleton ()->lazyPush ( $ jobs );
167
+ }
168
+ } else {
169
+ DeferredUpdates::addCallableUpdate ( static function () use ( $ store , $ pageString ) {
170
+ wfDebugLog ( 'SemanticDependencyUpdater ' , "[SDU] --------> [rebuildData] $ pageString " );
171
+ $ maintenanceFactory = ApplicationFactory::getInstance ()->newMaintenanceFactory ();
172
+
173
+ $ dataRebuilder = $ maintenanceFactory ->newDataRebuilder ( $ store );
174
+ $ dataRebuilder ->setOptions (
175
+ new Options ( [ 'page ' => $ pageString ] )
176
+ );
177
+ $ dataRebuilder ->rebuild ();
178
+ } );
179
+ }
180
+ }
181
+ }
182
+
183
+ }
0 commit comments