Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
15.25% |
9 / 59 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
WikibaseQualityConstraintsHooks | |
15.25% |
9 / 59 |
|
0.00% |
0 / 5 |
405.39 | |
0.00% |
0 / 1 |
onWikibaseChange | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
72 | |||
isSelectedForJobRunBasedOnPercentage | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
isConstraintStatementsChange | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
5.03 | |||
onArticlePurge | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
onBeforePageDisplay | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
72 |
1 | <?php |
2 | |
3 | namespace WikibaseQuality\ConstraintReport; |
4 | |
5 | use JobSpecification; |
6 | use MediaWiki\Config\Config; |
7 | use MediaWiki\MediaWikiServices; |
8 | use MediaWiki\Output\Hook\BeforePageDisplayHook; |
9 | use MediaWiki\Page\Hook\ArticlePurgeHook; |
10 | use MediaWiki\Registration\ExtensionRegistry; |
11 | use Wikibase\DataModel\Entity\NumericPropertyId; |
12 | use Wikibase\Lib\Changes\Change; |
13 | use Wikibase\Lib\Changes\EntityChange; |
14 | use Wikibase\Lib\Changes\EntityDiffChangedAspects; |
15 | use Wikibase\Repo\WikibaseRepo; |
16 | use WikibaseQuality\ConstraintReport\Api\ResultsCache; |
17 | use WikibaseQuality\ConstraintReport\Job\CheckConstraintsJob; |
18 | |
19 | /** |
20 | * Container for hook callbacks registered in extension.json. |
21 | * |
22 | * @license GPL-2.0-or-later |
23 | */ |
24 | final class WikibaseQualityConstraintsHooks implements |
25 | ArticlePurgeHook, |
26 | BeforePageDisplayHook |
27 | { |
28 | |
29 | public static function onWikibaseChange( Change $change ) { |
30 | if ( !( $change instanceof EntityChange ) ) { |
31 | return; |
32 | } |
33 | /** @var EntityChange $change */ |
34 | |
35 | $services = MediaWikiServices::getInstance(); |
36 | $config = $services->getMainConfig(); |
37 | $jobQueueGroup = $services->getJobQueueGroup(); |
38 | |
39 | // If jobs are enabled and the results would be stored in some way run a job. |
40 | if ( |
41 | $config->get( 'WBQualityConstraintsEnableConstraintsCheckJobs' ) && |
42 | $config->get( 'WBQualityConstraintsCacheCheckConstraintsResults' ) && |
43 | self::isSelectedForJobRunBasedOnPercentage() |
44 | ) { |
45 | $params = [ 'entityId' => $change->getEntityId()->getSerialization() ]; |
46 | $jobQueueGroup->lazyPush( |
47 | new JobSpecification( CheckConstraintsJob::COMMAND, $params ) |
48 | ); |
49 | } |
50 | |
51 | if ( $config->get( 'WBQualityConstraintsEnableConstraintsImportFromStatements' ) && |
52 | self::isConstraintStatementsChange( $config, $change ) |
53 | ) { |
54 | $params = [ 'propertyId' => $change->getEntityId()->getSerialization() ]; |
55 | $metadata = $change->getMetadata(); |
56 | if ( array_key_exists( 'rev_id', $metadata ) ) { |
57 | $params['revisionId'] = $metadata['rev_id']; |
58 | } |
59 | $jobQueueGroup->push( |
60 | new JobSpecification( 'constraintsTableUpdate', $params ) |
61 | ); |
62 | } |
63 | } |
64 | |
65 | private static function isSelectedForJobRunBasedOnPercentage() { |
66 | $config = MediaWikiServices::getInstance()->getMainConfig(); |
67 | $percentage = $config->get( 'WBQualityConstraintsEnableConstraintsCheckJobsRatio' ); |
68 | |
69 | return mt_rand( 1, 100 ) <= $percentage; |
70 | } |
71 | |
72 | public static function isConstraintStatementsChange( Config $config, Change $change ) { |
73 | if ( !( $change instanceof EntityChange ) || |
74 | $change->getAction() !== EntityChange::UPDATE || |
75 | !( $change->getEntityId() instanceof NumericPropertyId ) |
76 | ) { |
77 | return false; |
78 | } |
79 | |
80 | $info = $change->getInfo(); |
81 | |
82 | if ( !array_key_exists( 'compactDiff', $info ) ) { |
83 | // the non-compact diff ($info['diff']) does not contain statement diffs (T110996), |
84 | // so we only know that the change *might* affect the constraint statements |
85 | return true; |
86 | } |
87 | |
88 | /** @var EntityDiffChangedAspects $aspects */ |
89 | $aspects = $info['compactDiff']; |
90 | |
91 | $propertyConstraintId = $config->get( 'WBQualityConstraintsPropertyConstraintId' ); |
92 | return in_array( $propertyConstraintId, $aspects->getStatementChanges() ); |
93 | } |
94 | |
95 | public function onArticlePurge( $wikiPage ) { |
96 | $entityContentFactory = WikibaseRepo::getEntityContentFactory(); |
97 | if ( $entityContentFactory->isEntityContentModel( $wikiPage->getContentModel() ) ) { |
98 | $entityIdLookup = WikibaseRepo::getEntityIdLookup(); |
99 | $entityId = $entityIdLookup->getEntityIdForTitle( $wikiPage->getTitle() ); |
100 | if ( $entityId !== null ) { |
101 | $resultsCache = ResultsCache::getDefaultInstance(); |
102 | $resultsCache->delete( $entityId ); |
103 | } |
104 | } |
105 | } |
106 | |
107 | public function onBeforePageDisplay( $out, $skin ): void { |
108 | $lookup = WikibaseRepo::getEntityNamespaceLookup(); |
109 | $title = $out->getTitle(); |
110 | if ( $title === null ) { |
111 | return; |
112 | } |
113 | |
114 | if ( !$lookup->isNamespaceWithEntities( $title->getNamespace() ) ) { |
115 | return; |
116 | } |
117 | if ( empty( $out->getJsConfigVars()['wbIsEditView'] ) ) { |
118 | return; |
119 | } |
120 | |
121 | $services = MediaWikiServices::getInstance(); |
122 | $config = $services->getMainConfig(); |
123 | |
124 | $isMobileView = ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) && |
125 | $services->getService( 'MobileFrontend.Context' )->shouldDisplayMobileView(); |
126 | if ( $isMobileView ) { |
127 | return; |
128 | } |
129 | |
130 | $out->addModules( 'wikibase.quality.constraints.suggestions' ); |
131 | |
132 | if ( $config->get( 'WBQualityConstraintsShowConstraintViolationToNonLoggedInUsers' ) |
133 | || $out->getUser()->isRegistered() ) { |
134 | $out->addModules( 'wikibase.quality.constraints.gadget' ); |
135 | } |
136 | } |
137 | |
138 | } |