Skip to content

Commit bb3103e

Browse files
committed
refactor to use new registration standard
1 parent d52c91e commit bb3103e

File tree

3 files changed

+240
-215
lines changed

3 files changed

+240
-215
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,215 +1,164 @@
1-
<?php
2-
3-
/*
4-
* SemanticDependencyUpdater is a MediaWiki extension that monitors changes in the semantic data of a wiki page.
5-
* The affected page can the Semantic Dependency Updater property to define which pages should also be updated.
6-
* This can be defined through a list of pages or for more advanced use cases, a query string.
7-
*
8-
* This extension requires Semantic MediaWiki >= 2.3 (http://www.semantic-mediawiki.org)
9-
*
10-
* This extension is slightly based on Remco C. de Boers https://www.mediawiki.org/wiki/Extension:SemanticDummyEditor
11-
*
12-
* @author Simon Heimler, gesinn.it GmbH & Co
13-
*/
14-
15-
if ( !defined( 'MEDIAWIKI' ) ) {
16-
die();
17-
}
18-
19-
if ( !defined( 'SMW_VERSION' ) ) {
20-
die( "ERROR: Semantic MediaWiki must be installed for Semantic Dummy Editor to run!" );
21-
}
22-
23-
define( 'SDU_VERSION', '1.3.2' );
24-
25-
$wgExtensionCredits[defined( 'SEMANTIC_EXTENSION_TYPE' ) ? 'semantic' : 'other'][] = [
26-
'name' => 'SemanticDependencyUpdater',
27-
'author' => [
28-
'[https://www.mediawiki.org/wiki/User:Fannon Simon Heimler]',
29-
'[https://www.mediawiki.org/wiki/User:Planetenxin Alexander Gesinn]',
30-
'[https://www.mediawiki.org/wiki/User:Rcdeboer Remco C. de Boer]',
31-
],
32-
'url' => 'http://www.mediawiki.org/wiki/Extension:SemanticDependencyUpdater',
33-
'description' => 'Monitors semantic data changes and updates dependend pages',
34-
'version' => SDU_VERSION,
35-
];
36-
37-
global $wgExtensionFunctions;
38-
$wgExtensionFunctions[] = 'SemanticDependencyUpdater::setup';
39-
$wgJobClasses['DummyEditJob'] = 'DummyEditJob';
40-
41-
$wgSDUProperty = 'Semantic Dependency';
42-
$wgSDUUseJobQueue = false;
43-
44-
class SemanticDependencyUpdater {
45-
46-
public static function setup() {
47-
global $wgHooks;
48-
$wgHooks['SMW::SQLStore::AfterDataUpdateComplete'][] = 'SemanticDependencyUpdater::onAfterDataUpdateComplete';
49-
}
50-
51-
public static function onAfterDataUpdateComplete( SMWStore $store, SMWSemanticData $newData,
52-
$compositePropertyTableDiffIterator ) {
53-
54-
global $wgSDUProperty;
55-
global $wgSDUTraversed;
56-
57-
if ( !isset( $wgSDUTraversed ) ) {
58-
$wgSDUTraversed = [];
59-
}
60-
61-
$wgSDUProperty = str_replace( ' ', '_', $wgSDUProperty );
62-
$subject = $newData->getSubject();
63-
$title = $subject->getTitle();
64-
$id = $title->getPrefixedDBKey();
65-
66-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --> " . $title );
67-
68-
69-
// FIRST CHECK: Does the page data contain a $wgSUTPropertyName semantic property ?
70-
$properties = $newData->getProperties();
71-
$diffTable = $compositePropertyTableDiffIterator->getOrderedDiffByTable();
72-
73-
if ( !isset( $properties[$wgSDUProperty] ) ) {
74-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] <-- No SDU property found" );
75-
return true;
76-
}
77-
78-
79-
// SECOND CHECK: Have there been actual changes in the data? (Ignore internal SMW data!)
80-
// TODO: Introduce an explicit list of Semantic Properties to watch ?
81-
unset( $diffTable['smw_fpt_mdat'] ); // Ignore SMW's internal properties "smw_fpt_mdat"
82-
83-
if ( count( $diffTable ) > 0 ) {
84-
// wfDebugLog('SemanticDependencyUpdater', "[SDU] diffTable: " . print_r($diffTable, true));
85-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] -----> Data changes detected" );
86-
} else {
87-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] <-- No semantic data changes detected" );
88-
return true;
89-
}
90-
91-
92-
// THIRD CHECK: Has this page been already traversed more than twice?
93-
// This should only be the case when SMW errors occur.
94-
// In that case, the diffTable contains everything and SDU can't know if changes happend
95-
if ( array_key_exists( $id, $wgSDUTraversed ) ) {
96-
$wgSDUTraversed[$id] = $wgSDUTraversed[$id] + 1;
97-
} else {
98-
$wgSDUTraversed[$id] = 1;
99-
}
100-
if ( $wgSDUTraversed[$id] > 2 ) {
101-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] <-- Already traversed" );
102-
return true;
103-
}
104-
105-
106-
// QUERY AND UPDATE DEPENDENCIES
107-
108-
$dataItem = $newData->getPropertyValues( $properties[$wgSDUProperty] );
109-
110-
foreach ( $dataItem as $valueItem ) {
111-
SemanticDependencyUpdater::updatePagesMatchingQuery( $valueItem->getString() );
112-
}
113-
114-
return true;
115-
}
116-
117-
/**
118-
* @param string $queryString Query string, excluding [[ and ]] brackets
119-
*/
120-
private static function updatePagesMatchingQuery( $queryString ) {
121-
122-
global $sfgListSeparator;
123-
124-
$queryString = str_replace( 'AND', ']] [[', $queryString );
125-
$queryString = str_replace( 'OR', ']] OR [[', $queryString );
126-
127-
// If SF is installed, get the separator character and change it into ||
128-
// Otherwise SDU won't work with multi-value properties
129-
if ( isset( $sfgListSeparator ) ) {
130-
$queryString = rtrim( $queryString, $sfgListSeparator );
131-
$queryString = str_replace( $sfgListSeparator, ' || ', $queryString );
132-
}
133-
134-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [[$queryString]]" );
135-
136-
$store = smwfGetStore();
137-
138-
$params = [
139-
'limit' => 10000,
140-
];
141-
$processedParams = SMWQueryProcessor::getProcessedParams( $params );
142-
$query =
143-
SMWQueryProcessor::createQuery( "[[$queryString]]", $processedParams, SMWQueryProcessor::SPECIAL_PAGE );
144-
$result = $store->getQueryResult( $query ); // SMWQueryResult
145-
$wikiPageValues = $result->getResults(); // array of SMWWikiPageValues
146-
147-
// TODO: This can be optimized by collecting a list of all pages first, make them unique
148-
// and do the dummy edit afterwards
149-
// TODO: A threshold when to switch to Queue Jobs might be smarter
150-
foreach ( $wikiPageValues as $page ) {
151-
SemanticDependencyUpdater::dummyEdit( $page->getTitle() );
152-
}
153-
154-
return;
155-
}
156-
157-
/**
158-
* Save a null revision in the page's history to propagate the update
159-
*
160-
* @param Title $title
161-
*/
162-
public static function dummyEdit( $title ) {
163-
global $wgSDUUseJobQueue;
164-
165-
if ( $wgSDUUseJobQueue ) {
166-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [Edit Job] $title" );
167-
$job = new DummyEditJob( $title );
168-
$job->insert();
169-
} else {
170-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [Edit] $title" );
171-
$page = WikiPage::newFromID( $title->getArticleId() );
172-
if ( $page ) { // prevent NPE when page not found
173-
$content = $page->getContent( Revision::RAW );
174-
$text = ContentHandler::getContentText( $content );
175-
$page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
176-
"[SemanticDependencyUpdater] Null edit." ); // since this is a null edit, the edit summary will be ignored.
177-
$page->doPurge(); // required since SMW 2.5.1
178-
}
179-
}
180-
}
181-
182-
}
183-
184-
class DummyEditJob extends Job {
185-
186-
function __construct( $title, $params = '', $id = 0 ) {
187-
parent::__construct( 'DummyEditJob', $title, $params, $id );
188-
}
189-
190-
/**
191-
* Run the job
192-
* @return boolean success
193-
*/
194-
function run() {
195-
wfProfileIn( __METHOD__ );
196-
197-
if ( is_null( $this->title ) ) {
198-
$this->error = "DummyEditJob: Invalid title";
199-
wfProfileOut( __METHOD__ );
200-
return false;
201-
}
202-
203-
$page = WikiPage::newFromID( $this->title->getArticleId() );
204-
if ( $page ) { // prevent NPE when page not found
205-
$content = $page->getContent( Revision::RAW );
206-
$text = ContentHandler::getContentText( $content );
207-
$page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
208-
"[SemanticDependencyUpdater] Null edit." ); // since this is a null edit, the edit summary will be ignored.
209-
$page->doPurge(); // required since SMW 2.5.1
210-
}
211-
212-
wfProfileOut( __METHOD__ );
213-
return true;
214-
}
215-
}
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: Sebastian
5+
* Date: 21.08.2018
6+
* Time: 08:56
7+
*/
8+
9+
namespace SDU;
10+
11+
use SMW;
12+
use SMWStore;
13+
use SMWSemanticData;
14+
use SMWQueryProcessor;
15+
use Revision;
16+
use WikiPage;
17+
use ContentHandler;
18+
19+
class Hooks {
20+
21+
public static function setup() {
22+
23+
if ( !defined( 'MEDIAWIKI' ) ) {
24+
die();
25+
}
26+
27+
if ( !defined( 'SMW_VERSION' ) ) {
28+
die( "ERROR: Semantic MediaWiki must be installed for Semantic Dependency Updater to run!" );
29+
}
30+
31+
global $wgHooks;
32+
// registered Hook this way to make sure SMW is loaded
33+
$wgHooks['SMW::SQLStore::AfterDataUpdateComplete'][] = 'SDU\Hooks::onAfterDataUpdateComplete';
34+
}
35+
36+
public static function onAfterDataUpdateComplete( SMWStore $store, SMWSemanticData $newData,
37+
$compositePropertyTableDiffIterator ) {
38+
global $wgSDUProperty;
39+
global $wgSDUTraversed;
40+
41+
if ( !isset( $wgSDUTraversed ) ) {
42+
$wgSDUTraversed = [];
43+
}
44+
45+
$wgSDUProperty = str_replace( ' ', '_', $wgSDUProperty );
46+
$subject = $newData->getSubject();
47+
$title = $subject->getTitle();
48+
$id = $title->getPrefixedDBKey();
49+
50+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --> " . $title );
51+
52+
53+
// FIRST CHECK: Does the page data contain a $wgSUTPropertyName semantic property ?
54+
$properties = $newData->getProperties();
55+
$diffTable = $compositePropertyTableDiffIterator->getOrderedDiffByTable();
56+
57+
if ( !isset( $properties[$wgSDUProperty] ) ) {
58+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] <-- No SDU property found" );
59+
return true;
60+
}
61+
62+
// SECOND CHECK: Have there been actual changes in the data? (Ignore internal SMW data!)
63+
// TODO: Introduce an explicit list of Semantic Properties to watch ?
64+
unset( $diffTable['smw_fpt_mdat'] ); // Ignore SMW's internal properties "smw_fpt_mdat"
65+
66+
if ( count( $diffTable ) > 0 ) {
67+
// wfDebugLog('SemanticDependencyUpdater', "[SDU] diffTable: " . print_r($diffTable, true));
68+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] -----> Data changes detected" );
69+
} else {
70+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] <-- No semantic data changes detected" );
71+
return true;
72+
}
73+
74+
75+
// THIRD CHECK: Has this page been already traversed more than twice?
76+
// This should only be the case when SMW errors occur.
77+
// In that case, the diffTable contains everything and SDU can't know if changes happend
78+
if ( array_key_exists( $id, $wgSDUTraversed ) ) {
79+
$wgSDUTraversed[$id] = $wgSDUTraversed[$id] + 1;
80+
} else {
81+
$wgSDUTraversed[$id] = 1;
82+
}
83+
if ( $wgSDUTraversed[$id] > 2 ) {
84+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] <-- Already traversed" );
85+
return true;
86+
}
87+
88+
89+
// QUERY AND UPDATE DEPENDENCIES
90+
91+
$dataItem = $newData->getPropertyValues( $properties[$wgSDUProperty] );
92+
93+
foreach ( $dataItem as $valueItem ) {
94+
Hooks::updatePagesMatchingQuery( $valueItem->getString() );
95+
}
96+
97+
return true;
98+
}
99+
/**
100+
* @param string $queryString Query string, excluding [[ and ]] brackets
101+
*/
102+
private static function updatePagesMatchingQuery( $queryString ) {
103+
104+
global $sfgListSeparator;
105+
106+
$queryString = str_replace( 'AND', ']] [[', $queryString );
107+
$queryString = str_replace( 'OR', ']] OR [[', $queryString );
108+
109+
// If SF is installed, get the separator character and change it into ||
110+
// Otherwise SDU won't work with multi-value properties
111+
if ( isset( $sfgListSeparator ) ) {
112+
$queryString = rtrim( $queryString, $sfgListSeparator );
113+
$queryString = str_replace( $sfgListSeparator, ' || ', $queryString );
114+
}
115+
116+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [[$queryString]]" );
117+
118+
$store = smwfGetStore();
119+
120+
$params = [
121+
'limit' => 10000,
122+
];
123+
$processedParams = SMWQueryProcessor::getProcessedParams( $params );
124+
$query =
125+
SMWQueryProcessor::createQuery( "[[$queryString]]", $processedParams, SMWQueryProcessor::SPECIAL_PAGE );
126+
$result = $store->getQueryResult( $query ); // SMWQueryResult
127+
$wikiPageValues = $result->getResults(); // array of SMWWikiPageValues
128+
129+
// TODO: This can be optimized by collecting a list of all pages first, make them unique
130+
// and do the dummy edit afterwards
131+
// TODO: A threshold when to switch to Queue Jobs might be smarter
132+
foreach ( $wikiPageValues as $page ) {
133+
Hooks::dummyEdit( $page->getTitle() );
134+
}
135+
136+
return;
137+
}
138+
139+
/**
140+
* Save a null revision in the page's history to propagate the update
141+
*
142+
* @param Title $title
143+
*/
144+
public static function dummyEdit( $title ) {
145+
global $wgSDUUseJobQueue;
146+
147+
if ( $wgSDUUseJobQueue ) {
148+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [Edit Job] $title" );
149+
$job = new DummyEditJob( $title );
150+
$job->insert();
151+
} else {
152+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [Edit] $title" );
153+
$page = WikiPage::newFromID( $title->getArticleId() );
154+
if ( $page ) { // prevent NPE when page not found
155+
$content = $page->getContent( Revision::RAW );
156+
$text = ContentHandler::getContentText( $content );
157+
$page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
158+
"[SemanticDependencyUpdater] Null edit." ); // since this is a null edit, the edit summary will be ignored.
159+
$page->doPurge(); // required since SMW 2.5.1
160+
}
161+
}
162+
}
163+
164+
}

0 commit comments

Comments
 (0)